feat: improve field ops (#3172)

Co-authored-by: PatrikKozak <patrik@trbl.design>
This commit is contained in:
James Mikrut
2023-08-16 11:00:52 -04:00
committed by GitHub
parent e03a8e6b03
commit d91b44cbb3
4 changed files with 57 additions and 28 deletions

View File

@@ -3,10 +3,8 @@ import merge from 'deepmerge';
import { Field, fieldAffectsData, TabAsField, tabHasName } from '../../config/types';
import { Operation } from '../../../types';
import { PayloadRequest, RequestContext } from '../../../express/types';
import getValueWithDefault from '../../getDefaultValue';
import { traverseFields } from './traverseFields';
import { getExistingRowDoc } from './getExistingRowDoc';
import { cloneDataFromOriginalDoc } from './cloneDataFromOriginalDoc';
type Args = {
data: Record<string, unknown>
@@ -28,8 +26,6 @@ type Args = {
// This function is responsible for the following actions, in order:
// - Run condition
// - Merge original document data into incoming data
// - Compute default values for undefined fields
// - Execute field hooks
// - Validate data
// - Transform data for storage
@@ -59,26 +55,6 @@ export const promise = async ({
const operationLocale = req.locale || defaultLocale;
if (fieldAffectsData(field)) {
if (typeof siblingData[field.name] === 'undefined') {
// If no incoming data, but existing document data is found, merge it in
if (typeof siblingDoc[field.name] !== 'undefined') {
if (field.localized && typeof siblingDocWithLocales[field.name] === 'object' && siblingDocWithLocales[field.name] !== null) {
siblingData[field.name] = cloneDataFromOriginalDoc(siblingDocWithLocales[field.name][req.locale]);
} else {
siblingData[field.name] = cloneDataFromOriginalDoc(siblingDoc[field.name]);
}
// Otherwise compute default value
} else if (typeof field.defaultValue !== 'undefined') {
siblingData[field.name] = await getValueWithDefault({
value: siblingData[field.name],
defaultValue: field.defaultValue,
locale: req.locale,
user: req.user,
});
}
}
// skip validation if the field is localized and the incoming data is null
if (field.localized && operationLocale !== defaultLocale) {
if (['array', 'blocks'].includes(field.type) && siblingData[field.name] === null) {

View File

@@ -1,6 +1,9 @@
/* eslint-disable no-param-reassign */
import { PayloadRequest, RequestContext } from '../../../express/types';
import { Field, fieldAffectsData, TabAsField, tabHasName, valueIsValueWithRelation } from '../../config/types';
import getValueWithDefault from '../../getDefaultValue';
import { cloneDataFromOriginalDoc } from '../beforeChange/cloneDataFromOriginalDoc';
import { getExistingRowDoc } from '../beforeChange/getExistingRowDoc';
import { traverseFields } from './traverseFields';
type Args<T> = {
@@ -20,6 +23,8 @@ type Args<T> = {
// - Sanitize incoming data
// - Execute field hooks
// - Execute field access control
// - Merge original document data into incoming data
// - Compute default values for undefined fields
export const promise = async <T>({
data,
@@ -189,6 +194,22 @@ export const promise = async <T>({
delete siblingData[field.name];
}
}
if (typeof siblingData[field.name] === 'undefined') {
// If no incoming data, but existing document data is found, merge it in
if (typeof siblingDoc[field.name] !== 'undefined') {
siblingData[field.name] = cloneDataFromOriginalDoc(siblingDoc[field.name]);
// Otherwise compute default value
} else if (typeof field.defaultValue !== 'undefined') {
siblingData[field.name] = await getValueWithDefault({
value: siblingData[field.name],
defaultValue: field.defaultValue,
locale: req.locale,
user: req.user,
});
}
}
}
// Traverse subfields
@@ -231,7 +252,7 @@ export const promise = async <T>({
overrideAccess,
req,
siblingData: row,
siblingDoc: siblingDoc[field.name]?.[i] || {},
siblingDoc: getExistingRowDoc(row, siblingDoc[field.name]),
context,
}));
});
@@ -258,7 +279,7 @@ export const promise = async <T>({
overrideAccess,
req,
siblingData: row,
siblingDoc: siblingDoc[field.name]?.[i] || {},
siblingDoc: getExistingRowDoc(row, siblingDoc[field.name]),
context,
}));
}
@@ -291,8 +312,11 @@ export const promise = async <T>({
let tabSiblingData;
let tabSiblingDoc;
if (tabHasName(field)) {
tabSiblingData = typeof siblingData[field.name] === 'object' ? siblingData[field.name] : {};
tabSiblingDoc = typeof siblingDoc[field.name] === 'object' ? siblingDoc[field.name] : {};
if (typeof siblingData[field.name] !== 'object') siblingData[field.name] = {};
if (typeof siblingDoc[field.name] !== 'object') siblingDoc[field.name] = {};
tabSiblingData = siblingData[field.name] as Record<string, unknown>;
tabSiblingDoc = siblingDoc[field.name] as Record<string, unknown>;
} else {
tabSiblingData = siblingData;
tabSiblingDoc = siblingDoc;