fix: #423, #391 - prevents loading edit views until data initializes

This commit is contained in:
James
2022-02-03 11:49:15 -05:00
parent 7fd4b22180
commit 28846547af
5 changed files with 260 additions and 258 deletions

View File

@@ -51,120 +51,118 @@ const DefaultAccount: React.FC<Props> = (props) => {
return (
<div className={classes}>
<Form
className={`${baseClass}__form`}
method="put"
action={action}
initialState={initialState}
disabled={!hasSavePermission}
>
<div className={`${baseClass}__main`}>
<Meta
title="Account"
description="Account of current user"
keywords="Account, Dashboard, Payload, CMS"
/>
<Eyebrow />
<LeaveWithoutSaving />
<div className={`${baseClass}__edit`}>
{isLoading && (
<Loading />
)}
{!isLoading && (
<React.Fragment>
<header className={`${baseClass}__header`}>
<h1>
<RenderTitle {...{ data, useAsTitle, fallback: '[Untitled]' }} />
</h1>
</header>
<Auth
useAPIKey={auth.useAPIKey}
collection={collection}
email={data?.email}
operation="update"
/>
<RenderFields
operation="update"
permissions={permissions.fields}
readOnly={!hasSavePermission}
filter={(field) => field?.admin?.position !== 'sidebar'}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</React.Fragment>
)}
</div>
</div>
<div className={`${baseClass}__sidebar-wrap`}>
<div className={`${baseClass}__sidebar`}>
<div className={`${baseClass}__sidebar-sticky-wrap`}>
<ul className={`${baseClass}__collection-actions`}>
{(permissions?.create?.permission) && (
<React.Fragment>
<li><Link to={`${admin}/collections/${slug}/create`}>Create New</Link></li>
</React.Fragment>
)}
</ul>
<div className={`${baseClass}__document-actions${preview ? ` ${baseClass}__document-actions--with-preview` : ''}`}>
<PreviewButton
generatePreviewURL={preview}
data={data}
/>
{hasSavePermission && (
<FormSubmit>Save</FormSubmit>
)}
</div>
<div className={`${baseClass}__sidebar-fields`}>
<RenderFields
operation="update"
permissions={permissions.fields}
readOnly={!hasSavePermission}
filter={(field) => field?.admin?.position === 'sidebar'}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</div>
<ul className={`${baseClass}__meta`}>
<li className={`${baseClass}__api-url`}>
<span className={`${baseClass}__label`}>
API URL
{' '}
<CopyToClipboard value={apiURL} />
</span>
<a
href={apiURL}
target="_blank"
rel="noopener noreferrer"
>
{apiURL}
</a>
</li>
<li>
<div className={`${baseClass}__label`}>ID</div>
<div>{data?.id}</div>
</li>
{timestamps && (
<React.Fragment>
{data.updatedAt && (
<li>
<div className={`${baseClass}__label`}>Last Modified</div>
<div>{format(new Date(data.updatedAt), dateFormat)}</div>
</li>
)}
{data.createdAt && (
<li>
<div className={`${baseClass}__label`}>Created</div>
<div>{format(new Date(data.createdAt), dateFormat)}</div>
</li>
)}
</React.Fragment>
)}
</ul>
{isLoading && (
<Loading />
)}
{!isLoading && (
<Form
className={`${baseClass}__form`}
method="put"
action={action}
initialState={initialState}
disabled={!hasSavePermission}
>
<div className={`${baseClass}__main`}>
<Meta
title="Account"
description="Account of current user"
keywords="Account, Dashboard, Payload, CMS"
/>
<Eyebrow />
<LeaveWithoutSaving />
<div className={`${baseClass}__edit`}>
<header className={`${baseClass}__header`}>
<h1>
<RenderTitle {...{ data, useAsTitle, fallback: '[Untitled]' }} />
</h1>
</header>
<Auth
useAPIKey={auth.useAPIKey}
collection={collection}
email={data?.email}
operation="update"
/>
<RenderFields
operation="update"
permissions={permissions.fields}
readOnly={!hasSavePermission}
filter={(field) => field?.admin?.position !== 'sidebar'}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</div>
</div>
</div>
</Form>
<div className={`${baseClass}__sidebar-wrap`}>
<div className={`${baseClass}__sidebar`}>
<div className={`${baseClass}__sidebar-sticky-wrap`}>
<ul className={`${baseClass}__collection-actions`}>
{(permissions?.create?.permission) && (
<React.Fragment>
<li><Link to={`${admin}/collections/${slug}/create`}>Create New</Link></li>
</React.Fragment>
)}
</ul>
<div className={`${baseClass}__document-actions${preview ? ` ${baseClass}__document-actions--with-preview` : ''}`}>
<PreviewButton
generatePreviewURL={preview}
data={data}
/>
{hasSavePermission && (
<FormSubmit>Save</FormSubmit>
)}
</div>
<div className={`${baseClass}__sidebar-fields`}>
<RenderFields
operation="update"
permissions={permissions.fields}
readOnly={!hasSavePermission}
filter={(field) => field?.admin?.position === 'sidebar'}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</div>
<ul className={`${baseClass}__meta`}>
<li className={`${baseClass}__api-url`}>
<span className={`${baseClass}__label`}>
API URL
{' '}
<CopyToClipboard value={apiURL} />
</span>
<a
href={apiURL}
target="_blank"
rel="noopener noreferrer"
>
{apiURL}
</a>
</li>
<li>
<div className={`${baseClass}__label`}>ID</div>
<div>{data?.id}</div>
</li>
{timestamps && (
<React.Fragment>
{data.updatedAt && (
<li>
<div className={`${baseClass}__label`}>Last Modified</div>
<div>{format(new Date(data.updatedAt), dateFormat)}</div>
</li>
)}
{data.createdAt && (
<li>
<div className={`${baseClass}__label`}>Created</div>
<div>{format(new Date(data.createdAt), dateFormat)}</div>
</li>
)}
</React.Fragment>
)}
</ul>
</div>
</div>
</div>
</Form>
)}
</div>
);
};

