@payloadcms/plugin-multi-tenant 0.0.1
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/LICENSE.md +22 -0
- package/README.md +204 -0
- package/dist/components/GlobalViewRedirect/index.d.ts +10 -0
- package/dist/components/GlobalViewRedirect/index.d.ts.map +1 -0
- package/dist/components/GlobalViewRedirect/index.js +18 -0
- package/dist/components/GlobalViewRedirect/index.js.map +1 -0
- package/dist/components/TenantField/index.client.d.ts +10 -0
- package/dist/components/TenantField/index.client.d.ts.map +1 -0
- package/dist/components/TenantField/index.client.js +34 -0
- package/dist/components/TenantField/index.client.js.map +1 -0
- package/dist/components/TenantField/index.d.ts +3 -0
- package/dist/components/TenantField/index.d.ts.map +1 -0
- package/dist/components/TenantField/index.js +33 -0
- package/dist/components/TenantField/index.js.map +1 -0
- package/dist/components/TenantSelector/index.client.d.ts +11 -0
- package/dist/components/TenantSelector/index.client.d.ts.map +1 -0
- package/dist/components/TenantSelector/index.client.js +61 -0
- package/dist/components/TenantSelector/index.client.js.map +1 -0
- package/dist/components/TenantSelector/index.d.ts +10 -0
- package/dist/components/TenantSelector/index.d.ts.map +1 -0
- package/dist/components/TenantSelector/index.js +31 -0
- package/dist/components/TenantSelector/index.js.map +1 -0
- package/dist/components/TenantSelector/index.scss +4 -0
- package/dist/exports/rsc.d.ts +4 -0
- package/dist/exports/rsc.d.ts.map +1 -0
- package/dist/exports/rsc.js +5 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/exports/types.d.ts +2 -0
- package/dist/exports/types.d.ts.map +1 -0
- package/dist/exports/types.js +3 -0
- package/dist/exports/types.js.map +1 -0
- package/dist/exports/utilities.d.ts +6 -0
- package/dist/exports/utilities.d.ts.map +1 -0
- package/dist/exports/utilities.js +7 -0
- package/dist/exports/utilities.js.map +1 -0
- package/dist/fields/tenantField/index.d.ts +12 -0
- package/dist/fields/tenantField/index.d.ts.map +1 -0
- package/dist/fields/tenantField/index.js +38 -0
- package/dist/fields/tenantField/index.js.map +1 -0
- package/dist/fields/userTenantsArrayField/index.d.ts +4 -0
- package/dist/fields/userTenantsArrayField/index.d.ts.map +1 -0
- package/dist/fields/userTenantsArrayField/index.js +20 -0
- package/dist/fields/userTenantsArrayField/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities/combineWhereConstraints.d.ts +3 -0
- package/dist/utilities/combineWhereConstraints.d.ts.map +1 -0
- package/dist/utilities/combineWhereConstraints.js +19 -0
- package/dist/utilities/combineWhereConstraints.js.map +1 -0
- package/dist/utilities/extractID.d.ts +3 -0
- package/dist/utilities/extractID.d.ts.map +1 -0
- package/dist/utilities/extractID.js +8 -0
- package/dist/utilities/extractID.js.map +1 -0
- package/dist/utilities/getGlobalViewRedirect.d.ts +10 -0
- package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -0
- package/dist/utilities/getGlobalViewRedirect.js +44 -0
- package/dist/utilities/getGlobalViewRedirect.js.map +1 -0
- package/dist/utilities/getTenantAccess.d.ts +5 -0
- package/dist/utilities/getTenantAccess.d.ts.map +1 -0
- package/dist/utilities/getTenantAccess.js +14 -0
- package/dist/utilities/getTenantAccess.js.map +1 -0
- package/dist/utilities/getTenantFromCookie.d.ts +2 -0
- package/dist/utilities/getTenantFromCookie.d.ts.map +1 -0
- package/dist/utilities/getTenantFromCookie.js +8 -0
- package/dist/utilities/getTenantFromCookie.js.map +1 -0
- package/dist/utilities/getTenantListFilter.d.ts +8 -0
- package/dist/utilities/getTenantListFilter.d.ts.map +1 -0
- package/dist/utilities/getTenantListFilter.js +15 -0
- package/dist/utilities/getTenantListFilter.js.map +1 -0
- package/dist/utilities/getUserTenantIDs.d.ts +9 -0
- package/dist/utilities/getUserTenantIDs.d.ts.map +1 -0
- package/dist/utilities/getUserTenantIDs.js +22 -0
- package/dist/utilities/getUserTenantIDs.js.map +1 -0
- package/dist/utilities/withTenantAccess.d.ts +9 -0
- package/dist/utilities/withTenantAccess.d.ts.map +1 -0
- package/dist/utilities/withTenantAccess.js +26 -0
- package/dist/utilities/withTenantAccess.js.map +1 -0
- package/dist/utilities/withTenantListFilter.d.ts +13 -0
- package/dist/utilities/withTenantListFilter.d.ts.map +1 -0
- package/dist/utilities/withTenantListFilter.js +36 -0
- package/dist/utilities/withTenantListFilter.js.map +1 -0
- package/package.json +79 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018-2024 Payload CMS, Inc. <info@payloadcms.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Multi Tenant Plugin
|
|
2
|
+
|
|
3
|
+
A plugin for [Payload](https://github.com/payloadcms/payload) to easily manage multiple tenants from within your admin panel.
|
|
4
|
+
|
|
5
|
+
- [Source code](https://github.com/payloadcms/payload/tree/main/packages/plugin-multi-tenant)
|
|
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
|
+
|
|
9
|
+
## Plugin config example
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
multiTenantPlugin({
|
|
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,
|
|
26
|
+
/**
|
|
27
|
+
* The slug of the tenants collection you added to your config
|
|
28
|
+
*
|
|
29
|
+
* optional - @default 'tenants'
|
|
30
|
+
*/
|
|
31
|
+
tenantsSlug: 'tenants',
|
|
32
|
+
/**
|
|
33
|
+
* Define what collections you would like multi-tenancy to apply to
|
|
34
|
+
*
|
|
35
|
+
* Keyed on the slug of the collection
|
|
36
|
+
*/
|
|
37
|
+
collections: {
|
|
38
|
+
pages: {
|
|
39
|
+
/**
|
|
40
|
+
* Used to opt out of using the provided baseListFilter
|
|
41
|
+
*
|
|
42
|
+
* You can use the exported utility "getTenantFilter" within your own list filter
|
|
43
|
+
*
|
|
44
|
+
* optional - @default true
|
|
45
|
+
*/
|
|
46
|
+
useBaseListFilter: true
|
|
47
|
+
/**
|
|
48
|
+
* Used to opt out of the merged access control provided
|
|
49
|
+
*
|
|
50
|
+
* You can use the exported utility "getTenantAccess" within your access control functions
|
|
51
|
+
*
|
|
52
|
+
* optional - @default true
|
|
53
|
+
*/
|
|
54
|
+
useTenantAccess: true
|
|
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
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Name of the field
|
|
74
|
+
*
|
|
75
|
+
* optional - @default true
|
|
76
|
+
*/
|
|
77
|
+
name: 'tenant',
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Function that allows you to determine if certain users should have access to all tenants
|
|
81
|
+
*
|
|
82
|
+
* optional - @default () => false
|
|
83
|
+
*/
|
|
84
|
+
userHasAccessToAllTenants: (user) => user.isSuperAdmin === true
|
|
85
|
+
/**
|
|
86
|
+
* Options for the array field that gets added to the users collection.
|
|
87
|
+
*
|
|
88
|
+
* The field is an array of rows, by default each row has a relationship to a tenant
|
|
89
|
+
*
|
|
90
|
+
* optional - @default undefined
|
|
91
|
+
*/
|
|
92
|
+
userTenantsField: {
|
|
93
|
+
/**
|
|
94
|
+
* Allows you to set access control on the array field
|
|
95
|
+
*
|
|
96
|
+
* optional - @default undefined
|
|
97
|
+
*/
|
|
98
|
+
access: {
|
|
99
|
+
create, // optional
|
|
100
|
+
read, // optional
|
|
101
|
+
update, // optional
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* If you want to add additional fields to the tenant rows, you can specify them under rowFields
|
|
105
|
+
*
|
|
106
|
+
* optional - @default undefined
|
|
107
|
+
*/
|
|
108
|
+
rowFields: [
|
|
109
|
+
// Example adding a field onto the array row
|
|
110
|
+
{
|
|
111
|
+
name: 'roles',
|
|
112
|
+
type: 'select',
|
|
113
|
+
options: [
|
|
114
|
+
{ label: 'Admin', value: 'admin' },
|
|
115
|
+
{ label: 'User', value: 'user' },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### How to configure Collections as Globals for multi-tenant
|
|
125
|
+
|
|
126
|
+
When using multi-tenant, globals need to actually be configured as collections so the content can be specific per tenant.
|
|
127
|
+
To do that, you can mark a collection with `isGlobal` and it will behave like a global and users will not see the list view.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
multiTenantPlugin({
|
|
131
|
+
collections: {
|
|
132
|
+
navigation: {
|
|
133
|
+
isGlobal: true,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Customizing access control
|
|
140
|
+
|
|
141
|
+
In some cases, the access control supplied out of the box may be too strict. For example, if you need _some_ documents to be shared between tenants, you will need to opt out of the supplied access control functionality.
|
|
142
|
+
|
|
143
|
+
By default this plugin merges your access control result with a constraint based on tenants the user has access to within an _AND_ condition. That would not work for the above scenario.
|
|
144
|
+
|
|
145
|
+
In the multi-tenant plugin config you can set `useTenantAccess` to false:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
// File: payload.config.ts
|
|
149
|
+
|
|
150
|
+
import { buildConfig } from 'payload'
|
|
151
|
+
import { multiTenantPlugin } from '@payloadcms/plugin-multi-tenant'
|
|
152
|
+
import { getTenantAccess } from '@payloadcms/plugin-multi-tenant/utilities'
|
|
153
|
+
import { Config as ConfigTypes } from './payload-types'
|
|
154
|
+
|
|
155
|
+
// Add the plugin to your payload config
|
|
156
|
+
export default buildConfig({
|
|
157
|
+
plugins: [
|
|
158
|
+
multiTenantPlugin({
|
|
159
|
+
collections: {
|
|
160
|
+
media: {
|
|
161
|
+
useTenantAccess: false,
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}),
|
|
165
|
+
],
|
|
166
|
+
collections: [
|
|
167
|
+
{
|
|
168
|
+
slug: 'media',
|
|
169
|
+
fields: [
|
|
170
|
+
{
|
|
171
|
+
name: 'isShared',
|
|
172
|
+
type: 'checkbox',
|
|
173
|
+
defaultValue: false,
|
|
174
|
+
// you likely want to set access control on fields like this
|
|
175
|
+
// to prevent just any user from modifying it
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
access: {
|
|
179
|
+
read: ({ req, doc }) => {
|
|
180
|
+
if (!req.user) return false
|
|
181
|
+
|
|
182
|
+
const whereConstraint = {
|
|
183
|
+
or: [
|
|
184
|
+
{
|
|
185
|
+
isShared: {
|
|
186
|
+
equals: true,
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const tenantAccessResult = getTenantAccess({ user: req.user })
|
|
193
|
+
|
|
194
|
+
if (tenantAccessResult) {
|
|
195
|
+
whereConstraint.or.push(tenantAccessResult)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return whereConstraint
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
})
|
|
204
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CollectionSlug, ServerProps } from 'payload';
|
|
2
|
+
type Args = {
|
|
3
|
+
collectionSlug: CollectionSlug;
|
|
4
|
+
docID?: number | string;
|
|
5
|
+
globalSlugs: string[];
|
|
6
|
+
viewType: 'edit' | 'list';
|
|
7
|
+
} & ServerProps;
|
|
8
|
+
export declare const GlobalViewRedirect: (args: Args) => Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;AAM1D,KAAK,IAAI,GAAG;IACV,cAAc,EAAE,cAAc,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B,GAAG,WAAW,CAAA;AAEf,eAAO,MAAM,kBAAkB,SAAgB,IAAI,kBAelD,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { redirect } from 'next/navigation.js';
|
|
2
|
+
import { getGlobalViewRedirect } from '../../utilities/getGlobalViewRedirect.js';
|
|
3
|
+
export const GlobalViewRedirect = async (args)=>{
|
|
4
|
+
const collectionSlug = args?.collectionSlug;
|
|
5
|
+
if (collectionSlug && args.globalSlugs?.includes(collectionSlug)) {
|
|
6
|
+
const redirectRoute = await getGlobalViewRedirect({
|
|
7
|
+
slug: collectionSlug,
|
|
8
|
+
docID: args.docID,
|
|
9
|
+
payload: args.payload,
|
|
10
|
+
view: args.viewType
|
|
11
|
+
});
|
|
12
|
+
if (redirectRoute) {
|
|
13
|
+
redirect(redirectRoute);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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: 'edit' | 'list'\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 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","view","viewType"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,qBAAoB;AAE7C,SAASC,qBAAqB,QAAQ,2CAA0C;AAShF,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,MAAMR,KAAKS,QAAQ;QACrB;QAEA,IAAIL,eAAe;YACjBP,SAASO;QACX;IACF;AACF,EAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RelationshipFieldClientProps } from 'payload';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
type Props = {
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
serverValue?: number | string;
|
|
6
|
+
tenantsCollectionSlug: string;
|
|
7
|
+
} & RelationshipFieldClientProps;
|
|
8
|
+
export declare const TenantFieldClient: (args: Props) => React.JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=index.client.d.ts.map
|
|
@@ -0,0 +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;AAEzB,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC7B,qBAAqB,EAAE,MAAM,CAAA;CAC9B,GAAG,4BAA4B,CAAA;AAEhC,eAAO,MAAM,iBAAiB,SAAU,KAAK,sBA2B5C,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { RelationshipField, useField } from '@payloadcms/ui';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
export const TenantFieldClient = (args)=>{
|
|
6
|
+
const { path, serverValue } = args;
|
|
7
|
+
const { setValue, value } = useField({
|
|
8
|
+
path
|
|
9
|
+
});
|
|
10
|
+
React.useEffect(()=>{
|
|
11
|
+
if (serverValue && value !== serverValue) {
|
|
12
|
+
setValue(serverValue);
|
|
13
|
+
}
|
|
14
|
+
}, [
|
|
15
|
+
serverValue,
|
|
16
|
+
setValue,
|
|
17
|
+
value
|
|
18
|
+
]);
|
|
19
|
+
if (args.debug) {
|
|
20
|
+
return /*#__PURE__*/ _jsx(RelationshipField, {
|
|
21
|
+
field: {
|
|
22
|
+
name: path,
|
|
23
|
+
type: 'relationship',
|
|
24
|
+
label: 'Tenant',
|
|
25
|
+
relationTo: args.tenantsCollectionSlug,
|
|
26
|
+
required: true
|
|
27
|
+
},
|
|
28
|
+
path: path
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=index.client.js.map
|
|
@@ -0,0 +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 serverValue?: number | string\n tenantsCollectionSlug: string\n} & RelationshipFieldClientProps\n\nexport const TenantFieldClient = (args: Props) => {\n const { path, serverValue } = args\n\n const { setValue, value } = useField({ path })\n\n React.useEffect(() => {\n if (serverValue && value !== serverValue) {\n setValue(serverValue)\n }\n }, [serverValue, setValue, value])\n\n if (args.debug) {\n return (\n <RelationshipField\n field={{\n name: path,\n type: 'relationship',\n label: 'Tenant',\n relationTo: args.tenantsCollectionSlug,\n required: true,\n }}\n path={path}\n />\n )\n }\n\n return null\n}\n"],"names":["RelationshipField","useField","React","TenantFieldClient","args","path","serverValue","setValue","value","useEffect","debug","field","name","type","label","relationTo","tenantsCollectionSlug","required"],"mappings":"AAAA;;AAIA,SAASA,iBAAiB,EAAEC,QAAQ,QAAQ,iBAAgB;AAC5D,OAAOC,WAAW,QAAO;AAQzB,OAAO,MAAMC,oBAAoB,CAACC;IAChC,MAAM,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGF;IAE9B,MAAM,EAAEG,QAAQ,EAAEC,KAAK,EAAE,GAAGP,SAAS;QAAEI;IAAK;IAE5CH,MAAMO,SAAS,CAAC;QACd,IAAIH,eAAeE,UAAUF,aAAa;YACxCC,SAASD;QACX;IACF,GAAG;QAACA;QAAaC;QAAUC;KAAM;IAEjC,IAAIJ,KAAKM,KAAK,EAAE;QACd,qBACE,KAACV;YACCW,OAAO;gBACLC,MAAMP;gBACNQ,MAAM;gBACNC,OAAO;gBACPC,YAAYX,KAAKY,qBAAqB;gBACtCC,UAAU;YACZ;YACAZ,MAAMA;;IAGZ;IAEA,OAAO;AACT,EAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantField/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAazB,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAwC/B,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js';
|
|
4
|
+
import { getUserTenantIDs } from '../../utilities/getUserTenantIDs.js';
|
|
5
|
+
import { TenantFieldClient } from './index.client.js';
|
|
6
|
+
export const TenantField = async ({ clientField, debug, path, payload, readOnly, req, tenantsCollectionSlug, user })=>{
|
|
7
|
+
let serverValue = getTenantFromCookie(req.headers, payload.db.defaultIDType) || getUserTenantIDs(user)?.[0];
|
|
8
|
+
if (serverValue) {
|
|
9
|
+
try {
|
|
10
|
+
// validate that the tenant exists
|
|
11
|
+
const doc = await payload.findByID({
|
|
12
|
+
id: serverValue,
|
|
13
|
+
collection: tenantsCollectionSlug,
|
|
14
|
+
depth: 0
|
|
15
|
+
});
|
|
16
|
+
if (!doc) {
|
|
17
|
+
serverValue = undefined;
|
|
18
|
+
}
|
|
19
|
+
} catch (_) {
|
|
20
|
+
serverValue = undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return /*#__PURE__*/ _jsx(TenantFieldClient, {
|
|
24
|
+
debug: debug,
|
|
25
|
+
field: clientField,
|
|
26
|
+
path: path,
|
|
27
|
+
readOnly: readOnly,
|
|
28
|
+
serverValue: serverValue,
|
|
29
|
+
tenantsCollectionSlug: tenantsCollectionSlug
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/TenantField/index.tsx"],"sourcesContent":["import type { RelationshipFieldServerProps } from 'payload'\n\nimport React from 'react'\n\nimport type { UserWithTenantsField } from '../../types.js'\n\nimport { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js'\nimport { getUserTenantIDs } from '../../utilities/getUserTenantIDs.js'\nimport { TenantFieldClient } from './index.client.js'\n\ntype Props = {\n debug?: boolean\n tenantsCollectionSlug: string\n} & RelationshipFieldServerProps\n\nexport const TenantField: React.FC = async ({\n clientField,\n debug,\n path,\n payload,\n readOnly,\n req,\n tenantsCollectionSlug,\n user,\n}: Props) => {\n let serverValue: number | string | undefined =\n getTenantFromCookie(req.headers, payload.db.defaultIDType) ||\n getUserTenantIDs(user as UserWithTenantsField)?.[0]\n\n if (serverValue) {\n try {\n // validate that the tenant exists\n const doc = await payload.findByID({\n id: serverValue,\n collection: tenantsCollectionSlug,\n depth: 0,\n })\n if (!doc) {\n serverValue = undefined\n }\n } catch (_) {\n serverValue = undefined\n }\n }\n\n return (\n <TenantFieldClient\n debug={debug}\n field={clientField}\n path={path}\n readOnly={readOnly}\n serverValue={serverValue}\n tenantsCollectionSlug={tenantsCollectionSlug}\n />\n )\n}\n"],"names":["React","getTenantFromCookie","getUserTenantIDs","TenantFieldClient","TenantField","clientField","debug","path","payload","readOnly","req","tenantsCollectionSlug","user","serverValue","headers","db","defaultIDType","doc","findByID","id","collection","depth","undefined","_","field"],"mappings":";AAEA,OAAOA,WAAW,QAAO;AAIzB,SAASC,mBAAmB,QAAQ,yCAAwC;AAC5E,SAASC,gBAAgB,QAAQ,sCAAqC;AACtE,SAASC,iBAAiB,QAAQ,oBAAmB;AAOrD,OAAO,MAAMC,cAAwB,OAAO,EAC1CC,WAAW,EACXC,KAAK,EACLC,IAAI,EACJC,OAAO,EACPC,QAAQ,EACRC,GAAG,EACHC,qBAAqB,EACrBC,IAAI,EACE;IACN,IAAIC,cACFZ,oBAAoBS,IAAII,OAAO,EAAEN,QAAQO,EAAE,CAACC,aAAa,KACzDd,iBAAiBU,OAA+B,CAAC,EAAE;IAErD,IAAIC,aAAa;QACf,IAAI;YACF,kCAAkC;YAClC,MAAMI,MAAM,MAAMT,QAAQU,QAAQ,CAAC;gBACjCC,IAAIN;gBACJO,YAAYT;gBACZU,OAAO;YACT;YACA,IAAI,CAACJ,KAAK;gBACRJ,cAAcS;YAChB;QACF,EAAE,OAAOC,GAAG;YACVV,cAAcS;QAChB;IACF;IAEA,qBACE,KAACnB;QACCG,OAAOA;QACPkB,OAAOnB;QACPE,MAAMA;QACNE,UAAUA;QACVI,aAAaA;QACbF,uBAAuBA;;AAG7B,EAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './index.scss';
|
|
3
|
+
export declare const TenantSelectorClient: ({ cookieToSet, initialValue, options, }: {
|
|
4
|
+
cookieToSet?: string;
|
|
5
|
+
initialValue?: string;
|
|
6
|
+
options: {
|
|
7
|
+
label: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}[];
|
|
10
|
+
}) => React.JSX.Element;
|
|
11
|
+
//# sourceMappingURL=index.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.client.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,cAAc,CAAA;AAMrB,eAAO,MAAM,oBAAoB,4CAI9B;IACD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,CAAA;KACd,EAAE,CAAA;CACJ,sBAsDA,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { SelectInput } from '@payloadcms/ui';
|
|
4
|
+
import { useRouter } from 'next/navigation.js';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import './index.scss';
|
|
7
|
+
function findValue(options, value) {
|
|
8
|
+
return options.find((opt)=>opt.value === value)?.value;
|
|
9
|
+
}
|
|
10
|
+
export const TenantSelectorClient = ({ cookieToSet, initialValue, options })=>{
|
|
11
|
+
const [value, setValue] = React.useState(()=>{
|
|
12
|
+
if (initialValue) {
|
|
13
|
+
return findValue(options, initialValue);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const router = useRouter();
|
|
17
|
+
const setCookieAndReload = React.useCallback((value)=>{
|
|
18
|
+
const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT';
|
|
19
|
+
document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/';
|
|
20
|
+
setValue(value);
|
|
21
|
+
router.refresh();
|
|
22
|
+
}, [
|
|
23
|
+
router
|
|
24
|
+
]);
|
|
25
|
+
const handleChange = React.useCallback((option)=>{
|
|
26
|
+
if (!option) {
|
|
27
|
+
setCookieAndReload(undefined);
|
|
28
|
+
} else if ('value' in option) {
|
|
29
|
+
setCookieAndReload(option.value);
|
|
30
|
+
}
|
|
31
|
+
}, [
|
|
32
|
+
setCookieAndReload
|
|
33
|
+
]);
|
|
34
|
+
React.useEffect(()=>{
|
|
35
|
+
if (cookieToSet) {
|
|
36
|
+
setCookieAndReload(findValue(options, cookieToSet));
|
|
37
|
+
}
|
|
38
|
+
}, [
|
|
39
|
+
cookieToSet,
|
|
40
|
+
options,
|
|
41
|
+
setCookieAndReload
|
|
42
|
+
]);
|
|
43
|
+
if (options.length <= 1) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
47
|
+
className: "tenant-selector",
|
|
48
|
+
children: /*#__PURE__*/ _jsx(SelectInput, {
|
|
49
|
+
isClearable: false,
|
|
50
|
+
label: "Select a tenant",
|
|
51
|
+
name: "setTenant",
|
|
52
|
+
onChange: handleChange,
|
|
53
|
+
options: options,
|
|
54
|
+
path: "setTenant",
|
|
55
|
+
readOnly: !value,
|
|
56
|
+
value: value
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=index.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/TenantSelector/index.client.tsx"],"sourcesContent":["'use client'\nimport type { ReactSelectOption } from '@payloadcms/ui'\n\nimport { SelectInput } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React from 'react'\n\nimport './index.scss'\n\nfunction findValue(options: { label: string; value: string }[], value?: string) {\n return options.find((opt) => opt.value === value)?.value\n}\n\nexport const TenantSelectorClient = ({\n cookieToSet,\n initialValue,\n options,\n}: {\n cookieToSet?: string\n initialValue?: string\n options: {\n label: string\n value: string\n }[]\n}) => {\n const [value, setValue] = React.useState<string | undefined>(() => {\n if (initialValue) {\n return findValue(options, initialValue)\n }\n })\n\n const router = useRouter()\n\n const setCookieAndReload = React.useCallback(\n (value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n setValue(value)\n router.refresh()\n },\n [router],\n )\n\n const handleChange = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[]) => {\n if (!option) {\n setCookieAndReload(undefined)\n } else if ('value' in option) {\n setCookieAndReload(option.value as string)\n }\n },\n [setCookieAndReload],\n )\n\n React.useEffect(() => {\n if (cookieToSet) {\n setCookieAndReload(findValue(options, cookieToSet))\n }\n }, [cookieToSet, options, setCookieAndReload])\n\n if (options.length <= 1) {\n return null\n }\n\n return (\n <div className=\"tenant-selector\">\n <SelectInput\n isClearable={false}\n label=\"Select a tenant\"\n name=\"setTenant\"\n onChange={handleChange}\n options={options}\n path=\"setTenant\"\n readOnly={!value}\n value={value}\n />\n </div>\n )\n}\n"],"names":["SelectInput","useRouter","React","findValue","options","value","find","opt","TenantSelectorClient","cookieToSet","initialValue","setValue","useState","router","setCookieAndReload","useCallback","expires","document","cookie","refresh","handleChange","option","undefined","useEffect","length","div","className","isClearable","label","name","onChange","path","readOnly"],"mappings":"AAAA;;AAGA,SAASA,WAAW,QAAQ,iBAAgB;AAC5C,SAASC,SAAS,QAAQ,qBAAoB;AAC9C,OAAOC,WAAW,QAAO;AAEzB,OAAO,eAAc;AAErB,SAASC,UAAUC,OAA2C,EAAEC,KAAc;IAC5E,OAAOD,QAAQE,IAAI,CAAC,CAACC,MAAQA,IAAIF,KAAK,KAAKA,QAAQA;AACrD;AAEA,OAAO,MAAMG,uBAAuB,CAAC,EACnCC,WAAW,EACXC,YAAY,EACZN,OAAO,EAQR;IACC,MAAM,CAACC,OAAOM,SAAS,GAAGT,MAAMU,QAAQ,CAAqB;QAC3D,IAAIF,cAAc;YAChB,OAAOP,UAAUC,SAASM;QAC5B;IACF;IAEA,MAAMG,SAASZ;IAEf,MAAMa,qBAAqBZ,MAAMa,WAAW,CAC1C,CAACV;QACC,MAAMW,UAAU;QAChBC,SAASC,MAAM,GAAG,oBAAqBb,CAAAA,SAAS,EAAC,IAAKW,UAAU;QAChEL,SAASN;QACTQ,OAAOM,OAAO;IAChB,GACA;QAACN;KAAO;IAGV,MAAMO,eAAelB,MAAMa,WAAW,CACpC,CAACM;QACC,IAAI,CAACA,QAAQ;YACXP,mBAAmBQ;QACrB,OAAO,IAAI,WAAWD,QAAQ;YAC5BP,mBAAmBO,OAAOhB,KAAK;QACjC;IACF,GACA;QAACS;KAAmB;IAGtBZ,MAAMqB,SAAS,CAAC;QACd,IAAId,aAAa;YACfK,mBAAmBX,UAAUC,SAASK;QACxC;IACF,GAAG;QAACA;QAAaL;QAASU;KAAmB;IAE7C,IAAIV,QAAQoB,MAAM,IAAI,GAAG;QACvB,OAAO;IACT;IAEA,qBACE,KAACC;QAAIC,WAAU;kBACb,cAAA,KAAC1B;YACC2B,aAAa;YACbC,OAAM;YACNC,MAAK;YACLC,UAAUV;YACVhB,SAASA;YACT2B,MAAK;YACLC,UAAU,CAAC3B;YACXA,OAAOA;;;AAIf,EAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ServerProps } from 'payload';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { MultiTenantPluginConfig, UserWithTenantsField } from '../../types.js';
|
|
4
|
+
type Args = {
|
|
5
|
+
tenantsCollectionSlug: MultiTenantPluginConfig['tenantsSlug'];
|
|
6
|
+
user?: UserWithTenantsField;
|
|
7
|
+
} & ServerProps;
|
|
8
|
+
export declare const TenantSelector: ({ payload, tenantsCollectionSlug, user }: Args) => Promise<React.JSX.Element>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TenantSelector/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,uBAAuB,EAAU,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAI3F,KAAK,IAAI,GAAG;IACV,qBAAqB,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAA;IAC7D,IAAI,CAAC,EAAE,oBAAoB,CAAA;CAC5B,GAAG,WAAW,CAAA;AAEf,eAAO,MAAM,cAAc,6CAAoD,IAAI,+BAgClF,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cookies as getCookies } from 'next/headers.js';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { TenantSelectorClient } from './index.client.js';
|
|
5
|
+
export const TenantSelector = async ({ payload, tenantsCollectionSlug, user })=>{
|
|
6
|
+
const { docs: userTenants } = await payload.find({
|
|
7
|
+
collection: tenantsCollectionSlug,
|
|
8
|
+
depth: 0,
|
|
9
|
+
limit: 1000,
|
|
10
|
+
overrideAccess: false,
|
|
11
|
+
sort: 'name',
|
|
12
|
+
user
|
|
13
|
+
});
|
|
14
|
+
const tenantOptions = userTenants.map((doc)=>({
|
|
15
|
+
label: doc.name,
|
|
16
|
+
value: String(doc.id)
|
|
17
|
+
}));
|
|
18
|
+
let cookieToSet;
|
|
19
|
+
const cookies = await getCookies();
|
|
20
|
+
const selectedTenant = tenantOptions.find((tenant)=>tenant.value === cookies.get('payload-tenant')?.value)?.value;
|
|
21
|
+
if (!selectedTenant && userTenants.length > 0) {
|
|
22
|
+
cookieToSet = String(userTenants[0].id);
|
|
23
|
+
}
|
|
24
|
+
return /*#__PURE__*/ _jsx(TenantSelectorClient, {
|
|
25
|
+
cookieToSet: cookieToSet,
|
|
26
|
+
initialValue: selectedTenant,
|
|
27
|
+
options: tenantOptions
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/TenantSelector/index.tsx"],"sourcesContent":["import type { ServerProps } from 'payload'\n\nimport { cookies as getCookies } from 'next/headers.js'\nimport React from 'react'\n\nimport type { MultiTenantPluginConfig, Tenant, UserWithTenantsField } from '../../types.js'\n\nimport { TenantSelectorClient } from './index.client.js'\n\ntype Args = {\n tenantsCollectionSlug: MultiTenantPluginConfig['tenantsSlug']\n user?: UserWithTenantsField\n} & ServerProps\n\nexport const TenantSelector = async ({ payload, tenantsCollectionSlug, user }: Args) => {\n const { docs: userTenants } = await payload.find({\n collection: tenantsCollectionSlug,\n depth: 0,\n limit: 1000,\n overrideAccess: false,\n sort: 'name',\n user,\n })\n\n const tenantOptions = userTenants.map((doc: Tenant) => ({\n label: doc.name,\n value: String(doc.id),\n }))\n\n let cookieToSet: string | undefined\n const cookies = await getCookies()\n const selectedTenant = tenantOptions.find(\n (tenant) => tenant.value === cookies.get('payload-tenant')?.value,\n )?.value\n\n if (!selectedTenant && userTenants.length > 0) {\n cookieToSet = String(userTenants[0].id)\n }\n\n return (\n <TenantSelectorClient\n cookieToSet={cookieToSet}\n initialValue={selectedTenant}\n options={tenantOptions}\n />\n )\n}\n"],"names":["cookies","getCookies","React","TenantSelectorClient","TenantSelector","payload","tenantsCollectionSlug","user","docs","userTenants","find","collection","depth","limit","overrideAccess","sort","tenantOptions","map","doc","label","name","value","String","id","cookieToSet","selectedTenant","tenant","get","length","initialValue","options"],"mappings":";AAEA,SAASA,WAAWC,UAAU,QAAQ,kBAAiB;AACvD,OAAOC,WAAW,QAAO;AAIzB,SAASC,oBAAoB,QAAQ,oBAAmB;AAOxD,OAAO,MAAMC,iBAAiB,OAAO,EAAEC,OAAO,EAAEC,qBAAqB,EAAEC,IAAI,EAAQ;IACjF,MAAM,EAAEC,MAAMC,WAAW,EAAE,GAAG,MAAMJ,QAAQK,IAAI,CAAC;QAC/CC,YAAYL;QACZM,OAAO;QACPC,OAAO;QACPC,gBAAgB;QAChBC,MAAM;QACNR;IACF;IAEA,MAAMS,gBAAgBP,YAAYQ,GAAG,CAAC,CAACC,MAAiB,CAAA;YACtDC,OAAOD,IAAIE,IAAI;YACfC,OAAOC,OAAOJ,IAAIK,EAAE;QACtB,CAAA;IAEA,IAAIC;IACJ,MAAMxB,UAAU,MAAMC;IACtB,MAAMwB,iBAAiBT,cAAcN,IAAI,CACvC,CAACgB,SAAWA,OAAOL,KAAK,KAAKrB,QAAQ2B,GAAG,CAAC,mBAAmBN,QAC3DA;IAEH,IAAI,CAACI,kBAAkBhB,YAAYmB,MAAM,GAAG,GAAG;QAC7CJ,cAAcF,OAAOb,WAAW,CAAC,EAAE,CAACc,EAAE;IACxC;IAEA,qBACE,KAACpB;QACCqB,aAAaA;QACbK,cAAcJ;QACdK,SAASd;;AAGf,EAAC"}
|
|
@@ -0,0 +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,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { GlobalViewRedirect } from '../components/GlobalViewRedirect/index.js'\nexport { TenantField } from '../components/TenantField/index.js'\nexport { TenantSelector } from '../components/TenantSelector/index.js'\n"],"names":["GlobalViewRedirect","TenantField","TenantSelector"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,4CAA2C;AAC9E,SAASC,WAAW,QAAQ,qCAAoC;AAChE,SAASC,cAAc,QAAQ,wCAAuC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { MultiTenantPluginConfig } from '../types.js'\n"],"names":[],"mappings":"AAAA,WAA0D"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { getGlobalViewRedirect } from '../utilities/getGlobalViewRedirect.js';
|
|
2
|
+
export { getTenantAccess } from '../utilities/getTenantAccess.js';
|
|
3
|
+
export { getTenantFromCookie } from '../utilities/getTenantFromCookie.js';
|
|
4
|
+
export { getTenantListFilter } from '../utilities/getTenantListFilter.js';
|
|
5
|
+
export { getUserTenantIDs } from '../utilities/getUserTenantIDs.js';
|
|
6
|
+
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/exports/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { getGlobalViewRedirect } from '../utilities/getGlobalViewRedirect.js';
|
|
2
|
+
export { getTenantAccess } from '../utilities/getTenantAccess.js';
|
|
3
|
+
export { getTenantFromCookie } from '../utilities/getTenantFromCookie.js';
|
|
4
|
+
export { getTenantListFilter } from '../utilities/getTenantListFilter.js';
|
|
5
|
+
export { getUserTenantIDs } from '../utilities/getUserTenantIDs.js';
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export { getGlobalViewRedirect } from '../utilities/getGlobalViewRedirect.js'\nexport { getTenantAccess } from '../utilities/getTenantAccess.js'\nexport { getTenantFromCookie } from '../utilities/getTenantFromCookie.js'\nexport { getTenantListFilter } from '../utilities/getTenantListFilter.js'\nexport { getUserTenantIDs } from '../utilities/getUserTenantIDs.js'\n"],"names":["getGlobalViewRedirect","getTenantAccess","getTenantFromCookie","getTenantListFilter","getUserTenantIDs"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,wCAAuC;AAC7E,SAASC,eAAe,QAAQ,kCAAiC;AACjE,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,gBAAgB,QAAQ,mCAAkC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RelationshipField } from 'payload';
|
|
2
|
+
import type { MultiTenantPluginConfig } from '../../types.js';
|
|
3
|
+
type Args = {
|
|
4
|
+
access: MultiTenantPluginConfig['documentTenantField']['access'];
|
|
5
|
+
debug?: boolean;
|
|
6
|
+
name: string;
|
|
7
|
+
tenantsCollectionSlug: MultiTenantPluginConfig['tenantsSlug'];
|
|
8
|
+
unique: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const tenantField: ({ name, access, debug, tenantsCollectionSlug, unique, }: Args) => RelationshipField;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/tenantField/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAGhD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAI7D,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,uBAAuB,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,CAAA;IAChE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAA;IAC7D,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AACD,eAAO,MAAM,WAAW,4DAMrB,IAAI,KAAG,iBAiCR,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { APIError } from 'payload';
|
|
2
|
+
import { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js';
|
|
3
|
+
export const tenantField = ({ name, access, debug, tenantsCollectionSlug, unique })=>({
|
|
4
|
+
name,
|
|
5
|
+
type: 'relationship',
|
|
6
|
+
access,
|
|
7
|
+
admin: {
|
|
8
|
+
components: {
|
|
9
|
+
Field: {
|
|
10
|
+
clientProps: {
|
|
11
|
+
debug,
|
|
12
|
+
tenantsCollectionSlug
|
|
13
|
+
},
|
|
14
|
+
path: '@payloadcms/plugin-multi-tenant/rsc#TenantField'
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
position: debug ? 'sidebar' : undefined
|
|
18
|
+
},
|
|
19
|
+
hasMany: false,
|
|
20
|
+
hooks: {
|
|
21
|
+
beforeChange: [
|
|
22
|
+
({ req, value })=>{
|
|
23
|
+
if (!value) {
|
|
24
|
+
const tenantFromCookie = getTenantFromCookie(req.headers, req.payload.db.defaultIDType);
|
|
25
|
+
if (tenantFromCookie) {
|
|
26
|
+
return tenantFromCookie;
|
|
27
|
+
}
|
|
28
|
+
throw new APIError('You must select a tenant', 400, null, true);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
index: true,
|
|
34
|
+
relationTo: tenantsCollectionSlug,
|
|
35
|
+
unique
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=index.js.map
|