payload 1.1.7 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/forms.ts +10 -0
- package/dist/admin/components/elements/Autosave/index.js +3 -3
- package/dist/admin/components/elements/Nav/index.scss +1 -5
- package/dist/admin/components/elements/ReactSelect/index.scss +5 -1
- package/dist/admin/components/forms/Form/context.d.ts +5 -2
- package/dist/admin/components/forms/Form/context.js +9 -2
- package/dist/admin/components/forms/Form/fieldReducer.d.ts +2 -2
- package/dist/admin/components/forms/Form/fieldReducer.js +4 -1
- package/dist/admin/components/forms/Form/getSiblingData.js +11 -5
- package/dist/admin/components/forms/Form/index.js +12 -12
- package/dist/admin/components/forms/Form/initContextState.js +0 -3
- package/dist/admin/components/forms/Form/reduceFieldsToValues.js +6 -3
- package/dist/admin/components/forms/Form/types.d.ts +49 -7
- package/dist/admin/components/forms/field-types/Code/Code.js +0 -1
- package/dist/admin/components/forms/field-types/ConfirmPassword/index.js +2 -4
- package/dist/admin/components/forms/field-types/Email/index.js +0 -1
- package/dist/admin/components/forms/field-types/Number/index.js +0 -1
- package/dist/admin/components/forms/field-types/Password/index.js +0 -1
- package/dist/admin/components/forms/field-types/Point/index.js +0 -1
- package/dist/admin/components/forms/field-types/Relationship/AddNew/Modal/index.d.ts +4 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/Modal/index.js +67 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/Modal/index.scss +117 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/Modal/types.d.ts +6 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/Modal/types.js +1 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/index.d.ts +4 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/index.js +79 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/index.scss +60 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/types.d.ts +10 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/types.js +1 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/useRelatedCollections.d.ts +2 -0
- package/dist/admin/components/forms/field-types/Relationship/AddNew/useRelatedCollections.js +10 -0
- package/dist/admin/components/forms/field-types/Relationship/index.js +57 -45
- package/dist/admin/components/forms/field-types/Relationship/index.scss +15 -12
- package/dist/admin/components/forms/field-types/Relationship/optionsReducer.js +8 -7
- package/dist/admin/components/forms/field-types/Relationship/types.d.ts +1 -3
- package/dist/admin/components/forms/field-types/RichText/elements/relationship/Button/Fields/index.js +2 -3
- package/dist/admin/components/forms/field-types/Select/index.scss +1 -9
- package/dist/admin/components/forms/field-types/Text/index.js +0 -1
- package/dist/admin/components/forms/field-types/Textarea/index.js +0 -1
- package/dist/admin/components/forms/field-types/Upload/SelectExisting/index.js +2 -2
- package/dist/admin/components/forms/useField/index.js +71 -97
- package/dist/admin/components/forms/useField/types.d.ts +0 -2
- package/dist/admin/components/forms/withCondition/index.js +10 -5
- package/dist/admin/components/modals/LeaveWithoutSaving/index.scss +2 -2
- package/dist/admin/components/templates/Default/index.scss +1 -1
- package/dist/admin/components/utilities/EditDepth/index.d.ts +3 -0
- package/dist/admin/components/utilities/EditDepth/index.js +3 -0
- package/dist/admin/components/views/collections/Edit/Auth/APIKey.js +2 -3
- package/dist/admin/components/views/collections/Edit/Auth/index.js +3 -3
- package/dist/admin/components/views/collections/Edit/Default.js +9 -9
- package/dist/admin/components/views/collections/Edit/index.js +15 -12
- package/dist/admin/components/views/collections/Edit/types.d.ts +6 -0
- package/dist/admin/hooks/useTitle.js +2 -3
- package/dist/admin/index.js +1 -1
- package/dist/admin/scss/app.scss +6 -1
- package/dist/collections/config/defaults.d.ts +5 -5
- package/dist/config/types.d.ts +6 -1
- package/dist/express/types.d.ts +2 -2
- package/dist/fields/config/types.d.ts +2 -2
- package/docs/admin/components.mdx +3 -45
- package/docs/admin/customizing-css.mdx +1 -1
- package/docs/admin/hooks.mdx +271 -0
- package/docs/admin/preferences.mdx +1 -1
- package/docs/admin/webpack.mdx +1 -1
- package/docs/local-api/overview.mdx +1 -1
- package/package.json +2 -1
- package/types.d.ts +4 -0
|
@@ -13,7 +13,7 @@ import PerPage from '../../../../elements/PerPage';
|
|
|
13
13
|
import formatFields from '../../../../views/collections/List/formatFields';
|
|
14
14
|
import { getFilterOptionsQuery } from '../../getFilterOptionsQuery';
|
|
15
15
|
import { useDocumentInfo } from '../../../../utilities/DocumentInfo';
|
|
16
|
-
import {
|
|
16
|
+
import { useForm } from '../../../Form/context';
|
|
17
17
|
import ViewDescription from '../../../../elements/ViewDescription';
|
|
18
18
|
import './index.scss';
|
|
19
19
|
const baseClass = 'select-existing-upload-modal';
|
|
@@ -23,7 +23,7 @@ const SelectExistingUploadModal = (props) => {
|
|
|
23
23
|
const { serverURL, routes: { api } } = useConfig();
|
|
24
24
|
const { id } = useDocumentInfo();
|
|
25
25
|
const { user } = useAuth();
|
|
26
|
-
const { getData, getSiblingData } =
|
|
26
|
+
const { getData, getSiblingData } = useForm();
|
|
27
27
|
const { toggleModal, modalState } = useModal();
|
|
28
28
|
const [fields] = useState(() => formatFields(collection));
|
|
29
29
|
const [limit, setLimit] = useState(defaultLimit);
|
|
@@ -1,88 +1,26 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
2
|
import { useAuth } from '../../utilities/Auth';
|
|
3
|
-
import { useFormProcessing, useFormSubmitted, useFormModified, useForm } from '../Form/context';
|
|
4
|
-
import useDebounce from '../../../hooks/useDebounce';
|
|
3
|
+
import { useFormProcessing, useFormSubmitted, useFormModified, useForm, useFormFields } from '../Form/context';
|
|
5
4
|
import { useDocumentInfo } from '../../utilities/DocumentInfo';
|
|
6
5
|
import { useOperation } from '../../utilities/OperationProvider';
|
|
6
|
+
import useThrottledEffect from '../../../hooks/useThrottledEffect';
|
|
7
7
|
const useField = (options) => {
|
|
8
|
-
const { path, validate,
|
|
9
|
-
const formContext = useForm();
|
|
8
|
+
const { path, validate, disableFormData = false, condition, } = options;
|
|
10
9
|
const submitted = useFormSubmitted();
|
|
11
10
|
const processing = useFormProcessing();
|
|
12
11
|
const modified = useFormModified();
|
|
13
12
|
const { user } = useAuth();
|
|
14
13
|
const { id } = useDocumentInfo();
|
|
15
14
|
const operation = useOperation();
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
15
|
+
const field = useFormFields(([fields]) => fields[path]);
|
|
16
|
+
const dispatchField = useFormFields(([_, dispatch]) => dispatch);
|
|
17
|
+
const { getData, getSiblingData, setModified } = useForm();
|
|
18
|
+
const value = field === null || field === void 0 ? void 0 : field.value;
|
|
19
19
|
const initialValue = field === null || field === void 0 ? void 0 : field.initialValue;
|
|
20
|
-
const
|
|
21
|
-
const [internalValue, setInternalValue] = useState(() => field === null || field === void 0 ? void 0 : field.value);
|
|
22
|
-
const [internallyValid, setInternallyValid] = useState(undefined);
|
|
23
|
-
// Debounce internal values to update form state only every 60ms
|
|
24
|
-
const debouncedValue = useDebounce(internalValue, 120);
|
|
25
|
-
// Validation is defined by two ways -
|
|
26
|
-
// 1. by field state
|
|
27
|
-
// 2. maintained locally to reflect instant validation state changes
|
|
28
|
-
let valid = true;
|
|
29
|
-
if (field && typeof field.valid === 'boolean') {
|
|
30
|
-
valid = field.valid;
|
|
31
|
-
}
|
|
32
|
-
if (typeof internallyValid === 'boolean') {
|
|
33
|
-
valid = internallyValid;
|
|
34
|
-
}
|
|
20
|
+
const valid = typeof (field === null || field === void 0 ? void 0 : field.valid) === 'boolean' ? field.valid : true;
|
|
35
21
|
const showError = valid === false && submitted;
|
|
36
|
-
// Method to send update field values from field component(s)
|
|
37
|
-
// Should only be used internally
|
|
38
|
-
const sendField = useCallback(async (valueToSend) => {
|
|
39
|
-
const fieldToDispatch = {
|
|
40
|
-
path,
|
|
41
|
-
disableFormData,
|
|
42
|
-
initialValue,
|
|
43
|
-
validate,
|
|
44
|
-
condition,
|
|
45
|
-
value: valueToSend,
|
|
46
|
-
valid: false,
|
|
47
|
-
errorMessage: undefined,
|
|
48
|
-
};
|
|
49
|
-
const validateOptions = {
|
|
50
|
-
id,
|
|
51
|
-
user,
|
|
52
|
-
data: getData(),
|
|
53
|
-
siblingData: getSiblingData(path),
|
|
54
|
-
operation,
|
|
55
|
-
};
|
|
56
|
-
const validationResult = typeof validate === 'function' ? await validate(valueToSend, validateOptions) : true;
|
|
57
|
-
if (typeof validationResult === 'string') {
|
|
58
|
-
fieldToDispatch.errorMessage = validationResult;
|
|
59
|
-
fieldToDispatch.valid = false;
|
|
60
|
-
setInternallyValid(false);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
fieldToDispatch.valid = validationResult;
|
|
64
|
-
fieldToDispatch.errorMessage = undefined;
|
|
65
|
-
setInternallyValid(true);
|
|
66
|
-
}
|
|
67
|
-
if (typeof dispatchFields === 'function') {
|
|
68
|
-
dispatchFields(fieldToDispatch);
|
|
69
|
-
}
|
|
70
|
-
}, [
|
|
71
|
-
condition,
|
|
72
|
-
disableFormData,
|
|
73
|
-
dispatchFields,
|
|
74
|
-
getData,
|
|
75
|
-
getSiblingData,
|
|
76
|
-
id,
|
|
77
|
-
initialValue,
|
|
78
|
-
operation,
|
|
79
|
-
path,
|
|
80
|
-
user,
|
|
81
|
-
validate,
|
|
82
|
-
]);
|
|
83
22
|
// Method to return from `useField`, used to
|
|
84
|
-
// update
|
|
85
|
-
// as fast as they arrive. NOTE - this method is NOT debounced
|
|
23
|
+
// update field values from field component(s)
|
|
86
24
|
const setValue = useCallback((e, disableModifyingForm = false) => {
|
|
87
25
|
const val = (e && e.target) ? e.target.value : e;
|
|
88
26
|
if (!modified && !disableModifyingForm) {
|
|
@@ -90,42 +28,78 @@ const useField = (options) => {
|
|
|
90
28
|
setModified(true);
|
|
91
29
|
}
|
|
92
30
|
}
|
|
93
|
-
|
|
31
|
+
dispatchField({
|
|
32
|
+
type: 'UPDATE',
|
|
33
|
+
path,
|
|
34
|
+
value: val,
|
|
35
|
+
disableFormData,
|
|
36
|
+
});
|
|
94
37
|
}, [
|
|
95
38
|
setModified,
|
|
96
39
|
modified,
|
|
97
|
-
]);
|
|
98
|
-
useEffect(() => {
|
|
99
|
-
if (internalInitialValue !== initialValue) {
|
|
100
|
-
setInternalValue(initialValue);
|
|
101
|
-
setInternalInitialValue(initialValue);
|
|
102
|
-
}
|
|
103
|
-
setInternallyValid(undefined);
|
|
104
|
-
}, [initialValue, internalInitialValue]);
|
|
105
|
-
// The only time that the FORM value should be updated
|
|
106
|
-
// is when the debounced value updates. So, when the debounced value updates,
|
|
107
|
-
// send it up to the form
|
|
108
|
-
const valueToSend = enableDebouncedValue ? debouncedValue : internalValue;
|
|
109
|
-
useEffect(() => {
|
|
110
|
-
if (((field === null || field === void 0 ? void 0 : field.value) !== valueToSend && valueToSend !== undefined) || disableFormData !== (field === null || field === void 0 ? void 0 : field.disableFormData)) {
|
|
111
|
-
sendField(valueToSend);
|
|
112
|
-
}
|
|
113
|
-
}, [
|
|
114
40
|
path,
|
|
115
|
-
|
|
116
|
-
sendField,
|
|
117
|
-
field,
|
|
41
|
+
dispatchField,
|
|
118
42
|
disableFormData,
|
|
119
43
|
]);
|
|
120
|
-
|
|
121
|
-
|
|
44
|
+
// Store result from hook as ref
|
|
45
|
+
// to prevent unnecessary rerenders
|
|
46
|
+
const result = useMemo(() => ({
|
|
122
47
|
showError,
|
|
123
48
|
errorMessage: field === null || field === void 0 ? void 0 : field.errorMessage,
|
|
124
|
-
value
|
|
49
|
+
value,
|
|
125
50
|
formSubmitted: submitted,
|
|
126
51
|
formProcessing: processing,
|
|
127
52
|
setValue,
|
|
128
53
|
initialValue,
|
|
129
|
-
};
|
|
54
|
+
}), [field, processing, setValue, showError, submitted, value, initialValue]);
|
|
55
|
+
// Throttle the validate function
|
|
56
|
+
useThrottledEffect(() => {
|
|
57
|
+
const validateField = async () => {
|
|
58
|
+
const action = {
|
|
59
|
+
type: 'UPDATE',
|
|
60
|
+
path,
|
|
61
|
+
disableFormData,
|
|
62
|
+
validate,
|
|
63
|
+
condition,
|
|
64
|
+
value,
|
|
65
|
+
valid: false,
|
|
66
|
+
errorMessage: undefined,
|
|
67
|
+
};
|
|
68
|
+
const validateOptions = {
|
|
69
|
+
id,
|
|
70
|
+
user,
|
|
71
|
+
data: getData(),
|
|
72
|
+
siblingData: getSiblingData(path),
|
|
73
|
+
operation,
|
|
74
|
+
};
|
|
75
|
+
const validationResult = typeof validate === 'function' ? await validate(value, validateOptions) : true;
|
|
76
|
+
if (typeof validationResult === 'string') {
|
|
77
|
+
action.errorMessage = validationResult;
|
|
78
|
+
action.valid = false;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
action.valid = validationResult;
|
|
82
|
+
action.errorMessage = undefined;
|
|
83
|
+
}
|
|
84
|
+
if (action.valid !== valid && typeof dispatchField === 'function') {
|
|
85
|
+
dispatchField(action);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
validateField();
|
|
89
|
+
}, 150, [
|
|
90
|
+
value,
|
|
91
|
+
condition,
|
|
92
|
+
disableFormData,
|
|
93
|
+
dispatchField,
|
|
94
|
+
getData,
|
|
95
|
+
getSiblingData,
|
|
96
|
+
id,
|
|
97
|
+
operation,
|
|
98
|
+
path,
|
|
99
|
+
user,
|
|
100
|
+
validate,
|
|
101
|
+
valid,
|
|
102
|
+
]);
|
|
103
|
+
return result;
|
|
130
104
|
};
|
|
131
105
|
export default useField;
|
|
@@ -2,9 +2,7 @@ import { Condition, Validate } from '../../../../fields/config/types';
|
|
|
2
2
|
export declare type Options = {
|
|
3
3
|
path: string;
|
|
4
4
|
validate?: Validate;
|
|
5
|
-
enableDebouncedValue?: boolean;
|
|
6
5
|
disableFormData?: boolean;
|
|
7
|
-
ignoreWhileFlattening?: boolean;
|
|
8
6
|
condition?: Condition;
|
|
9
7
|
};
|
|
10
8
|
export declare type FieldType<T> = {
|
|
@@ -22,9 +22,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
const react_1 = __importStar(require("react"));
|
|
27
30
|
const context_1 = require("../Form/context");
|
|
31
|
+
const getSiblingData_1 = __importDefault(require("../Form/getSiblingData"));
|
|
32
|
+
const reduceFieldsToValues_1 = __importDefault(require("../Form/reduceFieldsToValues"));
|
|
28
33
|
const withCondition = (Field) => {
|
|
29
34
|
const CheckForCondition = (props) => {
|
|
30
35
|
const { admin: { condition, } = {}, } = props;
|
|
@@ -36,12 +41,12 @@ const withCondition = (Field) => {
|
|
|
36
41
|
const WithCondition = (props) => {
|
|
37
42
|
const { name, path: pathFromProps, admin: { condition, } = {}, } = props;
|
|
38
43
|
const path = typeof pathFromProps === 'string' ? pathFromProps : name;
|
|
39
|
-
const
|
|
40
|
-
const data =
|
|
41
|
-
const siblingData =
|
|
44
|
+
const [fields, dispatchFields] = (0, context_1.useAllFormFields)();
|
|
45
|
+
const data = (0, reduceFieldsToValues_1.default)(fields, true);
|
|
46
|
+
const siblingData = (0, getSiblingData_1.default)(fields, path);
|
|
42
47
|
const hasCondition = Boolean(condition);
|
|
43
48
|
const currentlyPassesCondition = hasCondition ? condition(data, siblingData) : true;
|
|
44
|
-
const field =
|
|
49
|
+
const field = fields[path];
|
|
45
50
|
const existingConditionPasses = field === null || field === void 0 ? void 0 : field.passesCondition;
|
|
46
51
|
(0, react_1.useEffect)(() => {
|
|
47
52
|
if (hasCondition) {
|
|
@@ -61,4 +66,4 @@ const withCondition = (Field) => {
|
|
|
61
66
|
return CheckForCondition;
|
|
62
67
|
};
|
|
63
68
|
exports.default = withCondition;
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYWRtaW4vY29tcG9uZW50cy9mb3Jtcy93aXRoQ29uZGl0aW9uL2luZGV4LnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0NBQXlDO0FBRXpDLDZDQUFtRDtBQUNuRCw0RUFBb0Q7QUFDcEQsd0ZBQWdFO0FBRWhFLE1BQU0sYUFBYSxHQUFHLENBQW9DLEtBQTZCLEVBQWUsRUFBRTtJQUN0RyxNQUFNLGlCQUFpQixHQUFnQixDQUFDLEtBQUssRUFBRSxFQUFFO1FBQy9DLE1BQU0sRUFDSixLQUFLLEVBQUUsRUFDTCxTQUFTLEdBQ1YsR0FBRyxFQUFFLEdBQ1AsR0FBRyxLQUEyQixDQUFDO1FBRWhDLElBQUksU0FBUyxFQUFFO1lBQ2IsT0FBTyw4QkFBQyxhQUFhLE9BQUssS0FBSyxHQUFJLENBQUM7U0FDckM7UUFFRCxPQUFPLDhCQUFDLEtBQUssT0FBSyxLQUFLLEdBQUksQ0FBQztJQUM5QixDQUFDLENBQUM7SUFFRixNQUFNLGFBQWEsR0FBZ0IsQ0FBQyxLQUFLLEVBQUUsRUFBRTtRQUMzQyxNQUFNLEVBQ0osSUFBSSxFQUNKLElBQUksRUFBRSxhQUFhLEVBQ25CLEtBQUssRUFBRSxFQUNMLFNBQVMsR0FDVixHQUFHLEVBQUUsR0FDUCxHQUFHLEtBRUgsQ0FBQztRQUVGLE1BQU0sSUFBSSxHQUFHLE9BQU8sYUFBYSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFdEUsTUFBTSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsR0FBRyxJQUFBLDBCQUFnQixHQUFFLENBQUM7UUFFcEQsTUFBTSxJQUFJLEdBQUcsSUFBQSw4QkFBb0IsRUFBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEQsTUFBTSxXQUFXLEdBQUcsSUFBQSx3QkFBYyxFQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsTUFBTSx3QkFBd0IsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNwRixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0IsTUFBTSx1QkFBdUIsR0FBRyxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsZUFBZSxDQUFDO1FBRXZELElBQUEsaUJBQVMsRUFBQyxHQUFHLEVBQUU7WUFDYixJQUFJLFlBQVksRUFBRTtnQkFDaEIsSUFBSSxDQUFDLHVCQUF1QixJQUFJLHdCQUF3QixFQUFFO29CQUN4RCxjQUFjLENBQUMsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2lCQUNsRTtnQkFFRCxJQUFJLENBQUMsd0JBQXdCLElBQUksQ0FBQyx1QkFBdUIsSUFBSSxPQUFPLHVCQUF1QixLQUFLLFdBQVcsQ0FBQyxFQUFFO29CQUM1RyxjQUFjLENBQUMsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2lCQUNuRTthQUNGO1FBQ0gsQ0FBQyxFQUFFLENBQUMsd0JBQXdCLEVBQUUsdUJBQXVCLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBRTVGLElBQUksd0JBQXdCLEVBQUU7WUFDNUIsT0FBTyw4QkFBQyxLQUFLLE9BQUssS0FBSyxHQUFJLENBQUM7U0FDN0I7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUMsQ0FBQztJQUVGLE9BQU8saUJBQWlCLENBQUM7QUFDM0IsQ0FBQyxDQUFDO0FBRUYsa0JBQWUsYUFBYSxDQUFDIn0=
|
|
@@ -4,7 +4,7 @@ import useField from '../../../../forms/useField';
|
|
|
4
4
|
import Label from '../../../../forms/Label';
|
|
5
5
|
import CopyToClipboard from '../../../../elements/CopyToClipboard';
|
|
6
6
|
import { text } from '../../../../../../fields/validations';
|
|
7
|
-
import {
|
|
7
|
+
import { useFormFields } from '../../../../forms/Form/context';
|
|
8
8
|
import GenerateConfirmation from '../../../../elements/GenerateConfirmation';
|
|
9
9
|
const path = 'apiKey';
|
|
10
10
|
const baseClass = 'api-key';
|
|
@@ -12,8 +12,7 @@ const validate = (val) => text(val, { minLength: 24, maxLength: 48, data: {}, si
|
|
|
12
12
|
const APIKey = () => {
|
|
13
13
|
const [initialAPIKey, setInitialAPIKey] = useState(null);
|
|
14
14
|
const [highlightedField, setHighlightedField] = useState(false);
|
|
15
|
-
const
|
|
16
|
-
const apiKey = getField(path);
|
|
15
|
+
const apiKey = useFormFields(([fields]) => fields[path]);
|
|
17
16
|
const apiKeyValue = apiKey === null || apiKey === void 0 ? void 0 : apiKey.value;
|
|
18
17
|
const APIKeyLabel = useMemo(() => (React.createElement("div", { className: `${baseClass}__label` },
|
|
19
18
|
React.createElement("span", null, "API Key"),
|
|
@@ -6,16 +6,16 @@ import Password from '../../../../forms/field-types/Password';
|
|
|
6
6
|
import Checkbox from '../../../../forms/field-types/Checkbox';
|
|
7
7
|
import Button from '../../../../elements/Button';
|
|
8
8
|
import ConfirmPassword from '../../../../forms/field-types/ConfirmPassword';
|
|
9
|
-
import {
|
|
9
|
+
import { useFormModified, useFormFields } from '../../../../forms/Form/context';
|
|
10
10
|
import APIKey from './APIKey';
|
|
11
11
|
import './index.scss';
|
|
12
12
|
const baseClass = 'auth-fields';
|
|
13
13
|
const Auth = (props) => {
|
|
14
14
|
const { useAPIKey, requirePassword, verify, collection: { slug }, collection, email, operation } = props;
|
|
15
15
|
const [changingPassword, setChangingPassword] = useState(requirePassword);
|
|
16
|
-
const
|
|
16
|
+
const enableAPIKey = useFormFields(([fields]) => fields.enableAPIKey);
|
|
17
|
+
const dispatchFields = useFormFields((reducer) => reducer[1]);
|
|
17
18
|
const modified = useFormModified();
|
|
18
|
-
const enableAPIKey = getField('enableAPIKey');
|
|
19
19
|
const { serverURL, routes: { api, }, } = useConfig();
|
|
20
20
|
const handleChangePassword = useCallback(async (state) => {
|
|
21
21
|
if (!state) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Link
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
3
|
import format from 'date-fns/format';
|
|
4
4
|
import { useConfig } from '../../../utilities/Config';
|
|
5
5
|
import Eyebrow from '../../../elements/Eyebrow';
|
|
@@ -29,10 +29,9 @@ import './index.scss';
|
|
|
29
29
|
const baseClass = 'collection-edit';
|
|
30
30
|
const DefaultEditView = (props) => {
|
|
31
31
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
32
|
-
const { params: { id } = {} } = useRouteMatch();
|
|
33
32
|
const { admin: { dateFormat }, routes: { admin } } = useConfig();
|
|
34
33
|
const { publishedDoc } = useDocumentInfo();
|
|
35
|
-
const { collection, isEditing, data, onSave, permissions, isLoading, initialState, apiURL, action, hasSavePermission, } = props;
|
|
34
|
+
const { collection, isEditing, data, onSave, permissions, isLoading, initialState, apiURL, action, hasSavePermission, disableEyebrow, disableActions, disableLeaveWithoutSaving, customHeader, id, } = props;
|
|
36
35
|
const { slug, fields, admin: { useAsTitle, disableDuplicate, preview, hideAPIURL, }, versions, timestamps, auth, upload, } = collection;
|
|
37
36
|
const classes = [
|
|
38
37
|
baseClass,
|
|
@@ -45,26 +44,27 @@ const DefaultEditView = (props) => {
|
|
|
45
44
|
React.createElement(Form, { className: `${baseClass}__form`, method: id ? 'patch' : 'post', action: action, onSuccess: onSave, disabled: !hasSavePermission, initialState: initialState },
|
|
46
45
|
React.createElement("div", { className: `${baseClass}__main` },
|
|
47
46
|
React.createElement(Meta, { title: `${isEditing ? 'Editing' : 'Creating'} - ${collection.labels.singular}`, description: `${isEditing ? 'Editing' : 'Creating'} - ${collection.labels.singular}`, keywords: `${collection.labels.singular}, Payload, CMS` }),
|
|
48
|
-
React.createElement(Eyebrow, null),
|
|
49
|
-
!(((_a = collection.versions) === null || _a === void 0 ? void 0 : _a.drafts) && ((_c = (_b = collection.versions) === null || _b === void 0 ? void 0 : _b.drafts) === null || _c === void 0 ? void 0 : _c.autosave)) && (React.createElement(LeaveWithoutSaving, null)),
|
|
47
|
+
!disableEyebrow && (React.createElement(Eyebrow, null)),
|
|
48
|
+
(!(((_a = collection.versions) === null || _a === void 0 ? void 0 : _a.drafts) && ((_c = (_b = collection.versions) === null || _b === void 0 ? void 0 : _b.drafts) === null || _c === void 0 ? void 0 : _c.autosave)) && !disableLeaveWithoutSaving) && (React.createElement(LeaveWithoutSaving, null)),
|
|
50
49
|
React.createElement(Gutter, { className: `${baseClass}__edit` },
|
|
51
50
|
React.createElement("header", { className: `${baseClass}__header` },
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
customHeader && customHeader,
|
|
52
|
+
!customHeader && (React.createElement("h1", null,
|
|
53
|
+
React.createElement(RenderTitle, { ...{ data, useAsTitle, fallback: '[Untitled]' } })))),
|
|
54
54
|
auth && (React.createElement(Auth, { useAPIKey: auth.useAPIKey, requirePassword: !isEditing, verify: auth.verify, collection: collection, email: data === null || data === void 0 ? void 0 : data.email, operation: operation })),
|
|
55
55
|
upload && (React.createElement(Upload, { data: data, collection: collection })),
|
|
56
56
|
React.createElement(RenderFields, { readOnly: !hasSavePermission, permissions: permissions.fields, filter: (field) => { var _a, _b; return (!((_a = field === null || field === void 0 ? void 0 : field.admin) === null || _a === void 0 ? void 0 : _a.position) || (((_b = field === null || field === void 0 ? void 0 : field.admin) === null || _b === void 0 ? void 0 : _b.position) !== 'sidebar')); }, fieldTypes: fieldTypes, fieldSchema: fields }))),
|
|
57
57
|
React.createElement("div", { className: `${baseClass}__sidebar-wrap` },
|
|
58
58
|
React.createElement("div", { className: `${baseClass}__sidebar` },
|
|
59
59
|
React.createElement("div", { className: `${baseClass}__sidebar-sticky-wrap` },
|
|
60
|
-
React.createElement("ul", { className: `${baseClass}__collection-actions` },
|
|
60
|
+
!disableActions && (React.createElement("ul", { className: `${baseClass}__collection-actions` },
|
|
61
61
|
((_d = permissions === null || permissions === void 0 ? void 0 : permissions.create) === null || _d === void 0 ? void 0 : _d.permission) && (React.createElement(React.Fragment, null,
|
|
62
62
|
React.createElement("li", null,
|
|
63
63
|
React.createElement(Link, { id: "action-create", to: `${admin}/collections/${slug}/create` }, "Create New")),
|
|
64
64
|
!disableDuplicate && isEditing && (React.createElement("li", null,
|
|
65
65
|
React.createElement(DuplicateDocument, { collection: collection, id: id, slug: slug }))))),
|
|
66
66
|
((_e = permissions === null || permissions === void 0 ? void 0 : permissions.delete) === null || _e === void 0 ? void 0 : _e.permission) && (React.createElement("li", null,
|
|
67
|
-
React.createElement(DeleteDocument, { collection: collection, id: id, buttonId: "action-delete" })))),
|
|
67
|
+
React.createElement(DeleteDocument, { collection: collection, id: id, buttonId: "action-delete" }))))),
|
|
68
68
|
React.createElement("div", { className: `${baseClass}__document-actions${((((_f = collection.versions) === null || _f === void 0 ? void 0 : _f.drafts) && !((_h = (_g = collection.versions) === null || _g === void 0 ? void 0 : _g.drafts) === null || _h === void 0 ? void 0 : _h.autosave)) || (isEditing && preview)) ? ` ${baseClass}__document-actions--has-2` : ''}` },
|
|
69
69
|
(preview && (!((_j = collection.versions) === null || _j === void 0 ? void 0 : _j.drafts) || ((_l = (_k = collection.versions) === null || _k === void 0 ? void 0 : _k.drafts) === null || _l === void 0 ? void 0 : _l.autosave))) && (React.createElement(PreviewButton, { generatePreviewURL: preview, data: data })),
|
|
70
70
|
hasSavePermission && (React.createElement(React.Fragment, null,
|
|
@@ -11,6 +11,7 @@ import buildStateFromSchema from '../../../forms/Form/buildStateFromSchema';
|
|
|
11
11
|
import { useLocale } from '../../../utilities/Locale';
|
|
12
12
|
import { useDocumentInfo } from '../../../utilities/DocumentInfo';
|
|
13
13
|
import { usePreferences } from '../../../utilities/Preferences';
|
|
14
|
+
import { EditDepthContext } from '../../../utilities/EditDepth';
|
|
14
15
|
const EditView = (props) => {
|
|
15
16
|
var _a, _b, _c;
|
|
16
17
|
const { collection: incomingCollection, isEditing } = props;
|
|
@@ -95,17 +96,19 @@ const EditView = (props) => {
|
|
|
95
96
|
const apiURL = `${serverURL}${api}/${slug}/${id}${collection.versions.drafts ? '?draft=true' : ''}`;
|
|
96
97
|
const action = `${serverURL}${api}/${slug}${isEditing ? `/${id}` : ''}?locale=${locale}&depth=0&fallback-locale=null`;
|
|
97
98
|
const hasSavePermission = (isEditing && ((_b = collectionPermissions === null || collectionPermissions === void 0 ? void 0 : collectionPermissions.update) === null || _b === void 0 ? void 0 : _b.permission)) || (!isEditing && ((_c = collectionPermissions === null || collectionPermissions === void 0 ? void 0 : collectionPermissions.create) === null || _c === void 0 ? void 0 : _c.permission));
|
|
98
|
-
return (React.createElement(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
99
|
+
return (React.createElement(EditDepthContext.Provider, { value: 1 },
|
|
100
|
+
React.createElement(RenderCustomComponent, { DefaultComponent: DefaultEdit, CustomComponent: CustomEdit, componentProps: {
|
|
101
|
+
id,
|
|
102
|
+
isLoading: !initialState,
|
|
103
|
+
data: dataToRender,
|
|
104
|
+
collection,
|
|
105
|
+
permissions: collectionPermissions,
|
|
106
|
+
isEditing,
|
|
107
|
+
onSave,
|
|
108
|
+
initialState,
|
|
109
|
+
hasSavePermission,
|
|
110
|
+
apiURL,
|
|
111
|
+
action,
|
|
112
|
+
} })));
|
|
110
113
|
};
|
|
111
114
|
export default EditView;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { SanitizedCollectionConfig } from '../../../../../collections/config/types';
|
|
2
3
|
import { CollectionPermission } from '../../../../../auth/types';
|
|
3
4
|
import { Document } from '../../../../../types';
|
|
@@ -9,6 +10,7 @@ export declare type IndexProps = {
|
|
|
9
10
|
export declare type Props = IndexProps & {
|
|
10
11
|
data: Document;
|
|
11
12
|
onSave?: () => void;
|
|
13
|
+
id?: string;
|
|
12
14
|
permissions: CollectionPermission;
|
|
13
15
|
isLoading: boolean;
|
|
14
16
|
initialState?: Fields;
|
|
@@ -16,4 +18,8 @@ export declare type Props = IndexProps & {
|
|
|
16
18
|
action: string;
|
|
17
19
|
hasSavePermission: boolean;
|
|
18
20
|
autosaveEnabled: boolean;
|
|
21
|
+
disableEyebrow?: boolean;
|
|
22
|
+
disableActions?: boolean;
|
|
23
|
+
disableLeaveWithoutSaving?: boolean;
|
|
24
|
+
customHeader?: React.ReactNode;
|
|
19
25
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useFormFields } from '../components/forms/Form/context';
|
|
2
2
|
const useTitle = (useAsTitle) => {
|
|
3
|
-
const
|
|
4
|
-
const titleField = getField(useAsTitle);
|
|
3
|
+
const titleField = useFormFields(([fields]) => fields[useAsTitle]);
|
|
5
4
|
return titleField === null || titleField === void 0 ? void 0 : titleField.value;
|
|
6
5
|
};
|
|
7
6
|
export default useTitle;
|
package/dist/admin/index.js
CHANGED
|
@@ -28,7 +28,7 @@ const Index = () => (React.createElement(React.Fragment, null,
|
|
|
28
28
|
} },
|
|
29
29
|
React.createElement(ScrollInfoProvider, null,
|
|
30
30
|
React.createElement(Router, null,
|
|
31
|
-
React.createElement(ModalProvider, { classPrefix: "payload", zIndex:
|
|
31
|
+
React.createElement(ModalProvider, { classPrefix: "payload", zIndex: 'var(--z-modal)', transTime: 0 },
|
|
32
32
|
React.createElement(AuthProvider, null,
|
|
33
33
|
React.createElement(PreferencesProvider, null,
|
|
34
34
|
React.createElement(ThemeProvider, null,
|
package/dist/admin/scss/app.scss
CHANGED
|
@@ -9,10 +9,13 @@
|
|
|
9
9
|
--breakpoint-m-width : #{$breakpoint-m-width};
|
|
10
10
|
--breakpoint-l-width : #{$breakpoint-l-width};
|
|
11
11
|
--scrollbar-width: 17px;
|
|
12
|
+
--nav-width: #{base(9)};
|
|
12
13
|
|
|
13
14
|
--theme-bg: var(--theme-elevation-0);
|
|
14
15
|
--theme-input-bg: var(--theme-elevation-0);
|
|
15
16
|
--theme-text: var(--theme-elevation-800);
|
|
17
|
+
--theme-baseline: #{$baseline-px};
|
|
18
|
+
--theme-baseline-body-size: #{$baseline-body-size};
|
|
16
19
|
--font-body: 'Suisse Intl', system-ui;
|
|
17
20
|
--font-mono: monospace;
|
|
18
21
|
--font-serif: 'Merriweather', serif;
|
|
@@ -26,10 +29,12 @@
|
|
|
26
29
|
|
|
27
30
|
@include large-break {
|
|
28
31
|
--gutter-h: #{base(3)};
|
|
32
|
+
--nav-width: #{base(8)};
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
@include mid-break {
|
|
32
36
|
--gutter-h: #{base(2)};
|
|
37
|
+
--nav-width: 100%;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
@include small-break {
|
|
@@ -172,4 +177,4 @@ dialog {
|
|
|
172
177
|
z-index: var(--z-modal);
|
|
173
178
|
}
|
|
174
179
|
|
|
175
|
-
@import '~payload-user-css';
|
|
180
|
+
@import '~payload-user-css';
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export declare const defaults: {
|
|
2
2
|
access: {
|
|
3
3
|
create: ({ req: { user } }: {
|
|
4
|
-
req: import("../../types").PayloadRequest
|
|
4
|
+
req: import("../../types").PayloadRequest<any>;
|
|
5
5
|
}) => boolean;
|
|
6
6
|
read: ({ req: { user } }: {
|
|
7
|
-
req: import("../../types").PayloadRequest
|
|
7
|
+
req: import("../../types").PayloadRequest<any>;
|
|
8
8
|
}) => boolean;
|
|
9
9
|
update: ({ req: { user } }: {
|
|
10
|
-
req: import("../../types").PayloadRequest
|
|
10
|
+
req: import("../../types").PayloadRequest<any>;
|
|
11
11
|
}) => boolean;
|
|
12
12
|
delete: ({ req: { user } }: {
|
|
13
|
-
req: import("../../types").PayloadRequest
|
|
13
|
+
req: import("../../types").PayloadRequest<any>;
|
|
14
14
|
}) => boolean;
|
|
15
15
|
unlock: ({ req: { user } }: {
|
|
16
|
-
req: import("../../types").PayloadRequest
|
|
16
|
+
req: import("../../types").PayloadRequest<any>;
|
|
17
17
|
}) => boolean;
|
|
18
18
|
};
|
|
19
19
|
timestamps: boolean;
|
package/dist/config/types.d.ts
CHANGED
|
@@ -56,10 +56,15 @@ export declare type InitOptions = {
|
|
|
56
56
|
loggerOptions?: LoggerOptions;
|
|
57
57
|
};
|
|
58
58
|
export declare type AccessResult = boolean | Where;
|
|
59
|
+
declare type AccessArgs<T = any, U = any> = {
|
|
60
|
+
req: PayloadRequest<U>;
|
|
61
|
+
id?: string | number;
|
|
62
|
+
data?: T;
|
|
63
|
+
};
|
|
59
64
|
/**
|
|
60
65
|
* Access function
|
|
61
66
|
*/
|
|
62
|
-
export declare type Access = (args
|
|
67
|
+
export declare type Access<T = any, U = any> = (args: AccessArgs<T, U>) => AccessResult | Promise<AccessResult>;
|
|
63
68
|
export interface PayloadHandler {
|
|
64
69
|
(req: PayloadRequest, res: Response, next: NextFunction): void;
|
|
65
70
|
}
|
package/dist/express/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { Collection } from '../collections/config/types';
|
|
|
7
7
|
import { User } from '../auth/types';
|
|
8
8
|
import { Document } from '../types';
|
|
9
9
|
import { TypeWithID } from '../globals/config/types';
|
|
10
|
-
export declare type PayloadRequest = Request & {
|
|
10
|
+
export declare type PayloadRequest<T = any> = Request & {
|
|
11
11
|
payload: Payload;
|
|
12
12
|
payloadDataLoader: DataLoader<string, TypeWithID>;
|
|
13
13
|
locale?: string;
|
|
@@ -17,7 +17,7 @@ export declare type PayloadRequest = Request & {
|
|
|
17
17
|
files?: {
|
|
18
18
|
file: UploadedFile;
|
|
19
19
|
};
|
|
20
|
-
user: User | null;
|
|
20
|
+
user: T & User | null;
|
|
21
21
|
payloadUploadSizes?: Record<string, Buffer>;
|
|
22
22
|
findByID?: {
|
|
23
23
|
[slug: string]: (q: unknown) => Document;
|
|
@@ -29,8 +29,8 @@ export declare type FieldHookArgs<T extends TypeWithID = any, P = any, S = any>
|
|
|
29
29
|
previousValue?: P;
|
|
30
30
|
};
|
|
31
31
|
export declare type FieldHook<T extends TypeWithID = any, P = any, S = any> = (args: FieldHookArgs<T, P, S>) => Promise<P> | P;
|
|
32
|
-
export declare type FieldAccess<T extends TypeWithID = any, P = any> = (args: {
|
|
33
|
-
req: PayloadRequest
|
|
32
|
+
export declare type FieldAccess<T extends TypeWithID = any, P = any, U = any> = (args: {
|
|
33
|
+
req: PayloadRequest<U>;
|
|
34
34
|
id?: string | number;
|
|
35
35
|
data?: Partial<T>;
|
|
36
36
|
siblingData?: Partial<P>;
|