@whatworks/payload-select-search-field 1.0.0 → 1.0.2
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/README.md +10 -6
- package/dist/endpoint.js +111 -0
- package/dist/endpoint.js.map +1 -0
- package/dist/endpointName.js +3 -0
- package/dist/endpointName.js.map +1 -0
- package/dist/exports/client.js +3 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.js +12 -0
- package/dist/plugin.js.map +1 -0
- package/dist/{src/selectSearchField.d.ts → selectSearchField.d.ts} +6 -5
- package/dist/selectSearchField.js +20 -0
- package/dist/selectSearchField.js.map +1 -0
- package/dist/{src/types.d.ts → types.d.ts} +12 -8
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/SelectSearchField.js +154 -0
- package/dist/ui/SelectSearchField.js.map +1 -0
- package/package.json +27 -12
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/{src/endpoint.d.ts → endpoint.d.ts} +0 -0
- package/dist/{src/endpointName.d.ts → endpointName.d.ts} +0 -0
- package/dist/{src/exports → exports}/client.d.ts +0 -0
- package/dist/{src/index.d.ts → index.d.ts} +2 -2
- /package/dist/{src/plugin.d.ts → plugin.d.ts} +0 -0
- /package/dist/{src/ui → ui}/SelectSearchField.d.ts +0 -0
package/README.md
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
Server-backed search select field and plugin for Payload. The client component queries a shared endpoint
|
|
4
4
|
and passes the current search query plus any currently selected values.
|
|
5
5
|
|
|
6
|
+
## Demo
|
|
7
|
+
|
|
8
|
+
https://github.com/user-attachments/assets/0f49d3f9-8473-4d77-8e20-ee07a1276a8e
|
|
9
|
+
|
|
10
|
+
|
|
6
11
|
## Usage
|
|
7
12
|
|
|
8
13
|
Add the plugin:
|
|
@@ -15,7 +20,7 @@ export default buildConfig({
|
|
|
15
20
|
})
|
|
16
21
|
```
|
|
17
22
|
|
|
18
|
-
Add a field with `selectSearch` (recommended):
|
|
23
|
+
Add a field with `selectSearch` (recommended):
|
|
19
24
|
|
|
20
25
|
```ts
|
|
21
26
|
import { selectSearch } from '@whatworks/payload-select-search-field'
|
|
@@ -23,6 +28,8 @@ import { selectSearch } from '@whatworks/payload-select-search-field'
|
|
|
23
28
|
selectSearch({
|
|
24
29
|
name: 'stripeCustomer',
|
|
25
30
|
hasMany: true,
|
|
31
|
+
passDataToSearchFunction: true,
|
|
32
|
+
passSiblingDataToSearchFunction: true,
|
|
26
33
|
searchFunction: async ({ query, selectedValues }) => {
|
|
27
34
|
return [
|
|
28
35
|
{ value: 'cus_123', label: `Result for ${query}` },
|
|
@@ -32,17 +39,14 @@ selectSearch({
|
|
|
32
39
|
})),
|
|
33
40
|
]
|
|
34
41
|
},
|
|
35
|
-
admin: {
|
|
36
|
-
components: {
|
|
37
|
-
Field: '@whatworks/payload-select-search-field/client#SelectSearchField',
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
42
|
})
|
|
41
43
|
```
|
|
42
44
|
|
|
43
45
|
`searchFunction` receives:
|
|
44
46
|
- `query`: the current input text.
|
|
45
47
|
- `selectedValues`: an array of currently selected values (empty array when nothing is selected).
|
|
48
|
+
- `siblingData`: sibling field values for the current field path when `passSiblingDataToSearchFunction: true`.
|
|
49
|
+
- `data`: full form data when `passDataToSearchFunction: true`.
|
|
46
50
|
- `req`, `field`, and `collection`/`global` context.
|
|
47
51
|
|
|
48
52
|
The client component calls the shared endpoint path from `selectSearchEndpoint`.
|
package/dist/endpoint.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { getFieldByPath } from 'payload';
|
|
2
|
+
import { selectSearchEndpoint } from './endpointName.js';
|
|
3
|
+
const maxQueryLength = 200;
|
|
4
|
+
const parseBody = async (req)=>{
|
|
5
|
+
if (typeof req.json === 'function') {
|
|
6
|
+
return await req.json();
|
|
7
|
+
}
|
|
8
|
+
if (req.body && typeof req.body === 'object') {
|
|
9
|
+
return req.body;
|
|
10
|
+
}
|
|
11
|
+
return {};
|
|
12
|
+
};
|
|
13
|
+
export const selectSearchEndpointHandler = ()=>({
|
|
14
|
+
method: 'post',
|
|
15
|
+
path: selectSearchEndpoint,
|
|
16
|
+
handler: async (req)=>{
|
|
17
|
+
if (!req.user) {
|
|
18
|
+
return Response.json({
|
|
19
|
+
error: 'Unauthorized'
|
|
20
|
+
}, {
|
|
21
|
+
status: 401
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
let body;
|
|
25
|
+
try {
|
|
26
|
+
body = await parseBody(req);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return Response.json({
|
|
29
|
+
error: 'Invalid JSON body'
|
|
30
|
+
}, {
|
|
31
|
+
status: 400
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const { entityType, slug, schemaPath } = body;
|
|
35
|
+
if (entityType !== 'collection' && entityType !== 'global') {
|
|
36
|
+
return Response.json({
|
|
37
|
+
error: 'Invalid entityType'
|
|
38
|
+
}, {
|
|
39
|
+
status: 400
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (!slug || !schemaPath) {
|
|
43
|
+
return Response.json({
|
|
44
|
+
error: 'Missing slug or schemaPath'
|
|
45
|
+
}, {
|
|
46
|
+
status: 400
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const safeQuery = String(body.query || '').slice(0, maxQueryLength);
|
|
50
|
+
const selectedValues = Array.isArray(body.selectedValues) ? body.selectedValues.map((value)=>String(value)) : [];
|
|
51
|
+
const config = req.payload.config;
|
|
52
|
+
const entityConfig = entityType === 'collection' ? config.collections?.find((collection)=>collection.slug === slug) : config.globals?.find((global)=>global.slug === slug);
|
|
53
|
+
if (!entityConfig) {
|
|
54
|
+
return Response.json({
|
|
55
|
+
error: 'Unknown entity'
|
|
56
|
+
}, {
|
|
57
|
+
status: 404
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const fields = entityConfig.flattenedFields;
|
|
61
|
+
if (!Array.isArray(fields)) {
|
|
62
|
+
return Response.json({
|
|
63
|
+
error: 'Fields not searchable'
|
|
64
|
+
}, {
|
|
65
|
+
status: 400
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const fieldResult = getFieldByPath({
|
|
69
|
+
fields,
|
|
70
|
+
path: schemaPath.split('.').slice(1).join('.')
|
|
71
|
+
});
|
|
72
|
+
if (!fieldResult) {
|
|
73
|
+
return Response.json({
|
|
74
|
+
error: 'Field not found'
|
|
75
|
+
}, {
|
|
76
|
+
status: 400
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const searchFunction = fieldResult?.field?.custom?.searchFunction;
|
|
80
|
+
if (typeof searchFunction !== 'function') {
|
|
81
|
+
return Response.json({
|
|
82
|
+
error: 'Field not searchable'
|
|
83
|
+
}, {
|
|
84
|
+
status: 400
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const collectionConfig = entityType === 'collection' ? entityConfig : undefined;
|
|
88
|
+
const globalConfig = entityType === 'global' ? entityConfig : undefined;
|
|
89
|
+
const options = await searchFunction({
|
|
90
|
+
req,
|
|
91
|
+
query: safeQuery,
|
|
92
|
+
selectedValues,
|
|
93
|
+
field: fieldResult.field,
|
|
94
|
+
collection: collectionConfig,
|
|
95
|
+
global: globalConfig
|
|
96
|
+
});
|
|
97
|
+
if (!Array.isArray(options)) {
|
|
98
|
+
return Response.json({
|
|
99
|
+
error: 'Invalid searchFunction response'
|
|
100
|
+
}, {
|
|
101
|
+
status: 500
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const res = {
|
|
105
|
+
options
|
|
106
|
+
};
|
|
107
|
+
return Response.json(res);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/endpoint.ts"],"sourcesContent":["import type {\n Endpoint,\n PayloadRequest,\n SanitizedCollectionConfig,\n SanitizedGlobalConfig,\n} from 'payload'\nimport { getFieldByPath } from 'payload'\nimport type { SelectSearchRequest, SelectSearchResponse, SelectSearchFunction } from './types.js'\nimport { selectSearchEndpoint } from './endpointName.js'\n\nconst maxQueryLength = 200\n\nconst parseBody = async (req: PayloadRequest): Promise<Partial<SelectSearchRequest>> => {\n if (typeof req.json === 'function') {\n return (await req.json()) as Partial<SelectSearchRequest>\n }\n\n if (req.body && typeof req.body === 'object') {\n return req.body as Partial<SelectSearchRequest>\n }\n\n return {}\n}\n\nexport const selectSearchEndpointHandler = (): Endpoint => ({\n method: 'post',\n path: selectSearchEndpoint,\n handler: async (req: PayloadRequest) => {\n if (!req.user) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n let body: Partial<SelectSearchRequest>\n try {\n body = await parseBody(req)\n } catch (error) {\n return Response.json({ error: 'Invalid JSON body' }, { status: 400 })\n }\n\n const { entityType, slug, schemaPath } = body\n if (entityType !== 'collection' && entityType !== 'global') {\n return Response.json({ error: 'Invalid entityType' }, { status: 400 })\n }\n\n if (!slug || !schemaPath) {\n return Response.json({ error: 'Missing slug or schemaPath' }, { status: 400 })\n }\n\n const safeQuery = String(body.query || '').slice(0, maxQueryLength)\n const selectedValues = Array.isArray(body.selectedValues)\n ? body.selectedValues.map((value) => String(value))\n : []\n\n const config = req.payload.config\n const entityConfig =\n entityType === 'collection'\n ? config.collections?.find((collection) => collection.slug === slug)\n : config.globals?.find((global) => global.slug === slug)\n\n if (!entityConfig) {\n return Response.json({ error: 'Unknown entity' }, { status: 404 })\n }\n\n const fields = entityConfig.flattenedFields\n if (!Array.isArray(fields)) {\n return Response.json({ error: 'Fields not searchable' }, { status: 400 })\n }\n\n const fieldResult = getFieldByPath({\n fields,\n path: schemaPath.split('.').slice(1).join('.'),\n })\n\n if (!fieldResult) {\n return Response.json({ error: 'Field not found' }, { status: 400 })\n }\n\n const searchFunction = fieldResult?.field?.custom?.searchFunction as\n | SelectSearchFunction\n | undefined\n\n if (typeof searchFunction !== 'function') {\n return Response.json({ error: 'Field not searchable' }, { status: 400 })\n }\n\n const collectionConfig =\n entityType === 'collection' ? (entityConfig as SanitizedCollectionConfig) : undefined\n const globalConfig =\n entityType === 'global' ? (entityConfig as SanitizedGlobalConfig) : undefined\n\n const options = await searchFunction({\n req,\n query: safeQuery,\n selectedValues,\n field: fieldResult.field,\n collection: collectionConfig,\n global: globalConfig,\n })\n\n if (!Array.isArray(options)) {\n return Response.json({ error: 'Invalid searchFunction response' }, { status: 500 })\n }\n\n const res: SelectSearchResponse = {\n options,\n }\n\n return Response.json(res)\n },\n})\n"],"names":["getFieldByPath","selectSearchEndpoint","maxQueryLength","parseBody","req","json","body","selectSearchEndpointHandler","method","path","handler","user","Response","error","status","entityType","slug","schemaPath","safeQuery","String","query","slice","selectedValues","Array","isArray","map","value","config","payload","entityConfig","collections","find","collection","globals","global","fields","flattenedFields","fieldResult","split","join","searchFunction","field","custom","collectionConfig","undefined","globalConfig","options","res"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/endpointName.ts"],"sourcesContent":["export const selectSearchEndpoint = '/select-search'\n"],"names":["selectSearchEndpoint"],"mappings":"AAAA,OAAO,MAAMA,uBAAuB,iBAAgB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { SelectSearchField } from '../ui/SelectSearchField.js'\n"],"names":["SelectSearchField"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,6BAA4B"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { selectSearchPlugin as selectSearchPlugin } from './plugin.js';
|
|
2
|
+
export { selectSearchEndpoint } from './endpointName.js';
|
|
3
|
+
export { selectSearchEndpointHandler } from './endpoint.js';
|
|
4
|
+
export { selectSearchField } from './selectSearchField.js';
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { selectSearchPlugin as selectSearchPlugin } from './plugin.js'\nexport { selectSearchEndpoint } from './endpointName.js'\nexport { selectSearchEndpointHandler } from './endpoint.js'\nexport { selectSearchField } from './selectSearchField.js'\nexport type {\n SelectSearchFunction,\n SelectSearchFunctionArgs,\n SelectSearchOption,\n SelectSearchRequest,\n SelectSearchResponse,\n} from './types.js'\n"],"names":["selectSearchPlugin","selectSearchEndpoint","selectSearchEndpointHandler","selectSearchField"],"mappings":"AAAA,SAASA,sBAAsBA,kBAAkB,QAAQ,cAAa;AACtE,SAASC,oBAAoB,QAAQ,oBAAmB;AACxD,SAASC,2BAA2B,QAAQ,gBAAe;AAC3D,SAASC,iBAAiB,QAAQ,yBAAwB"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { selectSearchEndpointHandler } from './endpoint.js';
|
|
2
|
+
export const selectSearchPlugin = ()=>{
|
|
3
|
+
return async (config)=>{
|
|
4
|
+
config.endpoints = [
|
|
5
|
+
...config.endpoints || [],
|
|
6
|
+
selectSearchEndpointHandler()
|
|
7
|
+
];
|
|
8
|
+
return config;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Plugin } from 'payload'\nimport { selectSearchEndpointHandler } from './endpoint.js'\n\nexport const selectSearchPlugin = (): Plugin => {\n return async (config) => {\n config.endpoints = [...(config.endpoints || []), selectSearchEndpointHandler()]\n return config\n }\n}\n"],"names":["selectSearchEndpointHandler","selectSearchPlugin","config","endpoints"],"mappings":"AACA,SAASA,2BAA2B,QAAQ,gBAAe;AAE3D,OAAO,MAAMC,qBAAqB;IAChC,OAAO,OAAOC;QACZA,OAAOC,SAAS,GAAG;eAAKD,OAAOC,SAAS,IAAI,EAAE;YAAGH;SAA8B;QAC/E,OAAOE;IACT;AACF,EAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Field, TextField } from 'payload';
|
|
2
2
|
import type { SelectSearchFunction } from './types.js';
|
|
3
|
-
export type SelectSearchFieldArgs =
|
|
3
|
+
export type SelectSearchFieldArgs = {
|
|
4
|
+
admin?: TextField['admin'];
|
|
5
|
+
custom?: Record<string, unknown>;
|
|
4
6
|
hasMany?: boolean;
|
|
5
|
-
|
|
7
|
+
passDataToSearchFunction?: boolean;
|
|
6
8
|
searchFunction: SelectSearchFunction;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
9
|
+
type?: 'text';
|
|
10
|
+
} & Omit<TextField, 'admin' | 'custom' | 'hasMany' | 'type'>;
|
|
10
11
|
export declare const selectSearchField: (args: SelectSearchFieldArgs) => Field;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const selectSearchField = (args)=>{
|
|
2
|
+
const { searchFunction, ...rest } = args;
|
|
3
|
+
return {
|
|
4
|
+
...rest,
|
|
5
|
+
type: 'text',
|
|
6
|
+
custom: {
|
|
7
|
+
...args.custom,
|
|
8
|
+
searchFunction: args.searchFunction
|
|
9
|
+
},
|
|
10
|
+
admin: {
|
|
11
|
+
...args.admin,
|
|
12
|
+
components: {
|
|
13
|
+
...args.admin?.components,
|
|
14
|
+
Field: args.admin?.components?.Field ?? '@whatworks/payload-select-search-field/client#SelectSearchField'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=selectSearchField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/selectSearchField.ts"],"sourcesContent":["import type { Field, TextField } from 'payload'\nimport type { SelectSearchFunction } from './types.js'\n\nexport type SelectSearchFieldArgs = Omit<TextField, 'admin' | 'custom' | 'type' | 'hasMany'> & {\n hasMany?: boolean\n type?: 'text'\n searchFunction: SelectSearchFunction\n custom?: Record<string, unknown>\n admin?: TextField['admin']\n}\n\nexport const selectSearchField = (args: SelectSearchFieldArgs): Field => {\n const { searchFunction, ...rest } = args\n return {\n ...rest,\n type: 'text',\n custom: {\n ...args.custom,\n searchFunction: args.searchFunction,\n },\n admin: {\n ...args.admin,\n components: {\n ...args.admin?.components,\n Field:\n args.admin?.components?.Field ??\n '@whatworks/payload-select-search-field/client#SelectSearchField',\n },\n },\n } as Field\n}\n"],"names":["selectSearchField","args","searchFunction","rest","type","custom","admin","components","Field"],"mappings":"AAWA,OAAO,MAAMA,oBAAoB,CAACC;IAChC,MAAM,EAAEC,cAAc,EAAE,GAAGC,MAAM,GAAGF;IACpC,OAAO;QACL,GAAGE,IAAI;QACPC,MAAM;QACNC,QAAQ;YACN,GAAGJ,KAAKI,MAAM;YACdH,gBAAgBD,KAAKC,cAAc;QACrC;QACAI,OAAO;YACL,GAAGL,KAAKK,KAAK;YACbC,YAAY;gBACV,GAAGN,KAAKK,KAAK,EAAEC,UAAU;gBACzBC,OACEP,KAAKK,KAAK,EAAEC,YAAYC,SACxB;YACJ;QACF;IACF;AACF,EAAC"}
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import type { FlattenedField, PayloadRequest, SanitizedCollectionConfig, SanitizedGlobalConfig } from 'payload';
|
|
1
|
+
import type { Data, FlattenedField, PayloadRequest, SanitizedCollectionConfig, SanitizedGlobalConfig } from 'payload';
|
|
2
2
|
export type SelectSearchOption = {
|
|
3
|
+
[key: string]: unknown;
|
|
3
4
|
label: string;
|
|
4
5
|
value: string;
|
|
5
|
-
[key: string]: unknown;
|
|
6
6
|
};
|
|
7
7
|
export type SelectSearchFunctionArgs = {
|
|
8
|
-
req: PayloadRequest;
|
|
9
|
-
query: string;
|
|
10
|
-
selectedValues: string[];
|
|
11
|
-
field: FlattenedField;
|
|
12
8
|
collection?: SanitizedCollectionConfig;
|
|
9
|
+
data?: Data;
|
|
10
|
+
field: FlattenedField;
|
|
13
11
|
global?: SanitizedGlobalConfig;
|
|
12
|
+
query: string;
|
|
13
|
+
req: PayloadRequest;
|
|
14
|
+
selectedValues: string[];
|
|
15
|
+
siblingData?: Data;
|
|
14
16
|
};
|
|
15
17
|
export type SelectSearchFunction = (args: SelectSearchFunctionArgs) => Promise<SelectSearchOption[]> | SelectSearchOption[];
|
|
16
18
|
export type SelectSearchRequest = {
|
|
19
|
+
data?: Data;
|
|
17
20
|
entityType: 'collection' | 'global';
|
|
18
|
-
slug: string;
|
|
19
|
-
schemaPath: string;
|
|
20
21
|
query?: string;
|
|
22
|
+
schemaPath: string;
|
|
21
23
|
selectedValues?: string[];
|
|
24
|
+
siblingData?: Data;
|
|
25
|
+
slug: string;
|
|
22
26
|
};
|
|
23
27
|
export type SelectSearchResponse = {
|
|
24
28
|
options: SelectSearchOption[];
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n FlattenedField,\n PayloadRequest,\n SanitizedCollectionConfig,\n SanitizedGlobalConfig,\n} from 'payload'\n\nexport type SelectSearchOption = {\n label: string\n value: string\n [key: string]: unknown\n}\n\nexport type SelectSearchFunctionArgs = {\n req: PayloadRequest\n query: string\n selectedValues: string[]\n field: FlattenedField\n collection?: SanitizedCollectionConfig\n global?: SanitizedGlobalConfig\n}\n\nexport type SelectSearchFunction = (\n args: SelectSearchFunctionArgs,\n) => Promise<SelectSearchOption[]> | SelectSearchOption[]\n\nexport type SelectSearchRequest = {\n entityType: 'collection' | 'global'\n slug: string\n schemaPath: string\n query?: string\n selectedValues?: string[]\n}\n\nexport type SelectSearchResponse = {\n options: SelectSearchOption[]\n}\n"],"names":[],"mappings":"AAkCA,WAEC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { SelectInput, useConfig, useDocumentInfo, useField } from '@payloadcms/ui';
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { selectSearchEndpoint } from '../endpointName.js';
|
|
6
|
+
const debounceMs = 300;
|
|
7
|
+
export const SelectSearchField = (props)=>{
|
|
8
|
+
const { field, path, schemaPath: schemaPathProp } = props;
|
|
9
|
+
const { value, setValue, showError } = useField({
|
|
10
|
+
path
|
|
11
|
+
});
|
|
12
|
+
const { collectionSlug, globalSlug } = useDocumentInfo();
|
|
13
|
+
const { config } = useConfig();
|
|
14
|
+
const [options, setOptions] = useState([]);
|
|
15
|
+
const [inputValue, setInputValue] = useState('');
|
|
16
|
+
const [remoteError, setRemoteError] = useState(null);
|
|
17
|
+
const abortRef = useRef(null);
|
|
18
|
+
const entityType = globalSlug ? 'global' : 'collection';
|
|
19
|
+
const slug = globalSlug || collectionSlug;
|
|
20
|
+
const schemaPath = schemaPathProp ?? field.name;
|
|
21
|
+
const hasMany = field.hasMany ?? false;
|
|
22
|
+
const apiPath = config.routes?.api || '/api';
|
|
23
|
+
const apiRoute = apiPath.startsWith('/') ? apiPath : `/${apiPath}`;
|
|
24
|
+
const baseURL = config.serverURL || '';
|
|
25
|
+
const endpointURL = `${baseURL}${apiRoute}${selectSearchEndpoint}`;
|
|
26
|
+
const selectedValues = useMemo(()=>{
|
|
27
|
+
if (hasMany) {
|
|
28
|
+
return Array.isArray(value) ? value.map((entry)=>String(entry)) : [];
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(value) || value === null || value === undefined) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return [
|
|
34
|
+
String(value)
|
|
35
|
+
];
|
|
36
|
+
}, [
|
|
37
|
+
hasMany,
|
|
38
|
+
value
|
|
39
|
+
]);
|
|
40
|
+
const fetchOptions = useCallback(async (query)=>{
|
|
41
|
+
if (!slug || !schemaPath) {
|
|
42
|
+
setOptions([]);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (abortRef.current) {
|
|
46
|
+
abortRef.current.abort();
|
|
47
|
+
}
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
abortRef.current = controller;
|
|
50
|
+
setRemoteError(null);
|
|
51
|
+
const res = await fetch(endpointURL, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'application/json'
|
|
55
|
+
},
|
|
56
|
+
credentials: 'include',
|
|
57
|
+
signal: controller.signal,
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
entityType,
|
|
60
|
+
slug,
|
|
61
|
+
schemaPath,
|
|
62
|
+
query,
|
|
63
|
+
selectedValues
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
const errorBody = await res.json().catch(()=>null);
|
|
68
|
+
const message = errorBody?.error || 'Failed to fetch options';
|
|
69
|
+
setRemoteError(message);
|
|
70
|
+
setOptions([]);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const data = await res.json();
|
|
74
|
+
setOptions(Array.isArray(data.options) ? data.options : []);
|
|
75
|
+
}, [
|
|
76
|
+
endpointURL,
|
|
77
|
+
entityType,
|
|
78
|
+
schemaPath,
|
|
79
|
+
selectedValues,
|
|
80
|
+
slug
|
|
81
|
+
]);
|
|
82
|
+
useEffect(()=>{
|
|
83
|
+
if (!slug || !schemaPath) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const timeout = setTimeout(()=>{
|
|
87
|
+
void fetchOptions(inputValue);
|
|
88
|
+
}, debounceMs);
|
|
89
|
+
return ()=>{
|
|
90
|
+
clearTimeout(timeout);
|
|
91
|
+
};
|
|
92
|
+
}, [
|
|
93
|
+
fetchOptions,
|
|
94
|
+
inputValue,
|
|
95
|
+
schemaPath,
|
|
96
|
+
slug
|
|
97
|
+
]);
|
|
98
|
+
useEffect(()=>{
|
|
99
|
+
return ()=>{
|
|
100
|
+
if (abortRef.current) {
|
|
101
|
+
abortRef.current.abort();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}, []);
|
|
105
|
+
const handleChange = useCallback((option)=>{
|
|
106
|
+
if (Array.isArray(option)) {
|
|
107
|
+
const values = option.map((entry)=>String(entry.value));
|
|
108
|
+
setValue(values);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!option) {
|
|
112
|
+
setValue(hasMany ? [] : null);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
setValue(String(option.value));
|
|
116
|
+
}, [
|
|
117
|
+
hasMany,
|
|
118
|
+
setValue
|
|
119
|
+
]);
|
|
120
|
+
const description = useMemo(()=>{
|
|
121
|
+
if (remoteError) {
|
|
122
|
+
return remoteError;
|
|
123
|
+
}
|
|
124
|
+
return field.admin?.description;
|
|
125
|
+
}, [
|
|
126
|
+
field.admin?.description,
|
|
127
|
+
remoteError
|
|
128
|
+
]);
|
|
129
|
+
const selectValue = useMemo(()=>{
|
|
130
|
+
if (hasMany) {
|
|
131
|
+
return Array.isArray(value) ? value : [];
|
|
132
|
+
}
|
|
133
|
+
return Array.isArray(value) ? '' : value ?? '';
|
|
134
|
+
}, [
|
|
135
|
+
hasMany,
|
|
136
|
+
value
|
|
137
|
+
]);
|
|
138
|
+
return /*#__PURE__*/ _jsx(SelectInput, {
|
|
139
|
+
description: description,
|
|
140
|
+
hasMany: hasMany,
|
|
141
|
+
label: field.label,
|
|
142
|
+
localized: field.localized,
|
|
143
|
+
name: field.name,
|
|
144
|
+
onChange: handleChange,
|
|
145
|
+
onInputChange: setInputValue,
|
|
146
|
+
options: options,
|
|
147
|
+
path: path,
|
|
148
|
+
required: field.required,
|
|
149
|
+
showError: showError,
|
|
150
|
+
value: selectValue
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
//# sourceMappingURL=SelectSearchField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ui/SelectSearchField.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject, TextFieldClientComponent } from 'payload'\nimport type { ReactSelectOption } from '@payloadcms/ui'\nimport { SelectInput, useConfig, useDocumentInfo, useField } from '@payloadcms/ui'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { selectSearchEndpoint } from '../endpointName.js'\n\nconst debounceMs = 300\n\nexport const SelectSearchField: TextFieldClientComponent = (props) => {\n const { field, path, schemaPath: schemaPathProp } = props\n\n const { value, setValue, showError } = useField<string | string[]>({\n path,\n })\n\n const { collectionSlug, globalSlug } = useDocumentInfo()\n const { config } = useConfig()\n\n const [options, setOptions] = useState<OptionObject[]>([])\n\n const [inputValue, setInputValue] = useState('')\n const [remoteError, setRemoteError] = useState<string | null>(null)\n\n const abortRef = useRef<AbortController | null>(null)\n\n const entityType = globalSlug ? 'global' : 'collection'\n const slug = globalSlug || collectionSlug\n\n const schemaPath = schemaPathProp ?? field.name\n const hasMany = field.hasMany ?? false\n\n const apiPath = config.routes?.api || '/api'\n const apiRoute = apiPath.startsWith('/') ? apiPath : `/${apiPath}`\n const baseURL = config.serverURL || ''\n const endpointURL = `${baseURL}${apiRoute}${selectSearchEndpoint}`\n\n const selectedValues = useMemo(() => {\n if (hasMany) {\n return Array.isArray(value) ? value.map((entry) => String(entry)) : []\n }\n\n if (Array.isArray(value) || value === null || value === undefined) {\n return []\n }\n\n return [String(value)]\n }, [hasMany, value])\n\n const fetchOptions = useCallback(\n async (query: string) => {\n if (!slug || !schemaPath) {\n setOptions([])\n return\n }\n\n if (abortRef.current) {\n abortRef.current.abort()\n }\n\n const controller = new AbortController()\n abortRef.current = controller\n\n setRemoteError(null)\n\n const res = await fetch(endpointURL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: 'include',\n signal: controller.signal,\n body: JSON.stringify({\n entityType,\n slug,\n schemaPath,\n query,\n selectedValues,\n }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => null)\n const message = errorBody?.error || 'Failed to fetch options'\n setRemoteError(message)\n setOptions([])\n return\n }\n\n const data = (await res.json()) as { options?: OptionObject[] }\n setOptions(Array.isArray(data.options) ? data.options : [])\n },\n [endpointURL, entityType, schemaPath, selectedValues, slug],\n )\n\n useEffect(() => {\n if (!slug || !schemaPath) {\n return\n }\n\n const timeout = setTimeout(() => {\n void fetchOptions(inputValue)\n }, debounceMs)\n\n return () => {\n clearTimeout(timeout)\n }\n }, [fetchOptions, inputValue, schemaPath, slug])\n\n useEffect(() => {\n return () => {\n if (abortRef.current) {\n abortRef.current.abort()\n }\n }\n }, [])\n\n const handleChange = useCallback(\n (option: ReactSelectOption | ReactSelectOption[] | null) => {\n if (Array.isArray(option)) {\n const values = option.map((entry) => String(entry.value))\n setValue(values)\n return\n }\n\n if (!option) {\n setValue(hasMany ? [] : null)\n return\n }\n\n setValue(String(option.value))\n },\n [hasMany, setValue],\n )\n\n const description = useMemo(() => {\n if (remoteError) {\n return remoteError\n }\n\n return field.admin?.description\n }, [field.admin?.description, remoteError])\n\n const selectValue = useMemo(() => {\n if (hasMany) {\n return Array.isArray(value) ? value : []\n }\n\n return Array.isArray(value) ? '' : (value ?? '')\n }, [hasMany, value])\n\n return (\n <SelectInput\n description={description}\n hasMany={hasMany}\n label={field.label as string}\n localized={field.localized}\n name={field.name}\n onChange={handleChange as (value: ReactSelectOption | ReactSelectOption[]) => void}\n onInputChange={setInputValue}\n options={options}\n path={path}\n required={field.required}\n showError={showError}\n value={selectValue}\n />\n )\n}\n"],"names":["SelectInput","useConfig","useDocumentInfo","useField","useCallback","useEffect","useMemo","useRef","useState","selectSearchEndpoint","debounceMs","SelectSearchField","props","field","path","schemaPath","schemaPathProp","value","setValue","showError","collectionSlug","globalSlug","config","options","setOptions","inputValue","setInputValue","remoteError","setRemoteError","abortRef","entityType","slug","name","hasMany","apiPath","routes","api","apiRoute","startsWith","baseURL","serverURL","endpointURL","selectedValues","Array","isArray","map","entry","String","undefined","fetchOptions","query","current","abort","controller","AbortController","res","fetch","method","headers","credentials","signal","body","JSON","stringify","ok","errorBody","json","catch","message","error","data","timeout","setTimeout","clearTimeout","handleChange","option","values","description","admin","selectValue","label","localized","onChange","onInputChange","required"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whatworks/payload-select-search-field",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Payload plugin and field component for server-backed search select fields.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
"LICENSE.md",
|
|
12
12
|
"README.md"
|
|
13
13
|
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/what-works-global/payload-packages",
|
|
17
|
+
"directory": "packages/select-search-field"
|
|
18
|
+
},
|
|
14
19
|
"publishConfig": {
|
|
15
20
|
"access": "public",
|
|
16
21
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -37,9 +42,15 @@
|
|
|
37
42
|
"@payloadcms/db-mongodb": "^3.0.0",
|
|
38
43
|
"@payloadcms/eslint-config": "^3.0.0",
|
|
39
44
|
"@payloadcms/next": "^3.0.0",
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@types/
|
|
45
|
+
"@swc-node/register": "1.10.9",
|
|
46
|
+
"@swc/cli": "0.6.0",
|
|
47
|
+
"@types/node": "22.19.9",
|
|
48
|
+
"@types/react": "19.2.9",
|
|
49
|
+
"@types/react-dom": "19.2.3",
|
|
50
|
+
"react": "19.2.1",
|
|
51
|
+
"react-dom": "19.2.1",
|
|
52
|
+
"eslint": "^9.23.0",
|
|
53
|
+
"eslint-config-next": "15.4.11",
|
|
43
54
|
"copyfiles": "^2.4.1",
|
|
44
55
|
"cross-env": "^7.0.3",
|
|
45
56
|
"next": "^16.1.6",
|
|
@@ -49,15 +60,19 @@
|
|
|
49
60
|
"typescript": "5.5.3"
|
|
50
61
|
},
|
|
51
62
|
"scripts": {
|
|
52
|
-
"build": "
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
63
|
+
"build": "pnpm copyfiles && pnpm build:types && pnpm build:swc",
|
|
64
|
+
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
65
|
+
"build:types": "tsc --outDir dist --rootDir ./src",
|
|
66
|
+
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
67
|
+
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
68
|
+
"dev": "next dev dev --turbo",
|
|
57
69
|
"dev:generate-importmap": "pnpm dev:payload generate:importmap",
|
|
58
70
|
"dev:generate-types": "pnpm dev:payload generate:types",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
71
|
+
"dev:payload": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload",
|
|
72
|
+
"generate:importmap": "pnpm dev:generate-importmap",
|
|
73
|
+
"generate:types": "pnpm dev:generate-types",
|
|
74
|
+
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
|
75
|
+
"lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
|
|
76
|
+
"typecheck": "tsc --outDir dist --rootDir ./src"
|
|
62
77
|
}
|
|
63
78
|
}
|