further types to admin
This commit is contained in:
@@ -7,3 +7,8 @@ export type Props = {
|
||||
collection: CollectionConfig,
|
||||
handleChange: (newState) => void,
|
||||
}
|
||||
|
||||
export type ListControls = {
|
||||
where?: unknown
|
||||
columns?: string[]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
export type Props = {
|
||||
columns: {
|
||||
accessor: string,
|
||||
components: {
|
||||
Heading: React.ReactNode,
|
||||
renderCell: (row: any, data: any) => React.ReactNode,
|
||||
},
|
||||
}[],
|
||||
data: []
|
||||
export type Column = {
|
||||
accessor: string,
|
||||
components: {
|
||||
Heading: React.ReactNode,
|
||||
renderCell: (row: any, data: any) => React.ReactNode,
|
||||
},
|
||||
}
|
||||
|
||||
export type Props = {
|
||||
columns: Column[],
|
||||
data: unknown[]
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ const UploadGallery: React.FC<Props> = (props) => {
|
||||
{docs.map((doc, i) => (
|
||||
<li key={i}>
|
||||
<UploadCard
|
||||
{...doc}
|
||||
{...doc as {id: string, filesize: number, mimeType: string, filename: string}}
|
||||
{...{ collection }}
|
||||
onClick={() => onCardClick(doc)}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { CollectionConfig } from '../../../../collections/config/types';
|
||||
|
||||
export type Props = {
|
||||
docs?: [],
|
||||
collection: unknown,
|
||||
docs?: unknown[],
|
||||
collection: CollectionConfig,
|
||||
onCardClick: (doc) => void,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export type Props = {
|
||||
label?: string
|
||||
label?: string | JSX.Element
|
||||
required?: boolean
|
||||
htmlFor?: string
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ export type Context = {
|
||||
export type Props = {
|
||||
className?: string
|
||||
operation?: Operation
|
||||
readOnly: boolean
|
||||
permissions: {
|
||||
readOnly?: boolean
|
||||
permissions?: {
|
||||
[field: string]: FieldPermissions
|
||||
}
|
||||
filter?: (field: Field) => boolean
|
||||
|
||||
@@ -32,7 +32,7 @@ const Text: React.FC<Props> = (props) => {
|
||||
return validationResult;
|
||||
}, [validate, maxLength, minLength, required]);
|
||||
|
||||
const fieldType = useFieldType({
|
||||
const fieldType = useFieldType<string>({
|
||||
path,
|
||||
validate: memoizedValidate,
|
||||
enableDebouncedValue: true,
|
||||
@@ -70,7 +70,7 @@ const Text: React.FC<Props> = (props) => {
|
||||
required={required}
|
||||
/>
|
||||
<input
|
||||
value={value as string || ''}
|
||||
value={value || ''}
|
||||
onChange={setValue}
|
||||
disabled={readOnly}
|
||||
placeholder={placeholder}
|
||||
|
||||
@@ -66,7 +66,6 @@ const AddUploadModal: React.FC<Props> = (props) => {
|
||||
</header>
|
||||
<Upload
|
||||
{...collection.upload}
|
||||
fieldTypes={fieldTypes}
|
||||
/>
|
||||
<NegativeFieldGutterProvider allow>
|
||||
<RenderFields
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Options, FieldType } from './types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const useFieldType = (options: Options): FieldType => {
|
||||
const useFieldType = <T extends unknown>(options: Options): FieldType<T> => {
|
||||
const {
|
||||
path,
|
||||
validate,
|
||||
|
||||
@@ -9,8 +9,8 @@ export type Options = {
|
||||
stringify?: boolean
|
||||
}
|
||||
|
||||
export type FieldType = {
|
||||
value: unknown
|
||||
export type FieldType<T> = {
|
||||
value: T
|
||||
errorMessage?: string
|
||||
showError: boolean
|
||||
formSubmitted: boolean
|
||||
|
||||
@@ -11,7 +11,7 @@ import RenderCustomComponent from '../../utilities/RenderCustomComponent';
|
||||
import { NegativeFieldGutterProvider } from '../../forms/FieldTypeGutter/context';
|
||||
|
||||
const AccountView: React.FC = () => {
|
||||
const { state: locationState } = useLocation();
|
||||
const { state: locationState } = useLocation<{ data: unknown }>();
|
||||
const locale = useLocale();
|
||||
const { setStepNav } = useStepNav();
|
||||
const { user, permissions } = useAuth();
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import MinimalTemplate from '../../templates/Minimal';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import Form from '../../forms/Form';
|
||||
import RenderFields from '../../forms/RenderFields';
|
||||
import fieldTypes from '../../forms/field-types';
|
||||
import FormSubmit from '../../forms/Submit';
|
||||
import { useAuth } from '@payloadcms/config-provider';
|
||||
import { Props } from './types';
|
||||
import { Field } from '../../../../fields/config/types';
|
||||
|
||||
import { NegativeFieldGutterProvider } from '../../forms/FieldTypeGutter/context';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'create-first-user';
|
||||
|
||||
const CreateFirstUser = (props) => {
|
||||
const CreateFirstUser: React.FC<Props> = (props) => {
|
||||
const { setInitialized } = props;
|
||||
const { setToken } = useAuth();
|
||||
const {
|
||||
@@ -43,7 +45,7 @@ const CreateFirstUser = (props) => {
|
||||
type: 'password',
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
] as Field[];
|
||||
|
||||
return (
|
||||
<MinimalTemplate className={baseClass}>
|
||||
@@ -56,7 +58,7 @@ const CreateFirstUser = (props) => {
|
||||
/>
|
||||
<Form
|
||||
onSuccess={onSuccess}
|
||||
method="POST"
|
||||
method="post"
|
||||
redirect={admin}
|
||||
action={`${serverURL}${api}/${userSlug}/first-register`}
|
||||
>
|
||||
|
||||
3
src/admin/components/views/CreateFirstUser/types.ts
Normal file
3
src/admin/components/views/CreateFirstUser/types.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export type Props = {
|
||||
setInitialized: (initialized: boolean) => void
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import { useStepNav } from '../../elements/StepNav';
|
||||
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
|
||||
import DefaultDashboard from './Default';
|
||||
|
||||
const Dashboard = () => {
|
||||
const Dashboard: React.FC = () => {
|
||||
const { permissions } = useAuth();
|
||||
const { setStepNav } = useStepNav();
|
||||
const [filteredGlobals, setFilteredGlobals] = useState([]);
|
||||
@@ -15,7 +15,9 @@ const Dashboard = () => {
|
||||
globals,
|
||||
admin: {
|
||||
components: {
|
||||
Dashboard: CustomDashboard,
|
||||
views: {
|
||||
Dashboard: CustomDashboard,
|
||||
} = {},
|
||||
} = {},
|
||||
} = {},
|
||||
} = useConfig();
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import MinimalTemplate from '../../templates/Minimal';
|
||||
import Form from '../../forms/Form';
|
||||
import Email from '../../forms/field-types/Email';
|
||||
import FormSubmit from '../../forms/Submit';
|
||||
import Button from '../../elements/Button';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import { useAuth } from '@payloadcms/config-provider';
|
||||
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'forgot-password';
|
||||
|
||||
const ForgotPassword = () => {
|
||||
const ForgotPassword: React.FC = () => {
|
||||
const [hasSubmitted, setHasSubmitted] = useState(false);
|
||||
const { user } = useAuth();
|
||||
const {
|
||||
@@ -78,9 +78,8 @@ const ForgotPassword = () => {
|
||||
return (
|
||||
<MinimalTemplate className={baseClass}>
|
||||
<Form
|
||||
novalidate
|
||||
handleResponse={handleResponse}
|
||||
method="POST"
|
||||
method="post"
|
||||
action={`${serverURL}${api}/${userSlug}/forgot-password`}
|
||||
>
|
||||
<h1>Forgot Password</h1>
|
||||
@@ -88,7 +87,7 @@ const ForgotPassword = () => {
|
||||
<Email
|
||||
label="Email Address"
|
||||
name="email"
|
||||
autoComplete="email"
|
||||
admin={{ autoComplete: 'email' }}
|
||||
required
|
||||
/>
|
||||
<FormSubmit>Submit</FormSubmit>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import format from 'date-fns/format';
|
||||
import Eyebrow from '../../elements/Eyebrow';
|
||||
import Form from '../../forms/Form';
|
||||
@@ -10,12 +9,13 @@ import CopyToClipboard from '../../elements/CopyToClipboard';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import fieldTypes from '../../forms/field-types';
|
||||
import LeaveWithoutSaving from '../../modals/LeaveWithoutSaving';
|
||||
import { Props } from './types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'global-edit';
|
||||
|
||||
const DefaultGlobalView = (props) => {
|
||||
const DefaultGlobalView: React.FC<Props> = (props) => {
|
||||
const {
|
||||
global, data, onSave, permissions, action, apiURL, initialState,
|
||||
} = props;
|
||||
@@ -58,7 +58,7 @@ const DefaultGlobalView = (props) => {
|
||||
operation="update"
|
||||
readOnly={!hasSavePermission}
|
||||
permissions={permissions.fields}
|
||||
filter={(field) => (!field.position || (field.position && field.position !== 'sidebar'))}
|
||||
filter={(field) => (!field.admin.position || (field.admin.position && field.admin.position !== 'sidebar'))}
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
/>
|
||||
@@ -92,8 +92,7 @@ const DefaultGlobalView = (props) => {
|
||||
operation="update"
|
||||
readOnly={!hasSavePermission}
|
||||
permissions={permissions.fields}
|
||||
filter={(field) => field.position === 'sidebar'}
|
||||
position="sidebar"
|
||||
filter={(field) => field.admin.position === 'sidebar'}
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={fields}
|
||||
/>
|
||||
@@ -103,7 +102,7 @@ const DefaultGlobalView = (props) => {
|
||||
{data.updatedAt && (
|
||||
<li>
|
||||
<div className={`${baseClass}__label`}>Last Modified</div>
|
||||
<div>{format(new Date(data.updatedAt), 'MMMM do yyyy, h:mm a')}</div>
|
||||
<div>{format(new Date(data.updatedAt as string), 'MMMM do yyyy, h:mm a')}</div>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
@@ -114,29 +113,4 @@ const DefaultGlobalView = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
DefaultGlobalView.defaultProps = {
|
||||
data: undefined,
|
||||
};
|
||||
|
||||
DefaultGlobalView.propTypes = {
|
||||
global: PropTypes.shape({
|
||||
label: PropTypes.string.isRequired,
|
||||
fields: PropTypes.arrayOf(PropTypes.shape({})),
|
||||
preview: PropTypes.func,
|
||||
}).isRequired,
|
||||
data: PropTypes.shape({
|
||||
updatedAt: PropTypes.string,
|
||||
}),
|
||||
onSave: PropTypes.func.isRequired,
|
||||
permissions: PropTypes.shape({
|
||||
update: PropTypes.shape({
|
||||
permission: PropTypes.bool,
|
||||
}),
|
||||
fields: PropTypes.shape({}),
|
||||
}).isRequired,
|
||||
action: PropTypes.string.isRequired,
|
||||
apiURL: PropTypes.string.isRequired,
|
||||
initialState: PropTypes.shape({}).isRequired,
|
||||
};
|
||||
|
||||
export default DefaultGlobalView;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import { useStepNav } from '../../elements/StepNav';
|
||||
@@ -11,9 +10,10 @@ import RenderCustomComponent from '../../utilities/RenderCustomComponent';
|
||||
import DefaultGlobal from './Default';
|
||||
import buildStateFromSchema from '../../forms/Form/buildStateFromSchema';
|
||||
import { NegativeFieldGutterProvider } from '../../forms/FieldTypeGutter/context';
|
||||
import { IndexProps } from './types';
|
||||
|
||||
const GlobalView = (props) => {
|
||||
const { state: locationState } = useLocation();
|
||||
const GlobalView: React.FC<IndexProps> = (props) => {
|
||||
const { state: locationState } = useLocation<{data?: Record<string, unknown>}>();
|
||||
const history = useHistory();
|
||||
const locale = useLocale();
|
||||
const { setStepNav } = useStepNav();
|
||||
@@ -97,18 +97,4 @@ const GlobalView = (props) => {
|
||||
</NegativeFieldGutterProvider>
|
||||
);
|
||||
};
|
||||
|
||||
GlobalView.propTypes = {
|
||||
global: PropTypes.shape({
|
||||
label: PropTypes.string.isRequired,
|
||||
slug: PropTypes.string.isRequired,
|
||||
fields: PropTypes.arrayOf(PropTypes.shape({})),
|
||||
admin: PropTypes.shape({
|
||||
components: PropTypes.shape({
|
||||
Edit: PropTypes.node,
|
||||
}),
|
||||
}),
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default GlobalView;
|
||||
|
||||
17
src/admin/components/views/Global/types.ts
Normal file
17
src/admin/components/views/Global/types.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { GlobalPermission } from '../../../../auth/types';
|
||||
import { GlobalConfig } from '../../../../globals/config/types';
|
||||
import { Fields } from '../../forms/Form/types';
|
||||
|
||||
export type IndexProps = {
|
||||
global: GlobalConfig
|
||||
}
|
||||
|
||||
export type Props = {
|
||||
global: GlobalConfig
|
||||
data: Record<string, unknown>
|
||||
onSave: () => void
|
||||
permissions: GlobalPermission
|
||||
action: string
|
||||
apiURL: string
|
||||
initialState: Fields
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import './index.scss';
|
||||
|
||||
const baseClass = 'login';
|
||||
|
||||
const Login = () => {
|
||||
const Login: React.FC = () => {
|
||||
const history = useHistory();
|
||||
const { user, setToken } = useAuth();
|
||||
const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = useConfig();
|
||||
@@ -71,17 +71,16 @@ const Login = () => {
|
||||
disableSuccessStatus
|
||||
waitForAutocomplete
|
||||
onSuccess={onSuccess}
|
||||
method="POST"
|
||||
method="post"
|
||||
action={`${serverURL}${api}/${userSlug}/login`}
|
||||
>
|
||||
<Email
|
||||
label="Email Address"
|
||||
name="email"
|
||||
autoComplete="email"
|
||||
admin={{ autoComplete: 'email' }}
|
||||
required
|
||||
/>
|
||||
<Password
|
||||
error="password"
|
||||
label="Password"
|
||||
name="password"
|
||||
autoComplete="off"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import { useAuth } from '@payloadcms/config-provider';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
|
||||
import Minimal from '../../templates/Minimal';
|
||||
import Button from '../../elements/Button';
|
||||
import Meta from '../../utilities/Meta';
|
||||
@@ -10,7 +9,7 @@ import './index.scss';
|
||||
|
||||
const baseClass = 'logout';
|
||||
|
||||
const Logout = (props) => {
|
||||
const Logout: React.FC<{inactivity?: boolean}> = (props) => {
|
||||
const { inactivity } = props;
|
||||
|
||||
const { logOut } = useAuth();
|
||||
@@ -47,12 +46,4 @@ const Logout = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
Logout.defaultProps = {
|
||||
inactivity: false,
|
||||
};
|
||||
|
||||
Logout.propTypes = {
|
||||
inactivity: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Logout;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useStepNav } from '../../elements/StepNav';
|
||||
import Button from '../../elements/Button';
|
||||
import Meta from '../../utilities/Meta';
|
||||
|
||||
const NotFound = () => {
|
||||
const NotFound: React.FC = () => {
|
||||
const { setStepNav } = useStepNav();
|
||||
const { routes: { admin } } = useConfig();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Link, useHistory, useParams } from 'react-router-dom';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import MinimalTemplate from '../../templates/Minimal';
|
||||
import Form from '../../forms/Form';
|
||||
import Password from '../../forms/field-types/Password';
|
||||
@@ -8,16 +8,16 @@ import ConfirmPassword from '../../forms/field-types/ConfirmPassword';
|
||||
import FormSubmit from '../../forms/Submit';
|
||||
import Button from '../../elements/Button';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import { useAuth } from '@payloadcms/config-provider';
|
||||
|
||||
|
||||
import './index.scss';
|
||||
import HiddenInput from '../../forms/field-types/HiddenInput';
|
||||
|
||||
const baseClass = 'reset-password';
|
||||
|
||||
const ResetPassword = () => {
|
||||
const ResetPassword: React.FC = () => {
|
||||
const { admin: { user: userSlug }, serverURL, routes: { admin, api } } = useConfig();
|
||||
const { token } = useParams();
|
||||
const { token } = useParams<{token?: string}>();
|
||||
const history = useHistory();
|
||||
const { user, setToken } = useAuth();
|
||||
|
||||
@@ -65,12 +65,11 @@ const ResetPassword = () => {
|
||||
<h1>Reset Password</h1>
|
||||
<Form
|
||||
onSuccess={onSuccess}
|
||||
method="POST"
|
||||
method="post"
|
||||
action={`${serverURL}${api}/${userSlug}/reset-password`}
|
||||
redirect={admin}
|
||||
>
|
||||
<Password
|
||||
error="password"
|
||||
label="New Password"
|
||||
name="password"
|
||||
autoComplete="off"
|
||||
|
||||
@@ -4,7 +4,7 @@ import Button from '../../elements/Button';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import MinimalTemplate from '../../templates/Minimal';
|
||||
|
||||
const Unauthorized = () => {
|
||||
const Unauthorized: React.FC = () => {
|
||||
const { routes: { admin } } = useConfig();
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import Logo from '../../graphics/Logo';
|
||||
import MinimalTemplate from '../../templates/Minimal';
|
||||
import Button from '../../elements/Button';
|
||||
import Meta from '../../utilities/Meta';
|
||||
import { CollectionConfig } from '../../../../collections/config/types';
|
||||
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import { useAuth } from '@payloadcms/config-provider';
|
||||
import Login from '../Login';
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'verify';
|
||||
|
||||
const Verify = ({ collection }) => {
|
||||
const Verify: React.FC<{ collection: CollectionConfig }> = ({ collection }) => {
|
||||
const { slug: collectionSlug } = collection;
|
||||
|
||||
const { user } = useAuth();
|
||||
const { token } = useParams();
|
||||
const { token } = useParams<{token?: string}>();
|
||||
const { serverURL, routes: { admin: adminRoute }, admin: { user: adminUser } } = useConfig();
|
||||
|
||||
const isAdminUser = collectionSlug === adminUser;
|
||||
@@ -66,10 +65,4 @@ const Verify = ({ collection }) => {
|
||||
</MinimalTemplate>
|
||||
);
|
||||
};
|
||||
|
||||
Verify.propTypes = {
|
||||
collection: PropTypes.shape({
|
||||
slug: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
export default Verify;
|
||||
|
||||
@@ -13,7 +13,7 @@ const path = 'apiKey';
|
||||
const baseClass = 'api-key';
|
||||
const validate = (val) => text(val, { minLength: 24, maxLength: 48 });
|
||||
|
||||
const APIKey = () => {
|
||||
const APIKey: React.FC = () => {
|
||||
const [initialAPIKey, setInitialAPIKey] = useState(null);
|
||||
const [highlightedField, setHighlightedField] = useState(false);
|
||||
|
||||
@@ -28,7 +28,7 @@ const APIKey = () => {
|
||||
<span>
|
||||
API Key
|
||||
</span>
|
||||
<CopyToClipboard value={apiKeyValue} />
|
||||
<CopyToClipboard value={apiKeyValue as string} />
|
||||
</div>
|
||||
), [apiKeyValue]);
|
||||
|
||||
@@ -83,9 +83,9 @@ const APIKey = () => {
|
||||
label={APIKeyLabel}
|
||||
/>
|
||||
<input
|
||||
value={value || ''}
|
||||
value={value as string || ''}
|
||||
className={highlightedField ? 'highlight' : undefined}
|
||||
disabled="disabled"
|
||||
disabled
|
||||
type="text"
|
||||
id="apiKey"
|
||||
name="apiKey"
|
||||
|
||||
@@ -100,7 +100,6 @@ const DefaultEditView: React.FC<Props> = (props) => {
|
||||
<Upload
|
||||
data={data}
|
||||
{...upload}
|
||||
fieldTypes={fieldTypes}
|
||||
/>
|
||||
)}
|
||||
<RenderFields
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React, {
|
||||
useState, useRef, useEffect, useCallback,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import useFieldType from '../../../../forms/useFieldType';
|
||||
import Button from '../../../../elements/Button';
|
||||
import FileDetails from '../../../../elements/FileDetails';
|
||||
import Error from '../../../../forms/Error';
|
||||
import { Props, Data } from './types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -24,9 +24,9 @@ const validate = (value) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const File = (props) => {
|
||||
const inputRef = useRef();
|
||||
const dropRef = useRef();
|
||||
const File: React.FC<Props> = (props) => {
|
||||
const inputRef = useRef(null);
|
||||
const dropRef = useRef(null);
|
||||
const [fileList, setFileList] = useState(undefined);
|
||||
const [selectingFile, setSelectingFile] = useState(false);
|
||||
const [dragging, setDragging] = useState(false);
|
||||
@@ -34,7 +34,9 @@ const File = (props) => {
|
||||
const [replacingFile, setReplacingFile] = useState(false);
|
||||
|
||||
const {
|
||||
data = {}, adminThumbnail, staticURL,
|
||||
data = {} as Data,
|
||||
adminThumbnail,
|
||||
staticURL,
|
||||
} = props;
|
||||
|
||||
const { filename } = data;
|
||||
@@ -44,7 +46,7 @@ const File = (props) => {
|
||||
setValue,
|
||||
showError,
|
||||
errorMessage,
|
||||
} = useFieldType({
|
||||
} = useFieldType<{name: string}>({
|
||||
path: 'file',
|
||||
validate,
|
||||
});
|
||||
@@ -111,7 +113,7 @@ const File = (props) => {
|
||||
};
|
||||
}
|
||||
|
||||
return () => { };
|
||||
return () => null;
|
||||
}, [handleDragIn, handleDragOut, handleDrop, dropRef]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -197,20 +199,4 @@ const File = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
File.defaultProps = {
|
||||
data: undefined,
|
||||
adminThumbnail: undefined,
|
||||
};
|
||||
|
||||
File.propTypes = {
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
data: PropTypes.shape({
|
||||
filename: PropTypes.string,
|
||||
mimeType: PropTypes.string,
|
||||
filesize: PropTypes.number,
|
||||
}),
|
||||
staticURL: PropTypes.string.isRequired,
|
||||
adminThumbnail: PropTypes.string,
|
||||
};
|
||||
|
||||
export default File;
|
||||
|
||||
11
src/admin/components/views/collections/Edit/Upload/types.ts
Normal file
11
src/admin/components/views/collections/Edit/Upload/types.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export type Data = {
|
||||
filename: string
|
||||
mimeType: string
|
||||
filesize: number
|
||||
}
|
||||
|
||||
export type Props = {
|
||||
data?: Data
|
||||
adminThumbnail?: string
|
||||
staticURL: string
|
||||
}
|
||||
@@ -4,16 +4,15 @@ import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
import { useStepNav } from '../../../elements/StepNav';
|
||||
import usePayloadAPI from '../../../../hooks/usePayloadAPI';
|
||||
|
||||
|
||||
import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
|
||||
import DefaultEdit from './Default';
|
||||
import buildStateFromSchema from '../../../forms/Form/buildStateFromSchema';
|
||||
import { NegativeFieldGutterProvider } from '../../../forms/FieldTypeGutter/context';
|
||||
import { useLocale } from '../../../utilities/Locale';
|
||||
import { Props } from './types';
|
||||
import { IndexProps } from './types';
|
||||
import { StepNavItem } from '../../../elements/StepNav/types';
|
||||
|
||||
const EditView: React.FC<Props> = (props) => {
|
||||
const EditView: React.FC<IndexProps> = (props) => {
|
||||
const { collection, isEditing } = props;
|
||||
|
||||
const {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Fields } from '../../../forms/Form/types';
|
||||
|
||||
export type IndexProps = {
|
||||
collection: CollectionConfig
|
||||
isEditing: boolean
|
||||
isEditing?: boolean
|
||||
}
|
||||
|
||||
export type Props = IndexProps & {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* eslint-disable react/jsx-max-props-per-line */
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import BlocksCell from './types/Blocks';
|
||||
import DateCell from './types/Date';
|
||||
import Checkbox from './types/Checkbox';
|
||||
import BlocksCell from './field-types/Blocks';
|
||||
import DateCell from './field-types/Date';
|
||||
import Checkbox from './field-types/Checkbox';
|
||||
|
||||
describe('Cell Types', () => {
|
||||
describe('Blocks', () => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const BlocksCell = ({ data, field }) => {
|
||||
const selectedBlocks = data ? data.map(({ blockType }) => blockType) : [];
|
||||
@@ -24,21 +23,4 @@ const BlocksCell = ({ data, field }) => {
|
||||
<span>{label}</span>
|
||||
);
|
||||
};
|
||||
|
||||
BlocksCell.defaultProps = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
BlocksCell.propTypes = {
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
field: PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
blocks: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default BlocksCell;
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -9,13 +8,4 @@ const Checkbox = ({ data }) => (
|
||||
<span>{JSON.stringify(data)}</span>
|
||||
</code>
|
||||
);
|
||||
|
||||
Checkbox.defaultProps = {
|
||||
data: undefined,
|
||||
};
|
||||
|
||||
Checkbox.propTypes = {
|
||||
data: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -12,12 +11,4 @@ const CodeCell = ({ data }) => {
|
||||
);
|
||||
};
|
||||
|
||||
CodeCell.defaultProps = {
|
||||
data: '',
|
||||
};
|
||||
|
||||
CodeCell.propTypes = {
|
||||
data: PropTypes.string,
|
||||
};
|
||||
|
||||
export default CodeCell;
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import format from 'date-fns/format';
|
||||
|
||||
const DateCell = ({ data }) => (
|
||||
@@ -8,12 +7,4 @@ const DateCell = ({ data }) => (
|
||||
</span>
|
||||
);
|
||||
|
||||
DateCell.defaultProps = {
|
||||
data: undefined,
|
||||
};
|
||||
|
||||
DateCell.propTypes = {
|
||||
data: PropTypes.string,
|
||||
};
|
||||
|
||||
export default DateCell;
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
|
||||
const RelationshipCell = (props) => {
|
||||
@@ -48,24 +47,4 @@ const RelationshipCell = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
RelationshipCell.defaultProps = {
|
||||
data: undefined,
|
||||
};
|
||||
|
||||
RelationshipCell.propTypes = {
|
||||
data: PropTypes.oneOfType([
|
||||
PropTypes.shape({}),
|
||||
PropTypes.array,
|
||||
PropTypes.string,
|
||||
]),
|
||||
field: PropTypes.shape({
|
||||
relationTo: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(
|
||||
PropTypes.string,
|
||||
),
|
||||
PropTypes.string,
|
||||
]),
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default RelationshipCell;
|
||||
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
const RichTextCell = ({ data }) => {
|
||||
const flattenedText = data?.map((i) => i?.children?.map((c) => c.text)).join(' ');
|
||||
const textToShow = flattenedText.length > 100 ? `${flattenedText.slice(0, 100)}\u2026` : flattenedText;
|
||||
return (
|
||||
<span>{textToShow}</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default RichTextCell;
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
const SelectCell = ({ data, field }) => {
|
||||
const findLabel = (items) => items.map((i) => {
|
||||
const found = field.options.filter((f) => f.value === i)?.[0]?.label;
|
||||
return found;
|
||||
}).join(', ');
|
||||
|
||||
let content = '';
|
||||
if (field?.options?.[0]?.value) {
|
||||
content = (Array.isArray(data))
|
||||
? findLabel(data) // hasMany
|
||||
: findLabel([data]);
|
||||
} else {
|
||||
content = data.join(', ');
|
||||
}
|
||||
return (
|
||||
<span>
|
||||
{content}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectCell;
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const TextareaCell = ({ data }) => {
|
||||
const textToShow = data.length > 100 ? `${data.substr(0, 100)}\u2026` : data;
|
||||
@@ -8,15 +7,4 @@ const TextareaCell = ({ data }) => {
|
||||
);
|
||||
};
|
||||
|
||||
TextareaCell.defaultProps = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
TextareaCell.propTypes = {
|
||||
data: PropTypes.string,
|
||||
field: PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default TextareaCell;
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -16,18 +15,4 @@ const UploadCell = ({ data }) => (
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
UploadCell.defaultProps = {
|
||||
data: {},
|
||||
};
|
||||
|
||||
UploadCell.propTypes = {
|
||||
data: PropTypes.oneOfType([
|
||||
PropTypes.shape({
|
||||
filename: PropTypes.string,
|
||||
mimeType: PropTypes.string,
|
||||
}),
|
||||
PropTypes.string,
|
||||
]),
|
||||
};
|
||||
|
||||
export default UploadCell;
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import RenderCustomComponent from '../../../../utilities/RenderCustomComponent';
|
||||
import cellComponents from './types';
|
||||
import cellComponents from './field-types';
|
||||
import { Props } from './types';
|
||||
|
||||
const DefaultCell = (props) => {
|
||||
const DefaultCell: React.FC<Props> = (props) => {
|
||||
const {
|
||||
field,
|
||||
colIndex,
|
||||
@@ -20,9 +20,11 @@ const DefaultCell = (props) => {
|
||||
|
||||
const { routes: { admin } } = useConfig();
|
||||
|
||||
let WrapElement = 'span';
|
||||
let WrapElement: React.ComponentType | string = 'span';
|
||||
|
||||
const wrapElementProps = {};
|
||||
const wrapElementProps: {
|
||||
to?: string
|
||||
} = {};
|
||||
|
||||
if (colIndex === 0) {
|
||||
WrapElement = Link;
|
||||
@@ -52,7 +54,7 @@ const DefaultCell = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Cell = (props) => {
|
||||
const Cell: React.FC<Props> = (props) => {
|
||||
const {
|
||||
colIndex,
|
||||
collection,
|
||||
@@ -83,44 +85,4 @@ const Cell = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
cellData: undefined,
|
||||
};
|
||||
|
||||
const propTypes = {
|
||||
colIndex: PropTypes.number.isRequired,
|
||||
collection: PropTypes.shape({
|
||||
slug: PropTypes.string,
|
||||
upload: PropTypes.shape({
|
||||
adminThumbnail: PropTypes.string,
|
||||
}),
|
||||
}).isRequired,
|
||||
cellData: PropTypes.oneOfType([
|
||||
PropTypes.shape({}),
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
PropTypes.instanceOf(Date),
|
||||
PropTypes.array,
|
||||
PropTypes.bool,
|
||||
]),
|
||||
rowData: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
field: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
admin: PropTypes.shape({
|
||||
components: PropTypes.shape({
|
||||
Cell: PropTypes.func,
|
||||
}),
|
||||
}),
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
DefaultCell.defaultProps = defaultProps;
|
||||
DefaultCell.propTypes = propTypes;
|
||||
Cell.defaultProps = defaultProps;
|
||||
Cell.propTypes = propTypes;
|
||||
|
||||
export default Cell;
|
||||
|
||||
12
src/admin/components/views/collections/List/Cell/types.ts
Normal file
12
src/admin/components/views/collections/List/Cell/types.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Field } from '../../../../../../fields/config/types';
|
||||
import { CollectionConfig } from '../../../../../../collections/config/types';
|
||||
|
||||
export type Props = {
|
||||
field: Field
|
||||
colIndex: number
|
||||
collection: CollectionConfig
|
||||
cellData: unknown
|
||||
rowData: {
|
||||
[path: string]: unknown
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const RichTextCell = ({ data }) => {
|
||||
const flattenedText = data?.map((i) => i?.children?.map((c) => c.text)).join(' ');
|
||||
const textToShow = flattenedText.length > 100 ? `${flattenedText.slice(0, 100)}\u2026` : flattenedText;
|
||||
return (
|
||||
<span>{textToShow}</span>
|
||||
);
|
||||
};
|
||||
|
||||
RichTextCell.defaultProps = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
RichTextCell.propTypes = {
|
||||
data: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
children: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
bold: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
|
||||
|
||||
field: PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default RichTextCell;
|
||||
@@ -1,54 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const SelectCell = ({ data, field }) => {
|
||||
const findLabel = (items) => items.map((i) => {
|
||||
const found = field.options.filter((f) => f.value === i)?.[0]?.label;
|
||||
return found;
|
||||
}).join(', ');
|
||||
|
||||
let content = '';
|
||||
if (field?.options?.[0]?.value) {
|
||||
content = (Array.isArray(data))
|
||||
? findLabel(data) // hasMany
|
||||
: findLabel([data]);
|
||||
} else {
|
||||
content = data.join(', ');
|
||||
}
|
||||
return (
|
||||
<span>
|
||||
{content}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
SelectCell.defaultProps = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
SelectCell.propTypes = {
|
||||
data: PropTypes.oneOfType(
|
||||
[
|
||||
PropTypes.string,
|
||||
PropTypes.arrayOf(PropTypes.string),
|
||||
PropTypes.arrayOf(PropTypes.shape({
|
||||
value: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
})),
|
||||
],
|
||||
),
|
||||
field: PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.shape({
|
||||
value: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
}),
|
||||
]),
|
||||
),
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default SelectCell;
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useConfig } from '@payloadcms/config-provider';
|
||||
import UploadGallery from '../../../elements/UploadGallery';
|
||||
import Eyebrow from '../../../elements/Eyebrow';
|
||||
@@ -10,12 +9,13 @@ import Pill from '../../../elements/Pill';
|
||||
import Button from '../../../elements/Button';
|
||||
import Table from '../../../elements/Table';
|
||||
import Meta from '../../../utilities/Meta';
|
||||
import { Props } from './types';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'collection-list';
|
||||
|
||||
const DefaultList = (props) => {
|
||||
const DefaultList: React.FC<Props> = (props) => {
|
||||
const {
|
||||
collection,
|
||||
collection: {
|
||||
@@ -132,49 +132,4 @@ const DefaultList = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
DefaultList.defaultProps = {
|
||||
data: null,
|
||||
};
|
||||
|
||||
DefaultList.propTypes = {
|
||||
collection: PropTypes.shape({
|
||||
upload: PropTypes.shape({}),
|
||||
labels: PropTypes.shape({
|
||||
singular: PropTypes.string,
|
||||
plural: PropTypes.string,
|
||||
}),
|
||||
slug: PropTypes.string,
|
||||
admin: PropTypes.shape({
|
||||
useAsTitle: PropTypes.string,
|
||||
}),
|
||||
fields: PropTypes.arrayOf(PropTypes.shape),
|
||||
timestamps: PropTypes.bool,
|
||||
}).isRequired,
|
||||
newDocumentURL: PropTypes.string.isRequired,
|
||||
data: PropTypes.shape({
|
||||
docs: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
limit: PropTypes.number,
|
||||
nextPage: PropTypes.number,
|
||||
prevPage: PropTypes.number,
|
||||
totalDocs: PropTypes.number,
|
||||
hasNextPage: PropTypes.bool,
|
||||
hasPrevPage: PropTypes.bool,
|
||||
page: PropTypes.number,
|
||||
totalPages: PropTypes.number,
|
||||
}),
|
||||
setListControls: PropTypes.func.isRequired,
|
||||
setSort: PropTypes.func.isRequired,
|
||||
listControls: PropTypes.shape({
|
||||
columns: PropTypes.arrayOf(
|
||||
PropTypes.string,
|
||||
),
|
||||
}).isRequired,
|
||||
hasCreatePermission: PropTypes.bool.isRequired,
|
||||
columns: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
export default DefaultList;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import Cell from './Cell';
|
||||
import SortColumn from '../../../elements/SortColumn';
|
||||
import { CollectionConfig } from '../../../../../collections/config/types';
|
||||
import { Column } from '../../../elements/Table/types';
|
||||
import { fieldHasSubFields, Field } from '../../../../../fields/config/types';
|
||||
|
||||
const buildColumns = (collection, columns, setSort) => (columns || []).reduce((cols, col, colIndex) => {
|
||||
const buildColumns = (collection: CollectionConfig, columns: string[], setSort: (sort: string) => void): Column[] => (columns || []).reduce((cols, col, colIndex) => {
|
||||
let field = null;
|
||||
|
||||
const fields = [
|
||||
@@ -11,17 +14,17 @@ const buildColumns = (collection, columns, setSort) => (columns || []).reduce((c
|
||||
name: 'id',
|
||||
type: 'text',
|
||||
label: 'ID',
|
||||
},
|
||||
} as Field,
|
||||
{
|
||||
name: 'updatedAt',
|
||||
type: 'date',
|
||||
label: 'Updated At',
|
||||
},
|
||||
} as Field,
|
||||
{
|
||||
name: 'createdAt',
|
||||
type: 'date',
|
||||
label: 'Created At',
|
||||
},
|
||||
} as Field,
|
||||
];
|
||||
|
||||
fields.forEach((fieldToCheck) => {
|
||||
@@ -29,7 +32,7 @@ const buildColumns = (collection, columns, setSort) => (columns || []).reduce((c
|
||||
field = fieldToCheck;
|
||||
}
|
||||
|
||||
if (!fieldToCheck.name && Array.isArray(fieldToCheck.fields)) {
|
||||
if (!fieldToCheck.name && fieldHasSubFields(fieldToCheck)) {
|
||||
fieldToCheck.fields.forEach((subField) => {
|
||||
if (subField.name === col) {
|
||||
field = subField;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import queryString from 'qs';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useConfig, useAuth } from '@payloadcms/config-provider';
|
||||
@@ -8,10 +7,12 @@ import usePayloadAPI from '../../../../hooks/usePayloadAPI';
|
||||
import DefaultList from './Default';
|
||||
import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
|
||||
import { useStepNav } from '../../../elements/StepNav';
|
||||
import { ListControls } from '../../../elements/ListControls/types';
|
||||
import formatFields from './formatFields';
|
||||
import buildColumns from './buildColumns';
|
||||
import { ListIndexProps } from './types';
|
||||
|
||||
const ListView = (props) => {
|
||||
const ListView: React.FC<ListIndexProps> = (props) => {
|
||||
const {
|
||||
collection,
|
||||
collection: {
|
||||
@@ -21,8 +22,14 @@ const ListView = (props) => {
|
||||
},
|
||||
admin: {
|
||||
components: {
|
||||
List: CustomList,
|
||||
} = {},
|
||||
views: {
|
||||
List: CustomList,
|
||||
},
|
||||
} = {
|
||||
views: {
|
||||
List: undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} = props;
|
||||
@@ -33,7 +40,7 @@ const ListView = (props) => {
|
||||
const { setStepNav } = useStepNav();
|
||||
|
||||
const [fields] = useState(() => formatFields(collection));
|
||||
const [listControls, setListControls] = useState({});
|
||||
const [listControls, setListControls] = useState<ListControls>({});
|
||||
const [columns, setColumns] = useState([]);
|
||||
const [sort, setSort] = useState(null);
|
||||
|
||||
@@ -51,6 +58,9 @@ const ListView = (props) => {
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
depth: 1,
|
||||
page: undefined,
|
||||
sort: undefined,
|
||||
where: undefined,
|
||||
};
|
||||
|
||||
if (page) params.page = page;
|
||||
@@ -90,21 +100,4 @@ const ListView = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
ListView.propTypes = {
|
||||
collection: PropTypes.shape({
|
||||
labels: PropTypes.shape({
|
||||
singular: PropTypes.string,
|
||||
plural: PropTypes.string,
|
||||
}),
|
||||
admin: PropTypes.shape({
|
||||
components: PropTypes.shape({
|
||||
List: PropTypes.node,
|
||||
}),
|
||||
}),
|
||||
slug: PropTypes.string,
|
||||
fields: PropTypes.arrayOf(PropTypes.shape),
|
||||
timestamps: PropTypes.bool,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default ListView;
|
||||
|
||||
16
src/admin/components/views/collections/List/types.ts
Normal file
16
src/admin/components/views/collections/List/types.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { CollectionConfig, PaginatedDocs } from '../../../../../collections/config/types';
|
||||
import { Column } from '../../../elements/Table/types';
|
||||
|
||||
export type Props = {
|
||||
collection: CollectionConfig
|
||||
data: PaginatedDocs
|
||||
newDocumentURL: string
|
||||
setListControls: (controls: unknown) => void
|
||||
setSort: (sort: string) => void
|
||||
columns: Column[]
|
||||
hasCreatePermission: boolean
|
||||
}
|
||||
|
||||
export type ListIndexProps = {
|
||||
collection: CollectionConfig
|
||||
}
|
||||
@@ -15,7 +15,7 @@ const useIntersect = ({
|
||||
const [node, setNode] = useState(null);
|
||||
|
||||
const observer = useRef(
|
||||
new window.IntersectionObserver(([entry]) => updateEntry(entry), {
|
||||
new window.IntersectionObserver(([ent]) => updateEntry(ent), {
|
||||
root,
|
||||
rootMargin,
|
||||
threshold,
|
||||
|
||||
@@ -69,6 +69,9 @@ export type PayloadConfig = {
|
||||
Icon?: React.ComponentType
|
||||
Logo?: React.ComponentType
|
||||
}
|
||||
views?: {
|
||||
Dashboard?: React.ComponentType
|
||||
}
|
||||
}
|
||||
};
|
||||
collections?: PayloadCollectionConfig[];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import React from 'react';
|
||||
import { Model, Document } from 'mongoose';
|
||||
import { DeepRequired } from 'ts-essentials';
|
||||
import { Access } from '../../config/types';
|
||||
@@ -8,6 +9,7 @@ export type GlobalModel = Model<Document>
|
||||
export type PayloadGlobalConfig = {
|
||||
slug: string
|
||||
label?: string
|
||||
preview?: (doc: Document, token: string) => string
|
||||
access?: {
|
||||
create?: Access;
|
||||
read?: Access;
|
||||
@@ -16,6 +18,13 @@ export type PayloadGlobalConfig = {
|
||||
admin?: Access;
|
||||
}
|
||||
fields: Field[];
|
||||
admin?: {
|
||||
components?: {
|
||||
views?: {
|
||||
Edit?: React.ComponentType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type GlobalConfig = DeepRequired<PayloadGlobalConfig>
|
||||
|
||||
Reference in New Issue
Block a user