@payloadcms/plugin-multi-tenant 0.0.1 → 3.18.0
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 +130 -95
- package/dist/components/GlobalViewRedirect/index.d.ts +3 -2
- package/dist/components/GlobalViewRedirect/index.d.ts.map +1 -1
- package/dist/components/GlobalViewRedirect/index.js +1 -0
- package/dist/components/GlobalViewRedirect/index.js.map +1 -1
- package/dist/components/TenantField/index.client.d.ts +3 -3
- package/dist/components/TenantField/index.client.d.ts.map +1 -1
- package/dist/components/TenantField/index.client.js +55 -17
- package/dist/components/TenantField/index.client.js.map +1 -1
- package/dist/components/TenantField/index.scss +14 -0
- package/dist/components/TenantSelector/index.d.ts +5 -8
- package/dist/components/TenantSelector/index.d.ts.map +1 -1
- package/dist/components/TenantSelector/index.js +35 -24
- package/dist/components/TenantSelector/index.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.d.ts.map +1 -0
- package/dist/exports/client.js +4 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/fields.d.ts +3 -0
- package/dist/exports/fields.d.ts.map +1 -0
- package/dist/exports/fields.js +4 -0
- package/dist/exports/fields.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -2
- package/dist/exports/rsc.d.ts.map +1 -1
- package/dist/exports/rsc.js +1 -2
- package/dist/exports/rsc.js.map +1 -1
- package/dist/fields/tenantField/index.d.ts +2 -3
- package/dist/fields/tenantField/index.d.ts.map +1 -1
- package/dist/fields/tenantField/index.js +8 -4
- package/dist/fields/tenantField/index.js.map +1 -1
- package/dist/fields/tenantsArrayField/index.d.ts +7 -0
- package/dist/fields/tenantsArrayField/index.d.ts.map +1 -0
- package/dist/fields/{userTenantsArrayField → tenantsArrayField}/index.js +3 -3
- package/dist/fields/tenantsArrayField/index.js.map +1 -0
- package/dist/hooks/afterTenantDelete.d.ts +16 -0
- package/dist/hooks/afterTenantDelete.d.ts.map +1 -0
- package/dist/hooks/afterTenantDelete.js +71 -0
- package/dist/hooks/afterTenantDelete.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -49
- package/dist/index.js.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.client.d.ts +19 -0
- package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -0
- package/dist/providers/TenantSelectionProvider/index.client.js +69 -0
- package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -0
- package/dist/providers/TenantSelectionProvider/index.d.ts +11 -0
- package/dist/providers/TenantSelectionProvider/index.d.ts.map +1 -0
- package/dist/providers/TenantSelectionProvider/index.js +31 -0
- package/dist/providers/TenantSelectionProvider/index.js.map +1 -0
- package/dist/types.d.ts +54 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/addCollectionAccess.d.ts +13 -0
- package/dist/utilities/addCollectionAccess.d.ts.map +1 -0
- package/dist/utilities/addCollectionAccess.js +29 -0
- package/dist/utilities/addCollectionAccess.js.map +1 -0
- package/dist/utilities/addFilterOptionsToFields.d.ts +9 -0
- package/dist/utilities/addFilterOptionsToFields.d.ts.map +1 -0
- package/dist/utilities/addFilterOptionsToFields.js +107 -0
- package/dist/utilities/addFilterOptionsToFields.js.map +1 -0
- package/dist/utilities/combineWhereConstraints.js +2 -2
- package/dist/utilities/combineWhereConstraints.js.map +1 -1
- package/dist/utilities/getGlobalViewRedirect.d.ts +4 -3
- package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -1
- package/dist/utilities/getGlobalViewRedirect.js +6 -5
- package/dist/utilities/getGlobalViewRedirect.js.map +1 -1
- package/dist/utilities/getTenantAccess.d.ts +7 -3
- package/dist/utilities/getTenantAccess.d.ts.map +1 -1
- package/dist/utilities/getTenantAccess.js +6 -9
- package/dist/utilities/getTenantAccess.js.map +1 -1
- package/dist/utilities/getTenantFromCookie.d.ts +8 -1
- package/dist/utilities/getTenantFromCookie.d.ts.map +1 -1
- package/dist/utilities/getTenantFromCookie.js +7 -1
- package/dist/utilities/getTenantFromCookie.js.map +1 -1
- package/dist/utilities/getTenantListFilter.d.ts.map +1 -1
- package/dist/utilities/getTenantListFilter.js +8 -8
- package/dist/utilities/getTenantListFilter.js.map +1 -1
- package/dist/utilities/getUserTenantIDs.d.ts +1 -2
- package/dist/utilities/getUserTenantIDs.d.ts.map +1 -1
- package/dist/utilities/getUserTenantIDs.js +2 -6
- package/dist/utilities/getUserTenantIDs.js.map +1 -1
- package/dist/utilities/withTenantAccess.d.ts +4 -3
- package/dist/utilities/withTenantAccess.d.ts.map +1 -1
- package/dist/utilities/withTenantAccess.js +12 -16
- package/dist/utilities/withTenantAccess.js.map +1 -1
- package/dist/utilities/withTenantListFilter.js +1 -1
- package/dist/utilities/withTenantListFilter.js.map +1 -1
- package/package.json +20 -10
- package/dist/components/TenantField/index.d.ts +0 -3
- package/dist/components/TenantField/index.d.ts.map +0 -1
- package/dist/components/TenantField/index.js +0 -33
- package/dist/components/TenantField/index.js.map +0 -1
- package/dist/components/TenantSelector/index.client.d.ts +0 -11
- package/dist/components/TenantSelector/index.client.d.ts.map +0 -1
- package/dist/components/TenantSelector/index.client.js +0 -61
- package/dist/components/TenantSelector/index.client.js.map +0 -1
- package/dist/fields/userTenantsArrayField/index.d.ts +0 -4
- package/dist/fields/userTenantsArrayField/index.d.ts.map +0 -1
- package/dist/fields/userTenantsArrayField/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,122 +3,126 @@
|
|
|
3
3
|
A plugin for [Payload](https://github.com/payloadcms/payload) to easily manage multiple tenants from within your admin panel.
|
|
4
4
|
|
|
5
5
|
- [Source code](https://github.com/payloadcms/payload/tree/main/packages/plugin-multi-tenant)
|
|
6
|
-
|
|
7
|
-
- [Documentation source](https://github.com/payloadcms/payload/tree/main/docs/plugins/multi-tenant.mdx)
|
|
6
|
+
- [Documentation](https://payloadcms.com/docs/plugins/multi-tenant)
|
|
7
|
+
- [Documentation source](https://github.com/payloadcms/payload/tree/main/docs/plugins/multi-tenant.mdx)
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @payloadcms/plugin-multi-tenant@beta
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Plugin Types
|
|
10
16
|
|
|
11
17
|
```ts
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Enable debugging:
|
|
15
|
-
* - shows the relationship field on enabled collection documents
|
|
16
|
-
*
|
|
17
|
-
* optional - @default false
|
|
18
|
-
*/
|
|
19
|
-
debug: false,
|
|
20
|
-
/**
|
|
21
|
-
* Enables/Disables the plugin
|
|
22
|
-
*
|
|
23
|
-
* optional - @default true
|
|
24
|
-
*/
|
|
25
|
-
enabled: true,
|
|
18
|
+
type MultiTenantPluginConfig<ConfigTypes = unknown> = {
|
|
26
19
|
/**
|
|
27
|
-
*
|
|
20
|
+
* After a tenant is deleted, the plugin will attempt to clean up related documents
|
|
21
|
+
* - removing documents with the tenant ID
|
|
22
|
+
* - removing the tenant from users
|
|
28
23
|
*
|
|
29
|
-
*
|
|
24
|
+
* @default true
|
|
30
25
|
*/
|
|
31
|
-
|
|
26
|
+
cleanupAfterTenantDelete?: boolean
|
|
32
27
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* Keyed on the slug of the collection
|
|
28
|
+
* Automatically
|
|
36
29
|
*/
|
|
37
30
|
collections: {
|
|
38
|
-
|
|
31
|
+
[key in CollectionSlug]?: {
|
|
39
32
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* You can use the exported utility "getTenantFilter" within your own list filter
|
|
33
|
+
* Set to `true` if you want the collection to behave as a global
|
|
43
34
|
*
|
|
44
|
-
*
|
|
35
|
+
* @default false
|
|
45
36
|
*/
|
|
46
|
-
|
|
37
|
+
isGlobal?: boolean
|
|
47
38
|
/**
|
|
48
|
-
*
|
|
39
|
+
* Set to `false` if you want to manually apply the baseListFilter
|
|
49
40
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* optional - @default true
|
|
41
|
+
* @default true
|
|
53
42
|
*/
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Used to make a collection feel like a global. When navigating to the list view, they will be redirected to the document view.
|
|
57
|
-
*
|
|
58
|
-
* optional - @default false
|
|
59
|
-
*/
|
|
60
|
-
isGlobal: false
|
|
61
|
-
},
|
|
62
|
-
/**
|
|
63
|
-
* Custom configuration for the tenant field placed on every enabled collection
|
|
64
|
-
*/
|
|
65
|
-
documentTenantField: {
|
|
66
|
-
// optional - provide access control on the injected tenant field
|
|
67
|
-
access: {
|
|
68
|
-
create,
|
|
69
|
-
read,
|
|
70
|
-
update,
|
|
71
|
-
},
|
|
43
|
+
useBaseListFilter?: boolean
|
|
72
44
|
/**
|
|
73
|
-
*
|
|
45
|
+
* Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied
|
|
74
46
|
*
|
|
75
|
-
*
|
|
47
|
+
* @default true
|
|
76
48
|
*/
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
49
|
+
useTenantAccess?: boolean
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Enables debug mode
|
|
54
|
+
* - Makes the tenant field visible in the admin UI within applicable collections
|
|
55
|
+
*
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
debug?: boolean
|
|
59
|
+
/**
|
|
60
|
+
* Enables the multi-tenant plugin
|
|
61
|
+
*
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
enabled?: boolean
|
|
65
|
+
/**
|
|
66
|
+
* Field configuration for the field added to all tenant enabled collections
|
|
67
|
+
*/
|
|
68
|
+
tenantField?: {
|
|
69
|
+
access?: RelationshipField['access']
|
|
85
70
|
/**
|
|
86
|
-
*
|
|
71
|
+
* The name of the field added to all tenant enabled collections
|
|
87
72
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* optional - @default undefined
|
|
73
|
+
* @default 'tenant'
|
|
91
74
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
75
|
+
name?: string
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Field configuration for the field added to the users collection
|
|
79
|
+
*
|
|
80
|
+
* If `includeDefaultField` is `false`, you must include the field on your users collection manually
|
|
81
|
+
* This is useful if you want to customize the field or place the field in a specific location
|
|
82
|
+
*/
|
|
83
|
+
tenantsArrayField?:
|
|
84
|
+
| {
|
|
85
|
+
/**
|
|
86
|
+
* Access configuration for the array field
|
|
87
|
+
*/
|
|
88
|
+
arrayFieldAccess?: ArrayField['access']
|
|
89
|
+
/**
|
|
90
|
+
* When `includeDefaultField` is `true`, the field will be added to the users collection automatically
|
|
91
|
+
*/
|
|
92
|
+
includeDefaultField?: true
|
|
93
|
+
/**
|
|
94
|
+
* Additional fields to include on the tenants array field
|
|
95
|
+
*/
|
|
96
|
+
rowFields?: Field[]
|
|
97
|
+
/**
|
|
98
|
+
* Access configuration for the tenant field
|
|
99
|
+
*/
|
|
100
|
+
tenantFieldAccess?: RelationshipField['access']
|
|
101
|
+
}
|
|
102
|
+
| {
|
|
103
|
+
arrayFieldAccess?: never
|
|
104
|
+
/**
|
|
105
|
+
* When `includeDefaultField` is `false`, you must include the field on your users collection manually
|
|
106
|
+
*/
|
|
107
|
+
includeDefaultField?: false
|
|
108
|
+
rowFields?: never
|
|
109
|
+
tenantFieldAccess?: never
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The slug for the tenant collection
|
|
113
|
+
*
|
|
114
|
+
* @default 'tenants'
|
|
115
|
+
*/
|
|
116
|
+
tenantsSlug?: string
|
|
117
|
+
/**
|
|
118
|
+
* Function that determines if a user has access to _all_ tenants
|
|
119
|
+
*
|
|
120
|
+
* Useful for super-admin type users
|
|
121
|
+
*/
|
|
122
|
+
userHasAccessToAllTenants?: (
|
|
123
|
+
user: ConfigTypes extends { user } ? ConfigTypes['user'] : User,
|
|
124
|
+
) => boolean
|
|
125
|
+
}
|
|
122
126
|
```
|
|
123
127
|
|
|
124
128
|
### How to configure Collections as Globals for multi-tenant
|
|
@@ -202,3 +206,34 @@ export default buildConfig({
|
|
|
202
206
|
],
|
|
203
207
|
})
|
|
204
208
|
```
|
|
209
|
+
|
|
210
|
+
### Placing the tenants array field
|
|
211
|
+
|
|
212
|
+
In your users collection you may want to place the field in a tab or in the sidebar, or customize some of the properties on it.
|
|
213
|
+
|
|
214
|
+
You can use the `tenantsArrayField.includeDefaultField: false` setting in the plugin config. You will then need to manually add a `tenants` array field in your users collection.
|
|
215
|
+
|
|
216
|
+
This field cannot be nested inside a named field, ie a group, named-tab or array. It _can_ be nested inside a row, unnamed-tab, collapsible.
|
|
217
|
+
|
|
218
|
+
To make it easier, this plugin exports the field for you to import and merge in your own properties.
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import type { CollectionConfig } from 'payload'
|
|
222
|
+
import { tenantsArrayField } from '@payloadcms/plugin-multi-tenant/fields'
|
|
223
|
+
|
|
224
|
+
const customTenantsArrayField = tenantsArrayField({
|
|
225
|
+
arrayFieldAccess: {}, // access control for the array field
|
|
226
|
+
tenantFieldAccess: {}, // access control for the tenants field on the array row
|
|
227
|
+
rowFields: [], // additional row fields
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
export const UsersCollection: CollectionConfig = {
|
|
231
|
+
slug: 'users',
|
|
232
|
+
fields: [
|
|
233
|
+
{
|
|
234
|
+
...customTenantsArrayField,
|
|
235
|
+
label: 'Associated Tenants',
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
}
|
|
239
|
+
```
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { CollectionSlug, ServerProps } from 'payload';
|
|
1
|
+
import type { CollectionSlug, ServerProps, ViewTypes } from 'payload';
|
|
2
2
|
type Args = {
|
|
3
3
|
collectionSlug: CollectionSlug;
|
|
4
4
|
docID?: number | string;
|
|
5
5
|
globalSlugs: string[];
|
|
6
|
-
|
|
6
|
+
tenantFieldName: string;
|
|
7
|
+
viewType: ViewTypes;
|
|
7
8
|
} & ServerProps;
|
|
8
9
|
export declare const GlobalViewRedirect: (args: Args) => Promise<void>;
|
|
9
10
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/GlobalViewRedirect/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/GlobalViewRedirect/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMrE,KAAK,IAAI,GAAG;IACV,cAAc,EAAE,cAAc,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,SAAS,CAAA;CACpB,GAAG,WAAW,CAAA;AAEf,eAAO,MAAM,kBAAkB,SAAgB,IAAI,kBAgBlD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/GlobalViewRedirect/index.ts"],"sourcesContent":["import type { CollectionSlug, ServerProps } from 'payload'\n\nimport { redirect } from 'next/navigation.js'\n\nimport { getGlobalViewRedirect } from '../../utilities/getGlobalViewRedirect.js'\n\ntype Args = {\n collectionSlug: CollectionSlug\n docID?: number | string\n globalSlugs: string[]\n viewType:
|
|
1
|
+
{"version":3,"sources":["../../../src/components/GlobalViewRedirect/index.ts"],"sourcesContent":["import type { CollectionSlug, ServerProps, ViewTypes } from 'payload'\n\nimport { redirect } from 'next/navigation.js'\n\nimport { getGlobalViewRedirect } from '../../utilities/getGlobalViewRedirect.js'\n\ntype Args = {\n collectionSlug: CollectionSlug\n docID?: number | string\n globalSlugs: string[]\n tenantFieldName: string\n viewType: ViewTypes\n} & ServerProps\n\nexport const GlobalViewRedirect = async (args: Args) => {\n const collectionSlug = args?.collectionSlug\n\n if (collectionSlug && args.globalSlugs?.includes(collectionSlug)) {\n const redirectRoute = await getGlobalViewRedirect({\n slug: collectionSlug,\n docID: args.docID,\n payload: args.payload,\n tenantFieldName: args.tenantFieldName,\n view: args.viewType,\n })\n\n if (redirectRoute) {\n redirect(redirectRoute)\n }\n }\n}\n"],"names":["redirect","getGlobalViewRedirect","GlobalViewRedirect","args","collectionSlug","globalSlugs","includes","redirectRoute","slug","docID","payload","tenantFieldName","view","viewType"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,qBAAoB;AAE7C,SAASC,qBAAqB,QAAQ,2CAA0C;AAUhF,OAAO,MAAMC,qBAAqB,OAAOC;IACvC,MAAMC,iBAAiBD,MAAMC;IAE7B,IAAIA,kBAAkBD,KAAKE,WAAW,EAAEC,SAASF,iBAAiB;QAChE,MAAMG,gBAAgB,MAAMN,sBAAsB;YAChDO,MAAMJ;YACNK,OAAON,KAAKM,KAAK;YACjBC,SAASP,KAAKO,OAAO;YACrBC,iBAAiBR,KAAKQ,eAAe;YACrCC,MAAMT,KAAKU,QAAQ;QACrB;QAEA,IAAIN,eAAe;YACjBP,SAASO;QACX;IACF;AACF,EAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { RelationshipFieldClientProps } from 'payload';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import './index.scss';
|
|
3
4
|
type Props = {
|
|
4
5
|
debug?: boolean;
|
|
5
|
-
|
|
6
|
-
tenantsCollectionSlug: string;
|
|
6
|
+
unique?: boolean;
|
|
7
7
|
} & RelationshipFieldClientProps;
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const TenantField: (args: Props) => React.JSX.Element | null;
|
|
9
9
|
export {};
|
|
10
10
|
//# sourceMappingURL=index.client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/components/TenantField/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AAG3D,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/components/TenantField/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AAG3D,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,cAAc,CAAA;AAIrB,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,GAAG,4BAA4B,CAAA;AAEhC,eAAO,MAAM,WAAW,SAAU,KAAK,6BA0CtC,CAAA"}
|
|
@@ -1,31 +1,69 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { RelationshipField, useField } from '@payloadcms/ui';
|
|
4
4
|
import React from 'react';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { SELECT_ALL } from '../../constants.js';
|
|
6
|
+
import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js';
|
|
7
|
+
import './index.scss';
|
|
8
|
+
const baseClass = 'tenantField';
|
|
9
|
+
export const TenantField = (args)=>{
|
|
10
|
+
const { debug, path, unique } = args;
|
|
7
11
|
const { setValue, value } = useField({
|
|
8
12
|
path
|
|
9
13
|
});
|
|
14
|
+
const { options, selectedTenantID, setPreventRefreshOnChange, setTenant } = useTenantSelection();
|
|
15
|
+
const hasSetValueRef = React.useRef(false);
|
|
10
16
|
React.useEffect(()=>{
|
|
11
|
-
if (
|
|
12
|
-
|
|
17
|
+
if (!hasSetValueRef.current && value) {
|
|
18
|
+
// set value on load
|
|
19
|
+
setTenant({
|
|
20
|
+
id: value,
|
|
21
|
+
refresh: unique
|
|
22
|
+
});
|
|
23
|
+
hasSetValueRef.current = true;
|
|
24
|
+
} else if (selectedTenantID && selectedTenantID === SELECT_ALL && options?.[0]?.value) {
|
|
25
|
+
// in the document view, the tenant field should always have a value
|
|
26
|
+
setTenant({
|
|
27
|
+
id: options[0].value,
|
|
28
|
+
refresh: unique
|
|
29
|
+
});
|
|
30
|
+
} else if ((!value || value !== selectedTenantID) && selectedTenantID) {
|
|
31
|
+
// Update the field value when the tenant is changed
|
|
32
|
+
setValue(selectedTenantID);
|
|
13
33
|
}
|
|
14
34
|
}, [
|
|
15
|
-
|
|
35
|
+
value,
|
|
36
|
+
selectedTenantID,
|
|
37
|
+
setTenant,
|
|
16
38
|
setValue,
|
|
17
|
-
|
|
39
|
+
options,
|
|
40
|
+
unique
|
|
18
41
|
]);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
42
|
+
React.useEffect(()=>{
|
|
43
|
+
if (!unique) {
|
|
44
|
+
setPreventRefreshOnChange(true);
|
|
45
|
+
}
|
|
46
|
+
return ()=>{
|
|
47
|
+
setPreventRefreshOnChange(false);
|
|
48
|
+
};
|
|
49
|
+
}, [
|
|
50
|
+
unique,
|
|
51
|
+
setPreventRefreshOnChange
|
|
52
|
+
]);
|
|
53
|
+
if (debug) {
|
|
54
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
55
|
+
className: baseClass,
|
|
56
|
+
children: [
|
|
57
|
+
/*#__PURE__*/ _jsx("div", {
|
|
58
|
+
className: `${baseClass}__wrapper`,
|
|
59
|
+
children: /*#__PURE__*/ _jsx(RelationshipField, {
|
|
60
|
+
...args
|
|
61
|
+
})
|
|
62
|
+
}),
|
|
63
|
+
/*#__PURE__*/ _jsx("div", {
|
|
64
|
+
className: `${baseClass}__hr`
|
|
65
|
+
})
|
|
66
|
+
]
|
|
29
67
|
});
|
|
30
68
|
}
|
|
31
69
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/TenantField/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { RelationshipFieldClientProps } from 'payload'\n\nimport { RelationshipField, useField } from '@payloadcms/ui'\nimport React from 'react'\n\ntype Props = {\n debug?: boolean\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/TenantField/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { RelationshipFieldClientProps } from 'payload'\n\nimport { RelationshipField, useField } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { SELECT_ALL } from '../../constants.js'\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\nimport './index.scss'\n\nconst baseClass = 'tenantField'\n\ntype Props = {\n debug?: boolean\n unique?: boolean\n} & RelationshipFieldClientProps\n\nexport const TenantField = (args: Props) => {\n const { debug, path, unique } = args\n const { setValue, value } = useField<number | string>({ path })\n const { options, selectedTenantID, setPreventRefreshOnChange, setTenant } = useTenantSelection()\n\n const hasSetValueRef = React.useRef(false)\n\n React.useEffect(() => {\n if (!hasSetValueRef.current && value) {\n // set value on load\n setTenant({ id: value, refresh: unique })\n hasSetValueRef.current = true\n } else if (selectedTenantID && selectedTenantID === SELECT_ALL && options?.[0]?.value) {\n // in the document view, the tenant field should always have a value\n setTenant({ id: options[0].value, refresh: unique })\n } else if ((!value || value !== selectedTenantID) && selectedTenantID) {\n // Update the field value when the tenant is changed\n setValue(selectedTenantID)\n }\n }, [value, selectedTenantID, setTenant, setValue, options, unique])\n\n React.useEffect(() => {\n if (!unique) {\n setPreventRefreshOnChange(true)\n }\n return () => {\n setPreventRefreshOnChange(false)\n }\n }, [unique, setPreventRefreshOnChange])\n\n if (debug) {\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__wrapper`}>\n <RelationshipField {...args} />\n </div>\n <div className={`${baseClass}__hr`} />\n </div>\n )\n }\n\n return null\n}\n"],"names":["RelationshipField","useField","React","SELECT_ALL","useTenantSelection","baseClass","TenantField","args","debug","path","unique","setValue","value","options","selectedTenantID","setPreventRefreshOnChange","setTenant","hasSetValueRef","useRef","useEffect","current","id","refresh","div","className"],"mappings":"AAAA;;AAIA,SAASA,iBAAiB,EAAEC,QAAQ,QAAQ,iBAAgB;AAC5D,OAAOC,WAAW,QAAO;AAEzB,SAASC,UAAU,QAAQ,qBAAoB;AAC/C,SAASC,kBAAkB,QAAQ,0DAAyD;AAC5F,OAAO,eAAc;AAErB,MAAMC,YAAY;AAOlB,OAAO,MAAMC,cAAc,CAACC;IAC1B,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAEC,MAAM,EAAE,GAAGH;IAChC,MAAM,EAAEI,QAAQ,EAAEC,KAAK,EAAE,GAAGX,SAA0B;QAAEQ;IAAK;IAC7D,MAAM,EAAEI,OAAO,EAAEC,gBAAgB,EAAEC,yBAAyB,EAAEC,SAAS,EAAE,GAAGZ;IAE5E,MAAMa,iBAAiBf,MAAMgB,MAAM,CAAC;IAEpChB,MAAMiB,SAAS,CAAC;QACd,IAAI,CAACF,eAAeG,OAAO,IAAIR,OAAO;YACpC,oBAAoB;YACpBI,UAAU;gBAAEK,IAAIT;gBAAOU,SAASZ;YAAO;YACvCO,eAAeG,OAAO,GAAG;QAC3B,OAAO,IAAIN,oBAAoBA,qBAAqBX,cAAcU,SAAS,CAAC,EAAE,EAAED,OAAO;YACrF,oEAAoE;YACpEI,UAAU;gBAAEK,IAAIR,OAAO,CAAC,EAAE,CAACD,KAAK;gBAAEU,SAASZ;YAAO;QACpD,OAAO,IAAI,AAAC,CAAA,CAACE,SAASA,UAAUE,gBAAe,KAAMA,kBAAkB;YACrE,oDAAoD;YACpDH,SAASG;QACX;IACF,GAAG;QAACF;QAAOE;QAAkBE;QAAWL;QAAUE;QAASH;KAAO;IAElER,MAAMiB,SAAS,CAAC;QACd,IAAI,CAACT,QAAQ;YACXK,0BAA0B;QAC5B;QACA,OAAO;YACLA,0BAA0B;QAC5B;IACF,GAAG;QAACL;QAAQK;KAA0B;IAEtC,IAAIP,OAAO;QACT,qBACE,MAACe;YAAIC,WAAWnB;;8BACd,KAACkB;oBAAIC,WAAW,GAAGnB,UAAU,SAAS,CAAC;8BACrC,cAAA,KAACL;wBAAmB,GAAGO,IAAI;;;8BAE7B,KAACgB;oBAAIC,WAAW,GAAGnB,UAAU,IAAI,CAAC;;;;IAGxC;IAEA,OAAO;AACT,EAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.tenantField {
|
|
2
|
+
&__wrapper {
|
|
3
|
+
margin-top: calc(-.75 * var(--spacing-field));
|
|
4
|
+
margin-bottom: var(--spacing-field);
|
|
5
|
+
width: 25%;
|
|
6
|
+
}
|
|
7
|
+
&__hr {
|
|
8
|
+
width: calc(100% + 2 * var(--gutter-h));
|
|
9
|
+
margin-left: calc(-1 * var(--gutter-h));
|
|
10
|
+
background-color: var(--theme-elevation-100);
|
|
11
|
+
height: 1px;
|
|
12
|
+
margin-bottom: var(--spacing-field);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ViewTypes } from 'payload';
|
|
2
|
+
import './index.scss';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
user?: UserWithTenantsField;
|
|
7
|
-
} & ServerProps;
|
|
8
|
-
export declare const TenantSelector: ({ payload, tenantsCollectionSlug, user }: Args) => Promise<React.JSX.Element>;
|
|
9
|
-
export {};
|
|
4
|
+
export declare const TenantSelector: ({ viewType }: {
|
|
5
|
+
viewType?: ViewTypes;
|
|
6
|
+
}) => React.JSX.Element | null;
|
|
10
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC,OAAO,cAAc,CAAA;AAErB,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,eAAO,MAAM,cAAc,iBAAkB;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,6BAqCpE,CAAA"}
|
|
@@ -1,30 +1,41 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
+
import { SelectInput } from '@payloadcms/ui';
|
|
4
|
+
import './index.scss';
|
|
3
5
|
import React from 'react';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
import { SELECT_ALL } from '../../constants.js';
|
|
7
|
+
import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js';
|
|
8
|
+
export const TenantSelector = ({ viewType })=>{
|
|
9
|
+
const { options, selectedTenantID, setTenant } = useTenantSelection();
|
|
10
|
+
const handleChange = React.useCallback((option)=>{
|
|
11
|
+
if (option && 'value' in option) {
|
|
12
|
+
setTenant({
|
|
13
|
+
id: option.value,
|
|
14
|
+
refresh: true
|
|
15
|
+
});
|
|
16
|
+
} else {
|
|
17
|
+
setTenant({
|
|
18
|
+
id: undefined,
|
|
19
|
+
refresh: true
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}, [
|
|
23
|
+
setTenant
|
|
24
|
+
]);
|
|
25
|
+
if (options.length <= 1) {
|
|
26
|
+
return null;
|
|
23
27
|
}
|
|
24
|
-
return /*#__PURE__*/ _jsx(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
29
|
+
className: "tenant-selector",
|
|
30
|
+
children: /*#__PURE__*/ _jsx(SelectInput, {
|
|
31
|
+
isClearable: viewType === 'list',
|
|
32
|
+
label: "Tenant",
|
|
33
|
+
name: "setTenant",
|
|
34
|
+
onChange: handleChange,
|
|
35
|
+
options: options,
|
|
36
|
+
path: "setTenant",
|
|
37
|
+
value: selectedTenantID ? selectedTenantID === SELECT_ALL ? undefined : String(selectedTenantID) : undefined
|
|
38
|
+
})
|
|
28
39
|
});
|
|
29
40
|
};
|
|
30
41
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/TenantSelector/index.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../src/components/TenantSelector/index.tsx"],"sourcesContent":["'use client'\nimport type { ReactSelectOption } from '@payloadcms/ui'\nimport type { ViewTypes } from 'payload'\n\nimport { SelectInput } from '@payloadcms/ui'\n\nimport './index.scss'\n\nimport React from 'react'\n\nimport { SELECT_ALL } from '../../constants.js'\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\n\nexport const TenantSelector = ({ viewType }: { viewType?: ViewTypes }) => {\n const { options, selectedTenantID, setTenant } = useTenantSelection()\n\n const handleChange = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[]) => {\n if (option && 'value' in option) {\n setTenant({ id: option.value as string, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n },\n [setTenant],\n )\n\n if (options.length <= 1) {\n return null\n }\n\n return (\n <div className=\"tenant-selector\">\n <SelectInput\n isClearable={viewType === 'list'}\n label=\"Tenant\"\n name=\"setTenant\"\n onChange={handleChange}\n options={options}\n path=\"setTenant\"\n value={\n selectedTenantID\n ? selectedTenantID === SELECT_ALL\n ? undefined\n : String(selectedTenantID)\n : undefined\n }\n />\n </div>\n )\n}\n"],"names":["SelectInput","React","SELECT_ALL","useTenantSelection","TenantSelector","viewType","options","selectedTenantID","setTenant","handleChange","useCallback","option","id","value","refresh","undefined","length","div","className","isClearable","label","name","onChange","path","String"],"mappings":"AAAA;;AAIA,SAASA,WAAW,QAAQ,iBAAgB;AAE5C,OAAO,eAAc;AAErB,OAAOC,WAAW,QAAO;AAEzB,SAASC,UAAU,QAAQ,qBAAoB;AAC/C,SAASC,kBAAkB,QAAQ,0DAAyD;AAE5F,OAAO,MAAMC,iBAAiB,CAAC,EAAEC,QAAQ,EAA4B;IACnE,MAAM,EAAEC,OAAO,EAAEC,gBAAgB,EAAEC,SAAS,EAAE,GAAGL;IAEjD,MAAMM,eAAeR,MAAMS,WAAW,CACpC,CAACC;QACC,IAAIA,UAAU,WAAWA,QAAQ;YAC/BH,UAAU;gBAAEI,IAAID,OAAOE,KAAK;gBAAYC,SAAS;YAAK;QACxD,OAAO;YACLN,UAAU;gBAAEI,IAAIG;gBAAWD,SAAS;YAAK;QAC3C;IACF,GACA;QAACN;KAAU;IAGb,IAAIF,QAAQU,MAAM,IAAI,GAAG;QACvB,OAAO;IACT;IAEA,qBACE,KAACC;QAAIC,WAAU;kBACb,cAAA,KAAClB;YACCmB,aAAad,aAAa;YAC1Be,OAAM;YACNC,MAAK;YACLC,UAAUb;YACVH,SAASA;YACTiB,MAAK;YACLV,OACEN,mBACIA,qBAAqBL,aACnBa,YACAS,OAAOjB,oBACTQ;;;AAKd,EAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,UAAU,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["// The tenant cookie can be set to _ALL_ to allow users to see all results for tenants they are a member of.\nexport const SELECT_ALL = '_ALL_'\n"],"names":["SELECT_ALL"],"mappings":"AAAA,4GAA4G;AAC5G,OAAO,MAAMA,aAAa,QAAO"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { TenantField } from '../components/TenantField/index.client.js'\nexport { TenantSelector } from '../components/TenantSelector/index.js'\n"],"names":["TenantField","TenantSelector"],"mappings":"AAAA,SAASA,WAAW,QAAQ,4CAA2C;AACvE,SAASC,cAAc,QAAQ,wCAAuC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/exports/fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/fields.ts"],"sourcesContent":["export { tenantField } from '../fields/tenantField/index.js'\nexport { tenantsArrayField } from '../fields/tenantsArrayField/index.js'\n"],"names":["tenantField","tenantsArrayField"],"mappings":"AAAA,SAASA,WAAW,QAAQ,iCAAgC;AAC5D,SAASC,iBAAiB,QAAQ,uCAAsC"}
|
package/dist/exports/rsc.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { GlobalViewRedirect } from '../components/GlobalViewRedirect/index.js';
|
|
2
|
-
export {
|
|
3
|
-
export { TenantSelector } from '../components/TenantSelector/index.js';
|
|
2
|
+
export { TenantSelectionProvider } from '../providers/TenantSelectionProvider/index.js';
|
|
4
3
|
//# sourceMappingURL=rsc.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAC9E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAA"}
|
package/dist/exports/rsc.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { GlobalViewRedirect } from '../components/GlobalViewRedirect/index.js';
|
|
2
|
-
export {
|
|
3
|
-
export { TenantSelector } from '../components/TenantSelector/index.js';
|
|
2
|
+
export { TenantSelectionProvider } from '../providers/TenantSelectionProvider/index.js';
|
|
4
3
|
|
|
5
4
|
//# sourceMappingURL=rsc.js.map
|