payload 1.1.6 → 1.1.8
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/api.js +8 -3
- package/dist/admin/components/elements/Autosave/index.js +5 -3
- package/dist/admin/components/elements/Nav/index.scss +1 -5
- package/dist/admin/components/elements/WhereBuilder/Condition/Relationship/index.js +2 -2
- 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 +59 -47
- package/dist/admin/components/forms/field-types/Relationship/index.scss +23 -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/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/Input.js +1 -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/DocumentInfo/index.js +3 -3
- 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/Verify/index.js +1 -1
- package/dist/admin/components/views/Version/Compare/index.js +1 -1
- package/dist/admin/components/views/collections/Edit/Auth/APIKey.js +2 -3
- package/dist/admin/components/views/collections/Edit/Auth/index.js +4 -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/components/views/collections/List/RelationshipProvider/index.js +1 -1
- package/dist/admin/hooks/useTitle.js +2 -3
- package/dist/admin/index.js +1 -1
- package/dist/admin/scss/app.scss +6 -1
- 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
|
@@ -26,7 +26,7 @@ const UploadInput = (props) => {
|
|
|
26
26
|
useEffect(() => {
|
|
27
27
|
if (typeof value === 'string' && value !== '') {
|
|
28
28
|
const fetchFile = async () => {
|
|
29
|
-
const response = await fetch(`${serverURL}${api}/${relationTo}/${value}
|
|
29
|
+
const response = await fetch(`${serverURL}${api}/${relationTo}/${value}`, { credentials: 'include' });
|
|
30
30
|
if (response.ok) {
|
|
31
31
|
const json = await response.json();
|
|
32
32
|
setFile(json);
|
|
@@ -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=
|
|
@@ -84,12 +84,12 @@ export const DocumentInfoProvider = ({ children, global, collection, id, }) => {
|
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
86
|
if (shouldFetch) {
|
|
87
|
-
let publishedJSON = await fetch(publishedFetchURL).then((res) => res.json());
|
|
87
|
+
let publishedJSON = await fetch(publishedFetchURL, { credentials: 'include' }).then((res) => res.json());
|
|
88
88
|
if (collection) {
|
|
89
89
|
publishedJSON = (_a = publishedJSON === null || publishedJSON === void 0 ? void 0 : publishedJSON.docs) === null || _a === void 0 ? void 0 : _a[0];
|
|
90
90
|
}
|
|
91
91
|
if (shouldFetchVersions) {
|
|
92
|
-
versionJSON = await fetch(`${versionFetchURL}?${qs.stringify(versionParams)}
|
|
92
|
+
versionJSON = await fetch(`${versionFetchURL}?${qs.stringify(versionParams)}`, { credentials: 'include' }).then((res) => res.json());
|
|
93
93
|
if (publishedJSON === null || publishedJSON === void 0 ? void 0 : publishedJSON.updatedAt) {
|
|
94
94
|
const newerVersionParams = {
|
|
95
95
|
...versionParams,
|
|
@@ -106,7 +106,7 @@ export const DocumentInfoProvider = ({ children, global, collection, id, }) => {
|
|
|
106
106
|
},
|
|
107
107
|
};
|
|
108
108
|
// Get any newer versions available
|
|
109
|
-
const newerVersionRes = await fetch(`${versionFetchURL}?${qs.stringify(newerVersionParams)}
|
|
109
|
+
const newerVersionRes = await fetch(`${versionFetchURL}?${qs.stringify(newerVersionParams)}`, { credentials: 'include' });
|
|
110
110
|
if (newerVersionRes.status === 200) {
|
|
111
111
|
unpublishedVersionJSON = await newerVersionRes.json();
|
|
112
112
|
}
|
|
@@ -18,7 +18,7 @@ const Verify = ({ collection }) => {
|
|
|
18
18
|
const [verifyResult, setVerifyResult] = useState(null);
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
async function verifyToken() {
|
|
21
|
-
const result = await fetch(`${serverURL}/api/${collectionSlug}/verify/${token}`, { method: 'POST' });
|
|
21
|
+
const result = await fetch(`${serverURL}/api/${collectionSlug}/verify/${token}`, { method: 'POST', credentials: 'include' });
|
|
22
22
|
setVerifyResult(result);
|
|
23
23
|
}
|
|
24
24
|
verifyToken();
|
|
@@ -39,7 +39,7 @@ const CompareVersion = (props) => {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
const search = qs.stringify(query);
|
|
42
|
-
const response = await fetch(`${baseURL}?${search}
|
|
42
|
+
const response = await fetch(`${baseURL}?${search}`, { credentials: 'include' });
|
|
43
43
|
if (response.ok) {
|
|
44
44
|
const data = await response.json();
|
|
45
45
|
if (data.docs.length > 0) {
|
|
@@ -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) {
|
|
@@ -27,6 +27,7 @@ const Auth = (props) => {
|
|
|
27
27
|
const unlock = useCallback(async () => {
|
|
28
28
|
const url = `${serverURL}${api}/${slug}/unlock`;
|
|
29
29
|
const response = await fetch(url, {
|
|
30
|
+
credentials: 'include',
|
|
30
31
|
headers: {
|
|
31
32
|
'Content-Type': 'application/json',
|
|
32
33
|
},
|
|
@@ -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
|
};
|
|
@@ -25,7 +25,7 @@ export const RelationshipProvider = ({ children }) => {
|
|
|
25
25
|
limit: 250,
|
|
26
26
|
};
|
|
27
27
|
const query = querystring.stringify(params, { addQueryPrefix: true });
|
|
28
|
-
const result = await fetch(`${url}${query}
|
|
28
|
+
const result = await fetch(`${url}${query}`, { credentials: 'include' });
|
|
29
29
|
if (result.ok) {
|
|
30
30
|
const json = await result.json();
|
|
31
31
|
if (json.docs) {
|
|
@@ -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';
|