View File

@@ -12,15 +12,17 @@ import fieldTypes from '../../forms/field-types';
import LeaveWithoutSaving from '../../modals/LeaveWithoutSaving';
import { Props } from './types';
import './index.scss';
import ViewDescription from '../../elements/ViewDescription';
import Loading from '../../elements/Loading';
import './index.scss';
const baseClass = 'global-edit';
const DefaultGlobalView: React.FC<Props> = (props) => {
const { admin: { dateFormat } } = useConfig();
const {
global, data, onSave, permissions, action, apiURL, initialState,
global, data, onSave, permissions, action, apiURL, initialState, isLoading,
} = props;
const {
@@ -36,6 +38,10 @@ const DefaultGlobalView: React.FC<Props> = (props) => {
return (
<div className={baseClass}>
{isLoading && (
<Loading />
)}
{!isLoading && (
<Form
className={`${baseClass}__form`}
method="post"
@@ -60,9 +66,9 @@ const DefaultGlobalView: React.FC<Props> = (props) => {
{label}
</h1>
{description && (
<div className={`${baseClass}__sub-header`}>
<ViewDescription description={description} />
</div>
<div className={`${baseClass}__sub-header`}>
<ViewDescription description={description} />
</div>
)}
</header>
<RenderFields
@@ -84,7 +90,7 @@ const DefaultGlobalView: React.FC<Props> = (props) => {
data={data}
/>
{hasSavePermission && (
<FormSubmit>Save</FormSubmit>
<FormSubmit>Save</FormSubmit>
)}
</div>
<div className={`${baseClass}__sidebar-fields`}>
@@ -98,35 +104,36 @@ const DefaultGlobalView: React.FC<Props> = (props) => {
/>
</div>
{data && (
<ul className={`${baseClass}__meta`}>
{data && (
<li className={`${baseClass}__api-url`}>
<span className={`${baseClass}__label`}>
API URL
{' '}
<CopyToClipboard value={apiURL} />
</span>
<a
href={apiURL}
target="_blank"
rel="noopener noreferrer"
>
{apiURL}
</a>
</li>
)}
{data.updatedAt && (
<li>
<div className={`${baseClass}__label`}>Last Modified</div>
<div>{format(new Date(data.updatedAt as string), dateFormat)}</div>
</li>
)}
</ul>
<ul className={`${baseClass}__meta`}>
{data && (
<li className={`${baseClass}__api-url`}>
<span className={`${baseClass}__label`}>
API URL
{' '}
<CopyToClipboard value={apiURL} />
</span>
<a
href={apiURL}
target="_blank"
rel="noopener noreferrer"
>
{apiURL}
</a>
</li>
)}
{data.updatedAt && (
<li>
<div className={`${baseClass}__label`}>Last Modified</div>
<div>{format(new Date(data.updatedAt as string), dateFormat)}</div>
</li>
)}
</ul>
)}
</div>
</div>
</div>
</Form>
)}
</div>
);
};

View File

@@ -54,7 +54,7 @@ const GlobalView: React.FC<IndexProps> = (props) => {
});
};
const [{ data }] = usePayloadAPI(
const [{ data, isLoading }] = usePayloadAPI(
`${serverURL}${api}/globals/${slug}`,
{ initialParams: { 'fallback-locale': 'null', depth: 0 } },
);
@@ -90,6 +90,7 @@ const GlobalView: React.FC<IndexProps> = (props) => {
DefaultComponent={DefaultGlobal}
CustomComponent={CustomEdit}
componentProps={{
isLoading,
data: dataToRender,
permissions: globalPermissions,
initialState,

View File

@@ -14,4 +14,5 @@ export type Props = {
action: string
apiURL: string
initialState: Fields
isLoading: boolean
}

View File

@@ -62,34 +62,34 @@ const DefaultEditView: React.FC<Props> = (props) => {
return (
<div className={classes}>
<Form
className={`${baseClass}__form`}
method={id ? 'put' : 'post'}
action={action}
onSuccess={onSave}
disabled={!hasSavePermission}
initialState={initialState}
>
<div className={`${baseClass}__main`}>
<Meta
title={`${isEditing ? 'Editing' : 'Creating'} - ${collection.labels.singular}`}
description={`${isEditing ? 'Editing' : 'Creating'} - ${collection.labels.singular}`}
keywords={`${collection.labels.singular}, Payload, CMS`}
/>
<Eyebrow />
<LeaveWithoutSaving />
<div className={`${baseClass}__edit`}>
{isLoading && (
<Loading />
)}
{!isLoading && (
<React.Fragment>
<header className={`${baseClass}__header`}>
<h1>
<RenderTitle {...{ data, useAsTitle, fallback: '[Untitled]' }} />
</h1>
</header>
{auth && (
{isLoading && (
<Loading />
)}
{!isLoading && (
<Form
className={`${baseClass}__form`}
method={id ? 'put' : 'post'}
action={action}
onSuccess={onSave}
disabled={!hasSavePermission}
initialState={initialState}
>
<div className={`${baseClass}__main`}>
<Meta
title={`${isEditing ? 'Editing' : 'Creating'} - ${collection.labels.singular}`}
description={`${isEditing ? 'Editing' : 'Creating'} - ${collection.labels.singular}`}
keywords={`${collection.labels.singular}, Payload, CMS`}
/>
<Eyebrow />
<LeaveWithoutSaving />
<div className={`${baseClass}__edit`}>
<React.Fragment>
<header className={`${baseClass}__header`}>
<h1>
<RenderTitle {...{ data, useAsTitle, fallback: '[Untitled]' }} />
</h1>
</header>
{auth && (
<Auth
useAPIKey={auth.useAPIKey}
requirePassword={!isEditing}
@@ -98,39 +98,38 @@ const DefaultEditView: React.FC<Props> = (props) => {
email={data?.email}
operation={operation}
/>
)}
{upload && (
)}
{upload && (
<Upload
data={data}
collection={collection}
/>
)}
<RenderFields
operation={operation}
readOnly={!hasSavePermission}
permissions={permissions.fields}
filter={(field) => (!field?.admin?.position || (field?.admin?.position !== 'sidebar'))}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</React.Fragment>
)}
)}
<RenderFields
operation={operation}
readOnly={!hasSavePermission}
permissions={permissions.fields}
filter={(field) => (!field?.admin?.position || (field?.admin?.position !== 'sidebar'))}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</React.Fragment>
</div>
</div>
</div>
<div className={`${baseClass}__sidebar-wrap`}>
<div className={`${baseClass}__sidebar`}>
<div className={`${baseClass}__sidebar-sticky-wrap`}>
{isEditing ? (
<ul className={`${baseClass}__collection-actions`}>
{(permissions?.create?.permission) && (
<div className={`${baseClass}__sidebar-wrap`}>
<div className={`${baseClass}__sidebar`}>
<div className={`${baseClass}__sidebar-sticky-wrap`}>
{isEditing ? (
<ul className={`${baseClass}__collection-actions`}>
{(permissions?.create?.permission) && (
<React.Fragment>
<li><Link to={`${admin}/collections/${slug}/create`}>Create New</Link></li>
{!disableDuplicate && (
<li><DuplicateDocument slug={slug} /></li>
)}
</React.Fragment>
)}
{permissions?.delete?.permission && (
)}
{permissions?.delete?.permission && (
<li>
<DeleteDocument
collection={collection}
@@ -138,76 +137,72 @@ const DefaultEditView: React.FC<Props> = (props) => {
/>
</li>
)}
</ul>
) : undefined}
<div className={`${baseClass}__document-actions${(preview && isEditing) ? ` ${baseClass}__document-actions--with-preview` : ''}`}>
{isEditing && (
<PreviewButton
generatePreviewURL={preview}
data={data}
</ul>
) : undefined}
<div className={`${baseClass}__document-actions${(preview && isEditing) ? ` ${baseClass}__document-actions--with-preview` : ''}`}>
{isEditing && (
<PreviewButton
generatePreviewURL={preview}
data={data}
/>
)}
{hasSavePermission && (
<FormSubmit>Save</FormSubmit>
)}
</div>
<div className={`${baseClass}__sidebar-fields`}>
<RenderFields
operation={isEditing ? 'update' : 'create'}
readOnly={!hasSavePermission}
permissions={permissions.fields}
filter={(field) => field?.admin?.position === 'sidebar'}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
)}
{hasSavePermission && (
<FormSubmit>Save</FormSubmit>
</div>
{isEditing && (
<ul className={`${baseClass}__meta`}>
<li className={`${baseClass}__api-url`}>
<span className={`${baseClass}__label`}>
API URL
{' '}
<CopyToClipboard value={apiURL} />
</span>
<a
href={apiURL}
target="_blank"
rel="noopener noreferrer"
>
{apiURL}
</a>
</li>
<li>
<div className={`${baseClass}__label`}>ID</div>
<div>{id}</div>
</li>
{timestamps && (
<React.Fragment>
{data.updatedAt && (
<li>
<div className={`${baseClass}__label`}>Last Modified</div>
<div>{format(new Date(data.updatedAt), dateFormat)}</div>
</li>
)}
{data.createdAt && (
<li>
<div className={`${baseClass}__label`}>Created</div>
<div>{format(new Date(data.createdAt), dateFormat)}</div>
</li>
)}
</React.Fragment>
)}
</ul>
)}
</div>
{!isLoading && (
<React.Fragment>
<div className={`${baseClass}__sidebar-fields`}>
<RenderFields
operation={isEditing ? 'update' : 'create'}
readOnly={!hasSavePermission}
permissions={permissions.fields}
filter={(field) => field?.admin?.position === 'sidebar'}
fieldTypes={fieldTypes}
fieldSchema={fields}
/>
</div>
{isEditing && (
<ul className={`${baseClass}__meta`}>
<li className={`${baseClass}__api-url`}>
<span className={`${baseClass}__label`}>
API URL
{' '}
<CopyToClipboard value={apiURL} />
</span>
<a
href={apiURL}
target="_blank"
rel="noopener noreferrer"
>
{apiURL}
</a>
</li>
<li>
<div className={`${baseClass}__label`}>ID</div>
<div>{id}</div>
</li>
{timestamps && (
<React.Fragment>
{data.updatedAt && (
<li>
<div className={`${baseClass}__label`}>Last Modified</div>
<div>{format(new Date(data.updatedAt), dateFormat)}</div>
</li>
)}
{data.createdAt && (
<li>
<div className={`${baseClass}__label`}>Created</div>
<div>{format(new Date(data.createdAt), dateFormat)}</div>
</li>
)}
</React.Fragment>
)}
</ul>
)}
</React.Fragment>
)}
</div>
</div>
</div>
</Form>
</Form>
)}
</div>
);
};