chore: further refinements
This commit is contained in:
@@ -61,7 +61,7 @@ Field Hooks receive one `args` argument that contains the following properties:
|
||||
| **`data`** | The data passed to update the document within `create` and `update` operations, and the full document itself in the `afterRead` hook. |
|
||||
| **`findMany`** | Boolean to denote if this hook is running against finding one, or finding many within the `afterRead` hook. |
|
||||
| **`operation`** | A string relating to which operation the field type is currently executing within. Useful within `beforeValidate`, `beforeChange`, and `afterChange` hooks to differentiate between `create` and `update` operations. |
|
||||
| **`originalDoc`** | The full original document in `update` operations. |
|
||||
| **`originalDoc`** | The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. |
|
||||
| **`req`** | The Express `request` object. It is mocked for Local API operations. |
|
||||
| **`siblingData`** | The sibling data passed to a field that the hook is running against. |
|
||||
| **`value`** | The value of the field. |
|
||||
|
||||
@@ -10,12 +10,19 @@ import { User } from '../../auth';
|
||||
import { Payload } from '../..';
|
||||
|
||||
export type FieldHookArgs<T extends TypeWithID = any, P = any, S = any> = {
|
||||
/** The data passed to update the document within create and update operations, and the full document itself in the afterRead hook. */
|
||||
data?: Partial<T>,
|
||||
/** Boolean to denote if this hook is running against finding one, or finding many within the afterRead hook. */
|
||||
findMany?: boolean
|
||||
/** The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. */
|
||||
originalDoc?: T,
|
||||
/** A string relating to which operation the field type is currently executing within. Useful within beforeValidate, beforeChange, and afterChange hooks to differentiate between create and update operations. */
|
||||
operation?: 'create' | 'read' | 'update' | 'delete',
|
||||
/** The Express request object. It is mocked for Local API operations. */
|
||||
req: PayloadRequest
|
||||
/** The sibling data passed to a field that the hook is running against. */
|
||||
siblingData: Partial<S>
|
||||
/** The value of the field. */
|
||||
value?: P,
|
||||
}
|
||||
|
||||
@@ -203,6 +210,7 @@ export type TabsField = Omit<FieldBase, 'admin' | 'name' | 'localized'> & {
|
||||
|
||||
export type TabAsField = Tab & {
|
||||
type: 'tab'
|
||||
name?: string
|
||||
};
|
||||
|
||||
export type UIField = {
|
||||
@@ -389,6 +397,7 @@ export type FieldAffectingData =
|
||||
| UploadField
|
||||
| CodeField
|
||||
| PointField
|
||||
| TabAsField
|
||||
|
||||
export type NonPresentationalField =
|
||||
TextField
|
||||
|
||||
@@ -126,14 +126,12 @@ export const promise = async ({
|
||||
}
|
||||
|
||||
case 'tab': {
|
||||
let tabSiblingData;
|
||||
let tabSiblingDoc;
|
||||
let tabSiblingData = siblingData;
|
||||
let tabSiblingDoc = siblingDoc;
|
||||
|
||||
if (tabHasName(field)) {
|
||||
tabSiblingData = siblingData[field.name] || {};
|
||||
tabSiblingDoc = siblingDoc[field.name];
|
||||
} else {
|
||||
tabSiblingData = siblingData || {};
|
||||
tabSiblingDoc = { ...siblingDoc };
|
||||
tabSiblingData = siblingData[field.name] as Record<string, unknown>;
|
||||
tabSiblingDoc = siblingDoc[field.name] as Record<string, unknown>;
|
||||
}
|
||||
|
||||
await traverseFields({
|
||||
|
||||
@@ -49,14 +49,13 @@ export const promise = async ({
|
||||
const hasLocalizedValue = flattenLocales
|
||||
&& fieldAffectsData(field)
|
||||
&& (typeof siblingDoc[field.name] === 'object' && siblingDoc[field.name] !== null)
|
||||
&& field.name
|
||||
&& field.localized
|
||||
&& req.locale !== 'all';
|
||||
|
||||
if (hasLocalizedValue) {
|
||||
let localizedValue = siblingDoc[field.name][req.locale];
|
||||
if (typeof localizedValue === 'undefined' && req.fallbackLocale) localizedValue = siblingDoc[field.name][req.fallbackLocale];
|
||||
if (typeof localizedValue === 'undefined' && field.type === 'group') localizedValue = {};
|
||||
if (typeof localizedValue === 'undefined' && (field.type === 'group' || field.type === 'tab')) localizedValue = {};
|
||||
if (typeof localizedValue === 'undefined') localizedValue = null;
|
||||
siblingDoc[field.name] = localizedValue;
|
||||
}
|
||||
|
||||
@@ -286,11 +286,16 @@ export const promise = async ({
|
||||
let tabSiblingData = siblingData;
|
||||
let tabSiblingDoc = siblingDoc;
|
||||
let tabSiblingDocWithLocales = siblingDocWithLocales;
|
||||
|
||||
if (tabHasName(field)) {
|
||||
tabPath = `${path}${field.name}.`;
|
||||
tabSiblingData = typeof siblingData[field.name] === 'object' ? siblingData[field.name] as Record<string, unknown> : {};
|
||||
tabSiblingDoc = typeof siblingDoc[field.name] === 'object' ? siblingDoc[field.name] as Record<string, unknown> : {};
|
||||
tabSiblingDocWithLocales = typeof siblingDocWithLocales[field.name] === 'object' ? siblingDocWithLocales[field.name] as Record<string, unknown> : {};
|
||||
if (typeof siblingData[field.name] !== 'object') siblingData[field.name] = {};
|
||||
if (typeof siblingDoc[field.name] !== 'object') siblingDoc[field.name] = {};
|
||||
if (typeof siblingDocWithLocales[field.name] !== 'object') siblingDocWithLocales[field.name] = {};
|
||||
|
||||
tabSiblingData = siblingData[field.name] as Record<string, unknown>;
|
||||
tabSiblingDoc = siblingDoc[field.name] as Record<string, unknown>;
|
||||
tabSiblingDocWithLocales = siblingDocWithLocales[field.name] as Record<string, unknown>;
|
||||
}
|
||||
|
||||
await traverseFields({
|
||||
|
||||
@@ -5,33 +5,52 @@
|
||||
* and re-run `payload generate:types` to regenerate this file.
|
||||
*/
|
||||
|
||||
export interface Config { }
|
||||
export interface Config {}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-global".
|
||||
* via the `definition` "posts".
|
||||
*/
|
||||
export interface AutosaveGlobal {
|
||||
export interface Post {
|
||||
id: string;
|
||||
_status?: 'draft' | 'published';
|
||||
title: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "autosave-posts".
|
||||
*/
|
||||
export interface AutosavePost {
|
||||
id: string;
|
||||
_status?: 'draft' | 'published';
|
||||
title: string;
|
||||
description: string;
|
||||
restrictedField?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "draft-posts".
|
||||
* via the `definition` "restricted".
|
||||
*/
|
||||
export interface DraftPost {
|
||||
export interface Restricted {
|
||||
id: string;
|
||||
name?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "read-only-collection".
|
||||
*/
|
||||
export interface ReadOnlyCollection {
|
||||
id: string;
|
||||
name?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "restricted-versions".
|
||||
*/
|
||||
export interface RestrictedVersion {
|
||||
id: string;
|
||||
name?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "sibling-data".
|
||||
*/
|
||||
export interface SiblingDatum {
|
||||
id: string;
|
||||
array: {
|
||||
allowPublicReadability?: boolean;
|
||||
|
||||
@@ -190,10 +190,9 @@ const TabsFields: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
afterChange: [
|
||||
({ data = {} }) => {
|
||||
if (!data.hooksTab) data.hooksTab = {};
|
||||
data.hooksTab.afterChange = true;
|
||||
return data.hooksTab;
|
||||
({ originalDoc }) => {
|
||||
originalDoc.hooksTab.afterChange = true;
|
||||
return originalDoc.hooksTab;
|
||||
},
|
||||
],
|
||||
afterRead: [
|
||||
|
||||
@@ -357,14 +357,14 @@ describe('Fields', () => {
|
||||
});
|
||||
|
||||
it('should allow hooks on a named tab', async () => {
|
||||
document = await payload.findByID({
|
||||
const newDocument = await payload.create<TabsField>({
|
||||
collection: tabsSlug,
|
||||
id: document.id,
|
||||
data: tabsDoc,
|
||||
});
|
||||
expect(document.hooksTab.beforeValidate).toBe(true);
|
||||
expect(document.hooksTab.beforeChange).toBe(true);
|
||||
expect(document.hooksTab.afterChange).toBe(true);
|
||||
expect(document.hooksTab.afterRead).toBe(true);
|
||||
expect(newDocument.hooksTab.beforeValidate).toBe(true);
|
||||
expect(newDocument.hooksTab.beforeChange).toBe(true);
|
||||
expect(newDocument.hooksTab.afterChange).toBe(true);
|
||||
expect(newDocument.hooksTab.afterRead).toBe(true);
|
||||
});
|
||||
|
||||
it('should return empty object for groups when no data present', async () => {
|
||||
|
||||
@@ -72,6 +72,13 @@ export interface BlockField {
|
||||
blockName?: string;
|
||||
blockType: 'subBlocks';
|
||||
}
|
||||
| {
|
||||
textInCollapsible?: string;
|
||||
textInRow?: string;
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'tabs';
|
||||
}
|
||||
)[];
|
||||
localizedBlocks: (
|
||||
| {
|
||||
@@ -108,6 +115,13 @@ export interface BlockField {
|
||||
blockName?: string;
|
||||
blockType: 'subBlocks';
|
||||
}
|
||||
| {
|
||||
textInCollapsible?: string;
|
||||
textInRow?: string;
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'tabs';
|
||||
}
|
||||
)[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
@@ -273,12 +287,25 @@ export interface TabsField {
|
||||
blockName?: string;
|
||||
blockType: 'subBlocks';
|
||||
}
|
||||
| {
|
||||
textInCollapsible?: string;
|
||||
textInRow?: string;
|
||||
id?: string;
|
||||
blockName?: string;
|
||||
blockType: 'tabs';
|
||||
}
|
||||
)[];
|
||||
group: {
|
||||
number: number;
|
||||
};
|
||||
textInRow: string;
|
||||
numberInRow: number;
|
||||
text?: string;
|
||||
defaultValue?: string;
|
||||
beforeValidate?: boolean;
|
||||
beforeChange?: boolean;
|
||||
afterChange?: boolean;
|
||||
afterRead?: boolean;
|
||||
textarea?: string;
|
||||
anotherText: string;
|
||||
createdAt: string;
|
||||
@@ -325,6 +352,8 @@ export interface Upload {
|
||||
filename?: string;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ export interface UnstoredMedia {
|
||||
filename?: string;
|
||||
mimeType?: string;
|
||||
filesize?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user