Merge pull request #308 from payloadcms/feat/field-type-point
Feat/field type point
This commit is contained in:
@@ -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');
|
||||
|
||||
|
||||
@@ -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 & {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user