Merge pull request #308 from payloadcms/feat/field-type-point

Feat/field type point
This commit is contained in:
James Mikrut
2021-08-31 13:32:18 -04:00
committed by GitHub
30 changed files with 716 additions and 50 deletions

View File

@@ -185,6 +185,12 @@ export const checkbox = baseField.keys({
defaultValue: joi.boolean(),
});
export const point = baseField.keys({
type: joi.string().valid('point').required(),
name: joi.string().required(),
defaultValue: joi.array().items(joi.number()).max(2).min(2),
});
export const relationship = baseField.keys({
type: joi.string().valid('relationship').required(),
hasMany: joi.boolean().default(false),
@@ -290,6 +296,7 @@ const fieldSchema = joi.alternatives()
richText,
blocks,
date,
point,
)
.id('field');

View File

@@ -243,6 +243,10 @@ export type BlockField = FieldBase & {
labels?: Labels
}
export type PointField = FieldBase & {
type: 'point',
}
export type Field =
TextField
| NumberField
@@ -259,6 +263,7 @@ export type Field =
| SelectField
| UploadField
| CodeField
| PointField
| RowField;
export type FieldWithPath = Field & {

View File

@@ -66,6 +66,7 @@ export default async function performFieldOperations(this: Payload, entityConfig
const relationshipPopulations = [];
const hookPromises = [];
const unflattenLocaleActions = [];
const transformActions = [];
const errors: { message: string, field: string }[] = [];
// //////////////////////////////////////////
@@ -98,26 +99,35 @@ export default async function performFieldOperations(this: Payload, entityConfig
showHiddenFields,
unflattenLocales,
unflattenLocaleActions,
transformActions,
docWithLocales,
});
await Promise.all(hookPromises);
if (hook === 'afterRead') {
transformActions.forEach((action) => action());
}
const hookResults = hookPromises.map((promise) => promise());
await Promise.all(hookResults);
validationPromises.forEach((promise) => promise());
await Promise.all(validationPromises);
if (errors.length > 0) {
throw new ValidationError(errors);
}
if (hook === 'beforeChange') {
transformActions.forEach((action) => action());
}
unflattenLocaleActions.forEach((action) => action());
await Promise.all(accessPromises);
const accessResults = accessPromises.map((promise) => promise());
await Promise.all(accessResults);
const relationshipPopulationPromises = relationshipPopulations.map((population) => population());
await Promise.all(relationshipPopulationPromises);
const relationshipPopulationResults = relationshipPopulations.map((population) => population());
await Promise.all(relationshipPopulationResults);
return fullData;
}

View File

@@ -15,7 +15,7 @@ type Arguments = {
flattenLocales: boolean
locale: string
fallbackLocale: string
accessPromises: Promise<void>[]
accessPromises: (() => Promise<void>)[]
operation: Operation
overrideAccess: boolean
req: PayloadRequest
@@ -24,7 +24,7 @@ type Arguments = {
depth: number
currentDepth: number
hook: HookName
hookPromises: Promise<void>[]
hookPromises: (() => Promise<void>)[]
fullOriginalDoc: Record<string, any>
fullData: Record<string, any>
validationPromises: (() => Promise<string | boolean>)[]
@@ -33,6 +33,7 @@ type Arguments = {
showHiddenFields: boolean
unflattenLocales: boolean
unflattenLocaleActions: (() => void)[]
transformActions: (() => void)[]
docWithLocales?: Record<string, any>
skipValidation?: boolean
}
@@ -64,6 +65,7 @@ const traverseFields = (args: Arguments): void => {
showHiddenFields,
unflattenLocaleActions,
unflattenLocales,
transformActions,
docWithLocales = {},
skipValidation,
} = args;
@@ -75,6 +77,14 @@ const traverseFields = (args: Arguments): void => {
delete data[field.name];
}
if (hook === 'afterRead' && field.type === 'point') {
transformActions.push(() => {
if (data[field.name]?.coordinates && Array.isArray(data[field.name].coordinates) && data[field.name].coordinates.length === 2) {
data[field.name] = data[field.name].coordinates;
}
});
}
if ((field.type === 'upload' || field.type === 'relationship')
&& (data[field.name] === '' || data[field.name] === 'none' || data[field.name] === 'null')) {
dataCopy[field.name] = null;
@@ -163,7 +173,7 @@ const traverseFields = (args: Arguments): void => {
});
}
accessPromises.push(accessPromise({
accessPromises.push(() => accessPromise({
data,
fullData,
originalDoc,
@@ -179,7 +189,7 @@ const traverseFields = (args: Arguments): void => {
payload,
}));
hookPromises.push(hookPromise({
hookPromises.push(() => hookPromise({
data,
field,
hook,
@@ -257,6 +267,20 @@ const traverseFields = (args: Arguments): void => {
updatedData[field.name] = field.defaultValue;
}
if (field.type === 'point' && data[field.name]) {
transformActions.push(() => {
if (Array.isArray(data[field.name]) && data[field.name][0] !== null && data[field.name][1] !== null) {
data[field.name] = {
type: 'Point',
coordinates: [
parseFloat(data[field.name][0]),
parseFloat(data[field.name][1]),
],
};
}
});
}
if (field.type === 'array' || field.type === 'blocks') {
const hasRowsOfNewData = Array.isArray(data[field.name]);
const newRowCount = hasRowsOfNewData ? (data[field.name] as Record<string, unknown>[]).length : 0;

View File

@@ -199,6 +199,24 @@ export const blocks: Validate = (value, options = {}) => {
return true;
};
export const point: Validate = (value: [number | string, number | string] = ['', ''], options = {}) => {
const x = parseFloat(String(value[0]));
const y = parseFloat(String(value[1]));
if (
(value[0] && value[1] && typeof x !== 'number' && typeof y !== 'number')
|| (options.required && (Number.isNaN(x) || Number.isNaN(y)))
|| (Array.isArray(value) && value.length !== 2)
) {
return 'This field requires two numbers';
}
if (!options.required && typeof value[0] !== typeof value[1]) {
return 'This field requires two numbers or both can be empty';
}
return true;
};
export default {
number,
text,
@@ -216,4 +234,5 @@ export default {
select,
radio,
blocks,
point,
};