@payloadcms/plugin-multi-tenant 3.38.0-internal.78d3ba4 → 3.38.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/dist/components/TenantSelector/index.d.ts.map +1 -1
- package/dist/components/TenantSelector/index.js +83 -15
- package/dist/components/TenantSelector/index.js.map +1 -1
- package/dist/components/WatchTenantCollection/index.d.ts +2 -0
- package/dist/components/WatchTenantCollection/index.d.ts.map +1 -0
- package/dist/components/WatchTenantCollection/index.js +34 -0
- package/dist/components/WatchTenantCollection/index.js.map +1 -0
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +1 -0
- package/dist/exports/client.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.client.d.ts +9 -1
- package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.client.js +24 -4
- package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -1
- package/dist/translations/index.d.ts +6 -0
- package/dist/translations/index.d.ts.map +1 -0
- package/dist/translations/index.js +80 -0
- package/dist/translations/index.js.map +1 -0
- package/dist/translations/languages/ar.d.ts +4 -0
- package/dist/translations/languages/ar.d.ts.map +1 -0
- package/dist/translations/languages/ar.js +12 -0
- package/dist/translations/languages/ar.js.map +1 -0
- package/dist/translations/languages/az.d.ts +4 -0
- package/dist/translations/languages/az.d.ts.map +1 -0
- package/dist/translations/languages/az.js +12 -0
- package/dist/translations/languages/az.js.map +1 -0
- package/dist/translations/languages/bg.d.ts +4 -0
- package/dist/translations/languages/bg.d.ts.map +1 -0
- package/dist/translations/languages/bg.js +12 -0
- package/dist/translations/languages/bg.js.map +1 -0
- package/dist/translations/languages/ca.d.ts +4 -0
- package/dist/translations/languages/ca.d.ts.map +1 -0
- package/dist/translations/languages/ca.js +12 -0
- package/dist/translations/languages/ca.js.map +1 -0
- package/dist/translations/languages/cs.d.ts +4 -0
- package/dist/translations/languages/cs.d.ts.map +1 -0
- package/dist/translations/languages/cs.js +12 -0
- package/dist/translations/languages/cs.js.map +1 -0
- package/dist/translations/languages/da.d.ts +4 -0
- package/dist/translations/languages/da.d.ts.map +1 -0
- package/dist/translations/languages/da.js +12 -0
- package/dist/translations/languages/da.js.map +1 -0
- package/dist/translations/languages/de.d.ts +4 -0
- package/dist/translations/languages/de.d.ts.map +1 -0
- package/dist/translations/languages/de.js +12 -0
- package/dist/translations/languages/de.js.map +1 -0
- package/dist/translations/languages/en.d.ts +9 -0
- package/dist/translations/languages/en.d.ts.map +1 -0
- package/dist/translations/languages/en.js +12 -0
- package/dist/translations/languages/en.js.map +1 -0
- package/dist/translations/languages/es.d.ts +4 -0
- package/dist/translations/languages/es.d.ts.map +1 -0
- package/dist/translations/languages/es.js +12 -0
- package/dist/translations/languages/es.js.map +1 -0
- package/dist/translations/languages/et.d.ts +4 -0
- package/dist/translations/languages/et.d.ts.map +1 -0
- package/dist/translations/languages/et.js +12 -0
- package/dist/translations/languages/et.js.map +1 -0
- package/dist/translations/languages/fa.d.ts +4 -0
- package/dist/translations/languages/fa.d.ts.map +1 -0
- package/dist/translations/languages/fa.js +12 -0
- package/dist/translations/languages/fa.js.map +1 -0
- package/dist/translations/languages/fr.d.ts +4 -0
- package/dist/translations/languages/fr.d.ts.map +1 -0
- package/dist/translations/languages/fr.js +12 -0
- package/dist/translations/languages/fr.js.map +1 -0
- package/dist/translations/languages/he.d.ts +4 -0
- package/dist/translations/languages/he.d.ts.map +1 -0
- package/dist/translations/languages/he.js +12 -0
- package/dist/translations/languages/he.js.map +1 -0
- package/dist/translations/languages/hr.d.ts +4 -0
- package/dist/translations/languages/hr.d.ts.map +1 -0
- package/dist/translations/languages/hr.js +12 -0
- package/dist/translations/languages/hr.js.map +1 -0
- package/dist/translations/languages/hu.d.ts +4 -0
- package/dist/translations/languages/hu.d.ts.map +1 -0
- package/dist/translations/languages/hu.js +12 -0
- package/dist/translations/languages/hu.js.map +1 -0
- package/dist/translations/languages/hy.d.ts +4 -0
- package/dist/translations/languages/hy.d.ts.map +1 -0
- package/dist/translations/languages/hy.js +12 -0
- package/dist/translations/languages/hy.js.map +1 -0
- package/dist/translations/languages/it.d.ts +4 -0
- package/dist/translations/languages/it.d.ts.map +1 -0
- package/dist/translations/languages/it.js +12 -0
- package/dist/translations/languages/it.js.map +1 -0
- package/dist/translations/languages/ja.d.ts +4 -0
- package/dist/translations/languages/ja.d.ts.map +1 -0
- package/dist/translations/languages/ja.js +12 -0
- package/dist/translations/languages/ja.js.map +1 -0
- package/dist/translations/languages/ko.d.ts +4 -0
- package/dist/translations/languages/ko.d.ts.map +1 -0
- package/dist/translations/languages/ko.js +12 -0
- package/dist/translations/languages/ko.js.map +1 -0
- package/dist/translations/languages/lt.d.ts +4 -0
- package/dist/translations/languages/lt.d.ts.map +1 -0
- package/dist/translations/languages/lt.js +12 -0
- package/dist/translations/languages/lt.js.map +1 -0
- package/dist/translations/languages/my.d.ts +4 -0
- package/dist/translations/languages/my.d.ts.map +1 -0
- package/dist/translations/languages/my.js +12 -0
- package/dist/translations/languages/my.js.map +1 -0
- package/dist/translations/languages/nb.d.ts +4 -0
- package/dist/translations/languages/nb.d.ts.map +1 -0
- package/dist/translations/languages/nb.js +12 -0
- package/dist/translations/languages/nb.js.map +1 -0
- package/dist/translations/languages/nl.d.ts +4 -0
- package/dist/translations/languages/nl.d.ts.map +1 -0
- package/dist/translations/languages/nl.js +12 -0
- package/dist/translations/languages/nl.js.map +1 -0
- package/dist/translations/languages/pl.d.ts +4 -0
- package/dist/translations/languages/pl.d.ts.map +1 -0
- package/dist/translations/languages/pl.js +12 -0
- package/dist/translations/languages/pl.js.map +1 -0
- package/dist/translations/languages/pt.d.ts +4 -0
- package/dist/translations/languages/pt.d.ts.map +1 -0
- package/dist/translations/languages/pt.js +12 -0
- package/dist/translations/languages/pt.js.map +1 -0
- package/dist/translations/languages/ro.d.ts +4 -0
- package/dist/translations/languages/ro.d.ts.map +1 -0
- package/dist/translations/languages/ro.js +12 -0
- package/dist/translations/languages/ro.js.map +1 -0
- package/dist/translations/languages/rs.d.ts +4 -0
- package/dist/translations/languages/rs.d.ts.map +1 -0
- package/dist/translations/languages/rs.js +12 -0
- package/dist/translations/languages/rs.js.map +1 -0
- package/dist/translations/languages/rsLatin.d.ts +4 -0
- package/dist/translations/languages/rsLatin.d.ts.map +1 -0
- package/dist/translations/languages/rsLatin.js +12 -0
- package/dist/translations/languages/rsLatin.js.map +1 -0
- package/dist/translations/languages/ru.d.ts +4 -0
- package/dist/translations/languages/ru.d.ts.map +1 -0
- package/dist/translations/languages/ru.js +12 -0
- package/dist/translations/languages/ru.js.map +1 -0
- package/dist/translations/languages/sk.d.ts +4 -0
- package/dist/translations/languages/sk.d.ts.map +1 -0
- package/dist/translations/languages/sk.js +12 -0
- package/dist/translations/languages/sk.js.map +1 -0
- package/dist/translations/languages/sl.d.ts +4 -0
- package/dist/translations/languages/sl.d.ts.map +1 -0
- package/dist/translations/languages/sl.js +12 -0
- package/dist/translations/languages/sl.js.map +1 -0
- package/dist/translations/languages/sv.d.ts +4 -0
- package/dist/translations/languages/sv.d.ts.map +1 -0
- package/dist/translations/languages/sv.js +12 -0
- package/dist/translations/languages/sv.js.map +1 -0
- package/dist/translations/languages/th.d.ts +4 -0
- package/dist/translations/languages/th.d.ts.map +1 -0
- package/dist/translations/languages/th.js +12 -0
- package/dist/translations/languages/th.js.map +1 -0
- package/dist/translations/languages/tr.d.ts +4 -0
- package/dist/translations/languages/tr.d.ts.map +1 -0
- package/dist/translations/languages/tr.js +12 -0
- package/dist/translations/languages/tr.js.map +1 -0
- package/dist/translations/languages/uk.d.ts +4 -0
- package/dist/translations/languages/uk.d.ts.map +1 -0
- package/dist/translations/languages/uk.js +12 -0
- package/dist/translations/languages/uk.js.map +1 -0
- package/dist/translations/languages/vi.d.ts +4 -0
- package/dist/translations/languages/vi.d.ts.map +1 -0
- package/dist/translations/languages/vi.js +12 -0
- package/dist/translations/languages/vi.js.map +1 -0
- package/dist/translations/languages/zh.d.ts +4 -0
- package/dist/translations/languages/zh.d.ts.map +1 -0
- package/dist/translations/languages/zh.js +12 -0
- package/dist/translations/languages/zh.js.map +1 -0
- package/dist/translations/languages/zhTw.d.ts +4 -0
- package/dist/translations/languages/zhTw.d.ts.map +1 -0
- package/dist/translations/languages/zhTw.js +12 -0
- package/dist/translations/languages/zhTw.js.map +1 -0
- package/dist/translations/types.d.ts +10 -0
- package/dist/translations/types.d.ts.map +1 -0
- package/dist/translations/types.js +3 -0
- package/dist/translations/types.js.map +1 -0
- package/package.json +16 -6
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAUxC,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,OAAO,cAAc,CAAA;AAIrB,eAAO,MAAM,cAAc,wBAAyB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,6BAqG1F,CAAA"}
|
|
@@ -1,14 +1,35 @@
|
|
|
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 { getTranslation } from '@payloadcms/translations';
|
|
4
|
-
import { SelectInput, useTranslation } from '@payloadcms/ui';
|
|
4
|
+
import { ConfirmationModal, SelectInput, Translation, useModal, useTranslation } from '@payloadcms/ui';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js';
|
|
7
7
|
import './index.scss';
|
|
8
|
+
const confirmSwitchTenantSlug = 'confirmSwitchTenant';
|
|
8
9
|
export const TenantSelector = ({ label, viewType })=>{
|
|
9
|
-
const { options, selectedTenantID, setTenant } = useTenantSelection();
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
10
|
+
const { options, preventRefreshOnChange, selectedTenantID, setTenant } = useTenantSelection();
|
|
11
|
+
const { openModal } = useModal();
|
|
12
|
+
const { i18n, t } = useTranslation();
|
|
13
|
+
const [tenantSelection, setTenantSelection] = React.useState();
|
|
14
|
+
const selectedValue = React.useMemo(()=>{
|
|
15
|
+
if (selectedTenantID) {
|
|
16
|
+
return options.find((option)=>option.value === selectedTenantID);
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}, [
|
|
20
|
+
options,
|
|
21
|
+
selectedTenantID
|
|
22
|
+
]);
|
|
23
|
+
const newSelectedValue = React.useMemo(()=>{
|
|
24
|
+
if (tenantSelection && 'value' in tenantSelection) {
|
|
25
|
+
return options.find((option)=>option.value === tenantSelection.value);
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}, [
|
|
29
|
+
options,
|
|
30
|
+
tenantSelection
|
|
31
|
+
]);
|
|
32
|
+
const switchTenant = React.useCallback((option)=>{
|
|
12
33
|
if (option && 'value' in option) {
|
|
13
34
|
setTenant({
|
|
14
35
|
id: option.value,
|
|
@@ -23,20 +44,67 @@ export const TenantSelector = ({ label, viewType })=>{
|
|
|
23
44
|
}, [
|
|
24
45
|
setTenant
|
|
25
46
|
]);
|
|
47
|
+
const onChange = React.useCallback((option)=>{
|
|
48
|
+
if (!preventRefreshOnChange) {
|
|
49
|
+
switchTenant(option);
|
|
50
|
+
return;
|
|
51
|
+
} else {
|
|
52
|
+
setTenantSelection(option);
|
|
53
|
+
openModal(confirmSwitchTenantSlug);
|
|
54
|
+
}
|
|
55
|
+
}, [
|
|
56
|
+
openModal,
|
|
57
|
+
preventRefreshOnChange,
|
|
58
|
+
switchTenant
|
|
59
|
+
]);
|
|
26
60
|
if (options.length <= 1) {
|
|
27
61
|
return null;
|
|
28
62
|
}
|
|
29
|
-
return /*#__PURE__*/
|
|
63
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
30
64
|
className: "tenant-selector",
|
|
31
|
-
children:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
65
|
+
children: [
|
|
66
|
+
/*#__PURE__*/ _jsx(SelectInput, {
|
|
67
|
+
isClearable: viewType === 'list',
|
|
68
|
+
label: getTranslation(label, i18n),
|
|
69
|
+
name: "setTenant",
|
|
70
|
+
onChange: onChange,
|
|
71
|
+
options: options,
|
|
72
|
+
path: "setTenant",
|
|
73
|
+
value: selectedTenantID
|
|
74
|
+
}),
|
|
75
|
+
/*#__PURE__*/ _jsx(ConfirmationModal, {
|
|
76
|
+
body: /*#__PURE__*/ _jsx(Translation, {
|
|
77
|
+
elements: {
|
|
78
|
+
0: ({ children })=>{
|
|
79
|
+
return /*#__PURE__*/ _jsx("b", {
|
|
80
|
+
children: children
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
85
|
+
// @ts-expect-error
|
|
86
|
+
i18nKey: "plugin-multi-tenant:confirm-tenant-switch--body",
|
|
87
|
+
t: t,
|
|
88
|
+
variables: {
|
|
89
|
+
fromTenant: selectedValue?.label,
|
|
90
|
+
toTenant: newSelectedValue?.label
|
|
91
|
+
}
|
|
92
|
+
}),
|
|
93
|
+
heading: /*#__PURE__*/ _jsx(Translation, {
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
95
|
+
// @ts-expect-error
|
|
96
|
+
i18nKey: "plugin-multi-tenant:confirm-tenant-switch--heading",
|
|
97
|
+
t: t,
|
|
98
|
+
variables: {
|
|
99
|
+
tenantLabel: label.toLowerCase()
|
|
100
|
+
}
|
|
101
|
+
}),
|
|
102
|
+
modalSlug: confirmSwitchTenantSlug,
|
|
103
|
+
onConfirm: ()=>{
|
|
104
|
+
switchTenant(tenantSelection);
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
]
|
|
40
108
|
});
|
|
41
109
|
};
|
|
42
110
|
|
|
@@ -1 +1 @@
|
|
|
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 { getTranslation } from '@payloadcms/translations'\nimport {
|
|
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 { getTranslation } from '@payloadcms/translations'\nimport {\n ConfirmationModal,\n SelectInput,\n Translation,\n useModal,\n useTranslation,\n} from '@payloadcms/ui'\nimport React from 'react'\n\nimport type {\n PluginMultiTenantTranslationKeys,\n PluginMultiTenantTranslations,\n} from '../../translations/index.js'\n\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\nimport './index.scss'\n\nconst confirmSwitchTenantSlug = 'confirmSwitchTenant'\n\nexport const TenantSelector = ({ label, viewType }: { label: string; viewType?: ViewTypes }) => {\n const { options, preventRefreshOnChange, selectedTenantID, setTenant } = useTenantSelection()\n const { openModal } = useModal()\n const { i18n, t } = useTranslation<\n PluginMultiTenantTranslations,\n PluginMultiTenantTranslationKeys\n >()\n const [tenantSelection, setTenantSelection] = React.useState<\n ReactSelectOption | ReactSelectOption[]\n >()\n\n const selectedValue = React.useMemo(() => {\n if (selectedTenantID) {\n return options.find((option) => option.value === selectedTenantID)\n }\n return undefined\n }, [options, selectedTenantID])\n\n const newSelectedValue = React.useMemo(() => {\n if (tenantSelection && 'value' in tenantSelection) {\n return options.find((option) => option.value === tenantSelection.value)\n }\n return undefined\n }, [options, tenantSelection])\n\n const switchTenant = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[] | undefined) => {\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 const onChange = React.useCallback(\n (option: ReactSelectOption | ReactSelectOption[]) => {\n if (!preventRefreshOnChange) {\n switchTenant(option)\n return\n } else {\n setTenantSelection(option)\n openModal(confirmSwitchTenantSlug)\n }\n },\n [openModal, preventRefreshOnChange, switchTenant],\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={getTranslation(label, i18n)}\n name=\"setTenant\"\n onChange={onChange}\n options={options}\n path=\"setTenant\"\n value={selectedTenantID as string | undefined}\n />\n\n <ConfirmationModal\n body={\n <Translation\n elements={{\n 0: ({ children }) => {\n return <b>{children}</b>\n },\n }}\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-multi-tenant:confirm-tenant-switch--body\"\n t={t}\n variables={{\n fromTenant: selectedValue?.label,\n toTenant: newSelectedValue?.label,\n }}\n />\n }\n heading={\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-multi-tenant:confirm-tenant-switch--heading\"\n t={t}\n variables={{\n tenantLabel: label.toLowerCase(),\n }}\n />\n }\n modalSlug={confirmSwitchTenantSlug}\n onConfirm={() => {\n switchTenant(tenantSelection)\n }}\n />\n </div>\n )\n}\n"],"names":["getTranslation","ConfirmationModal","SelectInput","Translation","useModal","useTranslation","React","useTenantSelection","confirmSwitchTenantSlug","TenantSelector","label","viewType","options","preventRefreshOnChange","selectedTenantID","setTenant","openModal","i18n","t","tenantSelection","setTenantSelection","useState","selectedValue","useMemo","find","option","value","undefined","newSelectedValue","switchTenant","useCallback","id","refresh","onChange","length","div","className","isClearable","name","path","body","elements","children","b","i18nKey","variables","fromTenant","toTenant","heading","tenantLabel","toLowerCase","modalSlug","onConfirm"],"mappings":"AAAA;;AAIA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SACEC,iBAAiB,EACjBC,WAAW,EACXC,WAAW,EACXC,QAAQ,EACRC,cAAc,QACT,iBAAgB;AACvB,OAAOC,WAAW,QAAO;AAOzB,SAASC,kBAAkB,QAAQ,0DAAyD;AAC5F,OAAO,eAAc;AAErB,MAAMC,0BAA0B;AAEhC,OAAO,MAAMC,iBAAiB,CAAC,EAAEC,KAAK,EAAEC,QAAQ,EAA2C;IACzF,MAAM,EAAEC,OAAO,EAAEC,sBAAsB,EAAEC,gBAAgB,EAAEC,SAAS,EAAE,GAAGR;IACzE,MAAM,EAAES,SAAS,EAAE,GAAGZ;IACtB,MAAM,EAAEa,IAAI,EAAEC,CAAC,EAAE,GAAGb;IAIpB,MAAM,CAACc,iBAAiBC,mBAAmB,GAAGd,MAAMe,QAAQ;IAI5D,MAAMC,gBAAgBhB,MAAMiB,OAAO,CAAC;QAClC,IAAIT,kBAAkB;YACpB,OAAOF,QAAQY,IAAI,CAAC,CAACC,SAAWA,OAAOC,KAAK,KAAKZ;QACnD;QACA,OAAOa;IACT,GAAG;QAACf;QAASE;KAAiB;IAE9B,MAAMc,mBAAmBtB,MAAMiB,OAAO,CAAC;QACrC,IAAIJ,mBAAmB,WAAWA,iBAAiB;YACjD,OAAOP,QAAQY,IAAI,CAAC,CAACC,SAAWA,OAAOC,KAAK,KAAKP,gBAAgBO,KAAK;QACxE;QACA,OAAOC;IACT,GAAG;QAACf;QAASO;KAAgB;IAE7B,MAAMU,eAAevB,MAAMwB,WAAW,CACpC,CAACL;QACC,IAAIA,UAAU,WAAWA,QAAQ;YAC/BV,UAAU;gBAAEgB,IAAIN,OAAOC,KAAK;gBAAYM,SAAS;YAAK;QACxD,OAAO;YACLjB,UAAU;gBAAEgB,IAAIJ;gBAAWK,SAAS;YAAK;QAC3C;IACF,GACA;QAACjB;KAAU;IAGb,MAAMkB,WAAW3B,MAAMwB,WAAW,CAChC,CAACL;QACC,IAAI,CAACZ,wBAAwB;YAC3BgB,aAAaJ;YACb;QACF,OAAO;YACLL,mBAAmBK;YACnBT,UAAUR;QACZ;IACF,GACA;QAACQ;QAAWH;QAAwBgB;KAAa;IAGnD,IAAIjB,QAAQsB,MAAM,IAAI,GAAG;QACvB,OAAO;IACT;IAEA,qBACE,MAACC;QAAIC,WAAU;;0BACb,KAAClC;gBACCmC,aAAa1B,aAAa;gBAC1BD,OAAOV,eAAeU,OAAOO;gBAC7BqB,MAAK;gBACLL,UAAUA;gBACVrB,SAASA;gBACT2B,MAAK;gBACLb,OAAOZ;;0BAGT,KAACb;gBACCuC,oBACE,KAACrC;oBACCsC,UAAU;wBACR,GAAG,CAAC,EAAEC,QAAQ,EAAE;4BACd,qBAAO,KAACC;0CAAGD;;wBACb;oBACF;oBACA,6DAA6D;oBAC7D,mBAAmB;oBACnBE,SAAQ;oBACR1B,GAAGA;oBACH2B,WAAW;wBACTC,YAAYxB,eAAeZ;wBAC3BqC,UAAUnB,kBAAkBlB;oBAC9B;;gBAGJsC,uBACE,KAAC7C;oBACC,6DAA6D;oBAC7D,mBAAmB;oBACnByC,SAAQ;oBACR1B,GAAGA;oBACH2B,WAAW;wBACTI,aAAavC,MAAMwC,WAAW;oBAChC;;gBAGJC,WAAW3C;gBACX4C,WAAW;oBACTvB,aAAaV;gBACf;;;;AAIR,EAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/WatchTenantCollection/index.tsx"],"names":[],"mappings":"AASA,eAAO,MAAM,qBAAqB,YAyBjC,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useConfig, useDocumentInfo, useEffectEvent, useFormFields } from '@payloadcms/ui';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js';
|
|
5
|
+
export const WatchTenantCollection = ()=>{
|
|
6
|
+
const { id, collectionSlug, title } = useDocumentInfo();
|
|
7
|
+
const { getEntityConfig } = useConfig();
|
|
8
|
+
const [useAsTitleName] = React.useState(()=>getEntityConfig({
|
|
9
|
+
collectionSlug
|
|
10
|
+
}).admin.useAsTitle);
|
|
11
|
+
const titleField = useFormFields(([fields])=>fields[useAsTitleName]);
|
|
12
|
+
const { updateTenants } = useTenantSelection();
|
|
13
|
+
const syncTenantTitle = useEffectEvent(()=>{
|
|
14
|
+
if (id) {
|
|
15
|
+
updateTenants({
|
|
16
|
+
id,
|
|
17
|
+
label: title
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
React.useEffect(()=>{
|
|
22
|
+
// only update the tenant selector when the document saves
|
|
23
|
+
// → aka when initial value changes
|
|
24
|
+
if (id && titleField?.initialValue) {
|
|
25
|
+
syncTenantTitle();
|
|
26
|
+
}
|
|
27
|
+
}, [
|
|
28
|
+
id,
|
|
29
|
+
titleField?.initialValue
|
|
30
|
+
]);
|
|
31
|
+
return null;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/WatchTenantCollection/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientCollectionConfig } from 'payload'\n\nimport { useConfig, useDocumentInfo, useEffectEvent, useFormFields } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\n\nexport const WatchTenantCollection = () => {\n const { id, collectionSlug, title } = useDocumentInfo()\n const { getEntityConfig } = useConfig()\n const [useAsTitleName] = React.useState(\n () => (getEntityConfig({ collectionSlug }) as ClientCollectionConfig).admin.useAsTitle,\n )\n const titleField = useFormFields(([fields]) => fields[useAsTitleName])\n\n const { updateTenants } = useTenantSelection()\n\n const syncTenantTitle = useEffectEvent(() => {\n if (id) {\n updateTenants({ id, label: title })\n }\n })\n\n React.useEffect(() => {\n // only update the tenant selector when the document saves\n // → aka when initial value changes\n if (id && titleField?.initialValue) {\n syncTenantTitle()\n }\n }, [id, titleField?.initialValue])\n\n return null\n}\n"],"names":["useConfig","useDocumentInfo","useEffectEvent","useFormFields","React","useTenantSelection","WatchTenantCollection","id","collectionSlug","title","getEntityConfig","useAsTitleName","useState","admin","useAsTitle","titleField","fields","updateTenants","syncTenantTitle","label","useEffect","initialValue"],"mappings":"AAAA;AAIA,SAASA,SAAS,EAAEC,eAAe,EAAEC,cAAc,EAAEC,aAAa,QAAQ,iBAAgB;AAC1F,OAAOC,WAAW,QAAO;AAEzB,SAASC,kBAAkB,QAAQ,0DAAyD;AAE5F,OAAO,MAAMC,wBAAwB;IACnC,MAAM,EAAEC,EAAE,EAAEC,cAAc,EAAEC,KAAK,EAAE,GAAGR;IACtC,MAAM,EAAES,eAAe,EAAE,GAAGV;IAC5B,MAAM,CAACW,eAAe,GAAGP,MAAMQ,QAAQ,CACrC,IAAM,AAACF,gBAAgB;YAAEF;QAAe,GAA8BK,KAAK,CAACC,UAAU;IAExF,MAAMC,aAAaZ,cAAc,CAAC,CAACa,OAAO,GAAKA,MAAM,CAACL,eAAe;IAErE,MAAM,EAAEM,aAAa,EAAE,GAAGZ;IAE1B,MAAMa,kBAAkBhB,eAAe;QACrC,IAAIK,IAAI;YACNU,cAAc;gBAAEV;gBAAIY,OAAOV;YAAM;QACnC;IACF;IAEAL,MAAMgB,SAAS,CAAC;QACd,0DAA0D;QAC1D,mCAAmC;QACnC,IAAIb,MAAMQ,YAAYM,cAAc;YAClCH;QACF;IACF,GAAG;QAACX;QAAIQ,YAAYM;KAAa;IAEjC,OAAO;AACT,EAAC"}
|
package/dist/exports/client.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { TenantField } from '../components/TenantField/index.client.js';
|
|
2
2
|
export { TenantSelector } from '../components/TenantSelector/index.js';
|
|
3
|
+
export { WatchTenantCollection } from '../components/WatchTenantCollection/index.js';
|
|
3
4
|
export { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js';
|
|
4
5
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +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;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sDAAsD,CAAA"}
|
|
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;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAA;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sDAAsD,CAAA"}
|
package/dist/exports/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { TenantField } from '../components/TenantField/index.client.js';
|
|
2
2
|
export { TenantSelector } from '../components/TenantSelector/index.js';
|
|
3
|
+
export { WatchTenantCollection } from '../components/WatchTenantCollection/index.js';
|
|
3
4
|
export { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js';
|
|
4
5
|
|
|
5
6
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +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'\nexport { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js'\n"],"names":["TenantField","TenantSelector","useTenantSelection"],"mappings":"AAAA,SAASA,WAAW,QAAQ,4CAA2C;AACvE,SAASC,cAAc,QAAQ,wCAAuC;AACtE,SAASC,kBAAkB,QAAQ,uDAAsD"}
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { TenantField } from '../components/TenantField/index.client.js'\nexport { TenantSelector } from '../components/TenantSelector/index.js'\nexport { WatchTenantCollection } from '../components/WatchTenantCollection/index.js'\nexport { useTenantSelection } from '../providers/TenantSelectionProvider/index.client.js'\n"],"names":["TenantField","TenantSelector","WatchTenantCollection","useTenantSelection"],"mappings":"AAAA,SAASA,WAAW,QAAQ,4CAA2C;AACvE,SAASC,cAAc,QAAQ,wCAAuC;AACtE,SAASC,qBAAqB,QAAQ,+CAA8C;AACpF,SAASC,kBAAkB,QAAQ,uDAAsD"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAKvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAczD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MAwWzB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { deepMergeSimple } from 'payload';
|
|
1
2
|
import { defaults } from './defaults.js';
|
|
2
3
|
import { tenantField } from './fields/tenantField/index.js';
|
|
3
4
|
import { tenantsArrayField } from './fields/tenantsArrayField/index.js';
|
|
@@ -5,6 +6,7 @@ import { addTenantCleanup } from './hooks/afterTenantDelete.js';
|
|
|
5
6
|
import { filterDocumentsBySelectedTenant } from './list-filters/filterDocumentsBySelectedTenant.js';
|
|
6
7
|
import { filterTenantsBySelectedTenant } from './list-filters/filterTenantsBySelectedTenant.js';
|
|
7
8
|
import { filterUsersBySelectedTenant } from './list-filters/filterUsersBySelectedTenant.js';
|
|
9
|
+
import { translations } from './translations/index.js';
|
|
8
10
|
import { addCollectionAccess } from './utilities/addCollectionAccess.js';
|
|
9
11
|
import { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js';
|
|
10
12
|
import { combineListFilters } from './utilities/combineListFilters.js';
|
|
@@ -183,6 +185,19 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
|
183
185
|
usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName
|
|
184
186
|
});
|
|
185
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Add custom tenant field that watches and dispatches updates to the selector
|
|
190
|
+
*/ collection.fields.push({
|
|
191
|
+
name: '_watchTenant',
|
|
192
|
+
type: 'ui',
|
|
193
|
+
admin: {
|
|
194
|
+
components: {
|
|
195
|
+
Field: {
|
|
196
|
+
path: '@payloadcms/plugin-multi-tenant/client#WatchTenantCollection'
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
186
201
|
} else if (pluginConfig.collections?.[collection.slug]) {
|
|
187
202
|
const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal);
|
|
188
203
|
if (isGlobal) {
|
|
@@ -271,6 +286,16 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
|
271
286
|
},
|
|
272
287
|
path: '@payloadcms/plugin-multi-tenant/client#TenantSelector'
|
|
273
288
|
});
|
|
289
|
+
/**
|
|
290
|
+
* Merge plugin translations
|
|
291
|
+
*/ const simplifiedTranslations = Object.entries(translations).reduce((acc, [key, value])=>{
|
|
292
|
+
acc[key] = value.translations;
|
|
293
|
+
return acc;
|
|
294
|
+
}, {});
|
|
295
|
+
incomingConfig.i18n = {
|
|
296
|
+
...incomingConfig.i18n,
|
|
297
|
+
translations: deepMergeSimple(simplifiedTranslations, incomingConfig.i18n?.translations ?? {})
|
|
298
|
+
};
|
|
274
299
|
return incomingConfig;
|
|
275
300
|
};
|
|
276
301
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type { CollectionConfig, Config } from 'payload'\n\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { filterDocumentsBySelectedTenant } from './list-filters/filterDocumentsBySelectedTenant.js'\nimport { filterTenantsBySelectedTenant } from './list-filters/filterTenantsBySelectedTenant.js'\nimport { filterUsersBySelectedTenant } from './list-filters/filterUsersBySelectedTenant.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { combineListFilters } from './utilities/combineListFilters.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n const tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel\n const basePath = pluginConfig.basePath || defaults.basePath\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenant selector localized labels\n */\n if (typeof tenantSelectorLabel === 'object') {\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n Object.entries(tenantSelectorLabel).forEach(([_locale, label]) => {\n const locale = _locale as AcceptedLanguages\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n if (!incomingConfig.i18n.translations) {\n incomingConfig.i18n.translations = {}\n }\n if (!(locale in incomingConfig.i18n.translations)) {\n incomingConfig.i18n.translations[locale] = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (!('multiTenant' in incomingConfig.i18n.translations[locale])) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant.selectorLabel = label\n })\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.useUsersTenantFilter !== false) {\n if (!adminUsersCollection.admin) {\n adminUsersCollection.admin = {}\n }\n\n adminUsersCollection.admin.baseListFilter = combineListFilters({\n baseListFilter: adminUsersCollection.admin?.baseListFilter,\n customFilter: (args) =>\n filterUsersBySelectedTenant({\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n })\n }\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.useTenantsListFilter !== false) {\n /**\n * Add list filter to tenants collection\n * - filter by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterTenantsBySelectedTenant({\n req: args.req,\n tenantsCollectionSlug,\n }),\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n } else if (pluginConfig.collections?.[collection.slug]) {\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n /**\n * Modify enabled collections\n */\n addFilterOptionsToFields({\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.splice(\n 0,\n 0,\n tenantField({\n ...(pluginConfig?.tenantField || {}),\n name: tenantFieldName,\n debug: pluginConfig.debug,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n\n if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {\n /**\n * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsBySelectedTenant({\n req: args.req,\n tenantFieldName,\n tenantsCollectionSlug,\n }),\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n basePath,\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n clientProps: {\n label: tenantSelectorLabel,\n },\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n return incomingConfig\n }\n"],"names":["defaults","tenantField","tenantsArrayField","addTenantCleanup","filterDocumentsBySelectedTenant","filterTenantsBySelectedTenant","filterUsersBySelectedTenant","addCollectionAccess","addFilterOptionsToFields","combineListFilters","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","tenantSelectorLabel","basePath","admin","components","actions","beforeNavLinks","providers","collections","i18n","Object","entries","forEach","_locale","label","locale","translations","multiTenant","selectorLabel","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","adminUsersSlug","collection","fieldName","useUsersTenantFilter","baseListFilter","customFilter","args","req","tenantCollection","collectionSlugs","globalCollectionSlugs","keys","reduce","acc","isGlobal","useTenantsCollectionAccess","useTenantsListFilter","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","useTenantAccess","clientProps","useAsTitle","path","length","serverProps","globalSlugs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type { CollectionConfig, Config } from 'payload'\n\nimport { deepMergeSimple } from 'payload'\n\nimport type { PluginDefaultTranslationsObject } from './translations/types.js'\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { filterDocumentsBySelectedTenant } from './list-filters/filterDocumentsBySelectedTenant.js'\nimport { filterTenantsBySelectedTenant } from './list-filters/filterTenantsBySelectedTenant.js'\nimport { filterUsersBySelectedTenant } from './list-filters/filterUsersBySelectedTenant.js'\nimport { translations } from './translations/index.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { combineListFilters } from './utilities/combineListFilters.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n const tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel\n const basePath = pluginConfig.basePath || defaults.basePath\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenant selector localized labels\n */\n if (typeof tenantSelectorLabel === 'object') {\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n Object.entries(tenantSelectorLabel).forEach(([_locale, label]) => {\n const locale = _locale as AcceptedLanguages\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n if (!incomingConfig.i18n.translations) {\n incomingConfig.i18n.translations = {}\n }\n if (!(locale in incomingConfig.i18n.translations)) {\n incomingConfig.i18n.translations[locale] = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (!('multiTenant' in incomingConfig.i18n.translations[locale])) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant = {}\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n incomingConfig.i18n.translations[locale].multiTenant.selectorLabel = label\n })\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.useUsersTenantFilter !== false) {\n if (!adminUsersCollection.admin) {\n adminUsersCollection.admin = {}\n }\n\n adminUsersCollection.admin.baseListFilter = combineListFilters({\n baseListFilter: adminUsersCollection.admin?.baseListFilter,\n customFilter: (args) =>\n filterUsersBySelectedTenant({\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n })\n }\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.useTenantsListFilter !== false) {\n /**\n * Add list filter to tenants collection\n * - filter by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterTenantsBySelectedTenant({\n req: args.req,\n tenantsCollectionSlug,\n }),\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n\n /**\n * Add custom tenant field that watches and dispatches updates to the selector\n */\n collection.fields.push({\n name: '_watchTenant',\n type: 'ui',\n admin: {\n components: {\n Field: {\n path: '@payloadcms/plugin-multi-tenant/client#WatchTenantCollection',\n },\n },\n },\n })\n } else if (pluginConfig.collections?.[collection.slug]) {\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n /**\n * Modify enabled collections\n */\n addFilterOptionsToFields({\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n })\n\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.splice(\n 0,\n 0,\n tenantField({\n ...(pluginConfig?.tenantField || {}),\n name: tenantFieldName,\n debug: pluginConfig.debug,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n\n if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {\n /**\n * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n collection.admin.baseListFilter = combineListFilters({\n baseListFilter: collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsBySelectedTenant({\n req: args.req,\n tenantFieldName,\n tenantsCollectionSlug,\n }),\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n basePath,\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n clientProps: {\n label: tenantSelectorLabel,\n },\n path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',\n })\n\n /**\n * Merge plugin translations\n */\n\n const simplifiedTranslations = Object.entries(translations).reduce(\n (acc, [key, value]) => {\n acc[key] = value.translations\n return acc\n },\n {} as Record<string, PluginDefaultTranslationsObject>,\n )\n\n incomingConfig.i18n = {\n ...incomingConfig.i18n,\n translations: deepMergeSimple(\n simplifiedTranslations,\n incomingConfig.i18n?.translations ?? {},\n ),\n }\n\n return incomingConfig\n }\n"],"names":["deepMergeSimple","defaults","tenantField","tenantsArrayField","addTenantCleanup","filterDocumentsBySelectedTenant","filterTenantsBySelectedTenant","filterUsersBySelectedTenant","translations","addCollectionAccess","addFilterOptionsToFields","combineListFilters","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","tenantSelectorLabel","basePath","admin","components","actions","beforeNavLinks","providers","collections","i18n","Object","entries","forEach","_locale","label","locale","multiTenant","selectorLabel","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","adminUsersSlug","collection","fieldName","useUsersTenantFilter","baseListFilter","customFilter","args","req","tenantCollection","collectionSlugs","globalCollectionSlugs","keys","reduce","acc","isGlobal","useTenantsCollectionAccess","useTenantsListFilter","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","type","Field","path","Boolean","disableDuplicate","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","splice","debug","unique","useBaseListFilter","useTenantAccess","clientProps","useAsTitle","length","serverProps","globalSlugs","simplifiedTranslations","key","value"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ type ContextType = {
|
|
|
5
5
|
* Array of options to select from
|
|
6
6
|
*/
|
|
7
7
|
options: OptionObject[];
|
|
8
|
+
preventRefreshOnChange: boolean;
|
|
8
9
|
/**
|
|
9
10
|
* The currently selected tenant ID
|
|
10
11
|
*/
|
|
@@ -25,8 +26,15 @@ type ContextType = {
|
|
|
25
26
|
id: number | string | undefined;
|
|
26
27
|
refresh?: boolean;
|
|
27
28
|
}) => void;
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
updateTenants: (args: {
|
|
33
|
+
id: number | string;
|
|
34
|
+
label: string;
|
|
35
|
+
}) => void;
|
|
28
36
|
};
|
|
29
|
-
export declare const TenantSelectionProviderClient: ({ children, initialValue, tenantCookie, tenantOptions, }: {
|
|
37
|
+
export declare const TenantSelectionProviderClient: ({ children, initialValue, tenantCookie, tenantOptions: tenantOptionsFromProps, }: {
|
|
30
38
|
children: React.ReactNode;
|
|
31
39
|
initialValue?: number | string;
|
|
32
40
|
tenantCookie?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,OAAO,KAAwB,MAAM,OAAO,CAAA;AAE5C,KAAK,WAAW,GAAG;IACjB;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB;;OAEG;IACH,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C;;;;OAIG;IACH,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxE;;;;;OAKG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAI3C,OAAO,KAAwB,MAAM,OAAO,CAAA;AAE5C,KAAK,WAAW,GAAG;IACjB;;OAEG;IACH,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,sBAAsB,EAAE,OAAO,CAAA;IAC/B;;OAEG;IACH,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC7C;;;;OAIG;IACH,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxE;;;;;OAKG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IACjF;;OAEG;IACH,aAAa,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACtE,CAAA;AAWD,eAAO,MAAM,6BAA6B,qFAKvC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,sBAkHA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAA2B,CAAA"}
|
|
@@ -5,17 +5,20 @@ import { useRouter } from 'next/navigation.js';
|
|
|
5
5
|
import React, { createContext } from 'react';
|
|
6
6
|
const Context = /*#__PURE__*/ createContext({
|
|
7
7
|
options: [],
|
|
8
|
+
preventRefreshOnChange: false,
|
|
8
9
|
selectedTenantID: undefined,
|
|
9
10
|
setPreventRefreshOnChange: ()=>null,
|
|
10
|
-
setTenant: ()=>null
|
|
11
|
+
setTenant: ()=>null,
|
|
12
|
+
updateTenants: ()=>null
|
|
11
13
|
});
|
|
12
|
-
export const TenantSelectionProviderClient = ({ children, initialValue, tenantCookie, tenantOptions })=>{
|
|
14
|
+
export const TenantSelectionProviderClient = ({ children, initialValue, tenantCookie, tenantOptions: tenantOptionsFromProps })=>{
|
|
13
15
|
const [selectedTenantID, setSelectedTenantID] = React.useState(initialValue);
|
|
14
16
|
const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false);
|
|
15
17
|
const { user } = useAuth();
|
|
16
18
|
const userID = React.useMemo(()=>user?.id, [
|
|
17
19
|
user?.id
|
|
18
20
|
]);
|
|
21
|
+
const [tenantOptions, setTenantOptions] = React.useState(()=>tenantOptionsFromProps);
|
|
19
22
|
const selectedTenantLabel = React.useMemo(()=>tenantOptions.find((option)=>option.value === selectedTenantID)?.label, [
|
|
20
23
|
selectedTenantID,
|
|
21
24
|
tenantOptions
|
|
@@ -52,6 +55,19 @@ export const TenantSelectionProviderClient = ({ children, initialValue, tenantCo
|
|
|
52
55
|
setSelectedTenantID,
|
|
53
56
|
tenantOptions
|
|
54
57
|
]);
|
|
58
|
+
const updateTenants = React.useCallback(({ id, label })=>{
|
|
59
|
+
setTenantOptions((prev)=>{
|
|
60
|
+
return prev.map((currentTenant)=>{
|
|
61
|
+
if (id === currentTenant.value) {
|
|
62
|
+
return {
|
|
63
|
+
label,
|
|
64
|
+
value: id
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return currentTenant;
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}, []);
|
|
55
71
|
React.useEffect(()=>{
|
|
56
72
|
if (selectedTenantID && !tenantOptions.find((option)=>option.value === selectedTenantID)) {
|
|
57
73
|
if (tenantOptions?.[0]?.value) {
|
|
@@ -78,6 +94,7 @@ export const TenantSelectionProviderClient = ({ children, initialValue, tenantCo
|
|
|
78
94
|
if (userID && !tenantCookie) {
|
|
79
95
|
// User is logged in, but does not have a tenant cookie, set it
|
|
80
96
|
setSelectedTenantID(initialValue);
|
|
97
|
+
setTenantOptions(tenantOptionsFromProps);
|
|
81
98
|
if (initialValue) {
|
|
82
99
|
setCookie(String(initialValue));
|
|
83
100
|
} else {
|
|
@@ -90,7 +107,8 @@ export const TenantSelectionProviderClient = ({ children, initialValue, tenantCo
|
|
|
90
107
|
initialValue,
|
|
91
108
|
setCookie,
|
|
92
109
|
deleteCookie,
|
|
93
|
-
router
|
|
110
|
+
router,
|
|
111
|
+
tenantOptionsFromProps
|
|
94
112
|
]);
|
|
95
113
|
React.useEffect(()=>{
|
|
96
114
|
if (!userID && tenantCookie) {
|
|
@@ -113,9 +131,11 @@ export const TenantSelectionProviderClient = ({ children, initialValue, tenantCo
|
|
|
113
131
|
children: /*#__PURE__*/ _jsx(Context, {
|
|
114
132
|
value: {
|
|
115
133
|
options: tenantOptions,
|
|
134
|
+
preventRefreshOnChange,
|
|
116
135
|
selectedTenantID,
|
|
117
136
|
setPreventRefreshOnChange,
|
|
118
|
-
setTenant
|
|
137
|
+
setTenant,
|
|
138
|
+
updateTenants
|
|
119
139
|
},
|
|
120
140
|
children: children
|
|
121
141
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject } from 'payload'\n\nimport { useAuth } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React, { createContext } from 'react'\n\ntype ContextType = {\n /**\n * Array of options to select from\n */\n options: OptionObject[]\n /**\n * The currently selected tenant ID\n */\n selectedTenantID: number | string | undefined\n /**\n * Prevents a refresh when the tenant is changed\n *\n * If not switching tenants while viewing a \"global\", set to true\n */\n setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>\n /**\n * Sets the selected tenant ID\n *\n * @param args.id - The ID of the tenant to select\n * @param args.refresh - Whether to refresh the page after changing the tenant\n */\n setTenant: (args: { id: number | string | undefined; refresh?: boolean }) => void\n}\n\nconst Context = createContext<ContextType>({\n options: [],\n selectedTenantID: undefined,\n setPreventRefreshOnChange: () => null,\n setTenant: () => null,\n})\n\nexport const TenantSelectionProviderClient = ({\n children,\n initialValue,\n tenantCookie,\n tenantOptions,\n}: {\n children: React.ReactNode\n initialValue?: number | string\n tenantCookie?: string\n tenantOptions: OptionObject[]\n}) => {\n const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(\n initialValue,\n )\n const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)\n const { user } = useAuth()\n const userID = React.useMemo(() => user?.id, [user?.id])\n const selectedTenantLabel = React.useMemo(\n () => tenantOptions.find((option) => option.value === selectedTenantID)?.label,\n [selectedTenantID, tenantOptions],\n )\n\n const router = useRouter()\n\n const setCookie = React.useCallback((value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n }, [])\n\n const deleteCookie = React.useCallback(() => {\n document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'\n }, [])\n\n const setTenant = React.useCallback<ContextType['setTenant']>(\n ({ id, refresh }) => {\n if (id === undefined) {\n if (tenantOptions.length > 1) {\n setSelectedTenantID(undefined)\n deleteCookie()\n } else {\n setSelectedTenantID(tenantOptions[0]?.value)\n setCookie(String(tenantOptions[0]?.value))\n }\n } else {\n setSelectedTenantID(id)\n setCookie(String(id))\n }\n if (!preventRefreshOnChange && refresh) {\n router.refresh()\n }\n },\n [deleteCookie, preventRefreshOnChange, router, setCookie, setSelectedTenantID, tenantOptions],\n )\n\n React.useEffect(() => {\n if (selectedTenantID && !tenantOptions.find((option) => option.value === selectedTenantID)) {\n if (tenantOptions?.[0]?.value) {\n setTenant({ id: tenantOptions[0].value, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n }\n }, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])\n\n React.useEffect(() => {\n if (userID && !tenantCookie) {\n // User is logged in, but does not have a tenant cookie, set it\n setSelectedTenantID(initialValue)\n if (initialValue) {\n setCookie(String(initialValue))\n } else {\n deleteCookie()\n }\n }\n }, [userID, tenantCookie, initialValue, setCookie, deleteCookie, router])\n\n React.useEffect(() => {\n if (!userID && tenantCookie) {\n // User is not logged in, but has a tenant cookie, delete it\n deleteCookie()\n setSelectedTenantID(undefined)\n } else if (userID) {\n // User changed, refresh\n router.refresh()\n }\n }, [userID, tenantCookie, deleteCookie, router])\n\n return (\n <span\n data-selected-tenant-id={selectedTenantID}\n data-selected-tenant-title={selectedTenantLabel}\n >\n <Context\n value={{\n options: tenantOptions,\n selectedTenantID,\n setPreventRefreshOnChange,\n setTenant,\n }}\n >\n {children}\n </Context>\n </span>\n )\n}\n\nexport const useTenantSelection = () => React.use(Context)\n"],"names":["useAuth","useRouter","React","createContext","Context","options","selectedTenantID","undefined","setPreventRefreshOnChange","setTenant","TenantSelectionProviderClient","children","initialValue","tenantCookie","tenantOptions","
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/TenantSelectionProvider/index.client.tsx"],"sourcesContent":["'use client'\n\nimport type { OptionObject } from 'payload'\n\nimport { useAuth } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation.js'\nimport React, { createContext } from 'react'\n\ntype ContextType = {\n /**\n * Array of options to select from\n */\n options: OptionObject[]\n preventRefreshOnChange: boolean\n /**\n * The currently selected tenant ID\n */\n selectedTenantID: number | string | undefined\n /**\n * Prevents a refresh when the tenant is changed\n *\n * If not switching tenants while viewing a \"global\", set to true\n */\n setPreventRefreshOnChange: React.Dispatch<React.SetStateAction<boolean>>\n /**\n * Sets the selected tenant ID\n *\n * @param args.id - The ID of the tenant to select\n * @param args.refresh - Whether to refresh the page after changing the tenant\n */\n setTenant: (args: { id: number | string | undefined; refresh?: boolean }) => void\n /**\n *\n */\n updateTenants: (args: { id: number | string; label: string }) => void\n}\n\nconst Context = createContext<ContextType>({\n options: [],\n preventRefreshOnChange: false,\n selectedTenantID: undefined,\n setPreventRefreshOnChange: () => null,\n setTenant: () => null,\n updateTenants: () => null,\n})\n\nexport const TenantSelectionProviderClient = ({\n children,\n initialValue,\n tenantCookie,\n tenantOptions: tenantOptionsFromProps,\n}: {\n children: React.ReactNode\n initialValue?: number | string\n tenantCookie?: string\n tenantOptions: OptionObject[]\n}) => {\n const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(\n initialValue,\n )\n const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)\n const { user } = useAuth()\n const userID = React.useMemo(() => user?.id, [user?.id])\n const [tenantOptions, setTenantOptions] = React.useState<OptionObject[]>(\n () => tenantOptionsFromProps,\n )\n const selectedTenantLabel = React.useMemo(\n () => tenantOptions.find((option) => option.value === selectedTenantID)?.label,\n [selectedTenantID, tenantOptions],\n )\n\n const router = useRouter()\n\n const setCookie = React.useCallback((value?: string) => {\n const expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'\n }, [])\n\n const deleteCookie = React.useCallback(() => {\n document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'\n }, [])\n\n const setTenant = React.useCallback<ContextType['setTenant']>(\n ({ id, refresh }) => {\n if (id === undefined) {\n if (tenantOptions.length > 1) {\n setSelectedTenantID(undefined)\n deleteCookie()\n } else {\n setSelectedTenantID(tenantOptions[0]?.value)\n setCookie(String(tenantOptions[0]?.value))\n }\n } else {\n setSelectedTenantID(id)\n setCookie(String(id))\n }\n if (!preventRefreshOnChange && refresh) {\n router.refresh()\n }\n },\n [deleteCookie, preventRefreshOnChange, router, setCookie, setSelectedTenantID, tenantOptions],\n )\n\n const updateTenants = React.useCallback<ContextType['updateTenants']>(({ id, label }) => {\n setTenantOptions((prev) => {\n return prev.map((currentTenant) => {\n if (id === currentTenant.value) {\n return {\n label,\n value: id,\n }\n }\n return currentTenant\n })\n })\n }, [])\n\n React.useEffect(() => {\n if (selectedTenantID && !tenantOptions.find((option) => option.value === selectedTenantID)) {\n if (tenantOptions?.[0]?.value) {\n setTenant({ id: tenantOptions[0].value, refresh: true })\n } else {\n setTenant({ id: undefined, refresh: true })\n }\n }\n }, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])\n\n React.useEffect(() => {\n if (userID && !tenantCookie) {\n // User is logged in, but does not have a tenant cookie, set it\n setSelectedTenantID(initialValue)\n setTenantOptions(tenantOptionsFromProps)\n if (initialValue) {\n setCookie(String(initialValue))\n } else {\n deleteCookie()\n }\n }\n }, [userID, tenantCookie, initialValue, setCookie, deleteCookie, router, tenantOptionsFromProps])\n\n React.useEffect(() => {\n if (!userID && tenantCookie) {\n // User is not logged in, but has a tenant cookie, delete it\n deleteCookie()\n setSelectedTenantID(undefined)\n } else if (userID) {\n // User changed, refresh\n router.refresh()\n }\n }, [userID, tenantCookie, deleteCookie, router])\n\n return (\n <span\n data-selected-tenant-id={selectedTenantID}\n data-selected-tenant-title={selectedTenantLabel}\n >\n <Context\n value={{\n options: tenantOptions,\n preventRefreshOnChange,\n selectedTenantID,\n setPreventRefreshOnChange,\n setTenant,\n updateTenants,\n }}\n >\n {children}\n </Context>\n </span>\n )\n}\n\nexport const useTenantSelection = () => React.use(Context)\n"],"names":["useAuth","useRouter","React","createContext","Context","options","preventRefreshOnChange","selectedTenantID","undefined","setPreventRefreshOnChange","setTenant","updateTenants","TenantSelectionProviderClient","children","initialValue","tenantCookie","tenantOptions","tenantOptionsFromProps","setSelectedTenantID","useState","user","userID","useMemo","id","setTenantOptions","selectedTenantLabel","find","option","value","label","router","setCookie","useCallback","expires","document","cookie","deleteCookie","refresh","length","String","prev","map","currentTenant","useEffect","span","data-selected-tenant-id","data-selected-tenant-title","useTenantSelection","use"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GenericTranslationsObject, NestedKeysStripped, SupportedLanguages } from '@payloadcms/translations';
|
|
2
|
+
import type { PluginDefaultTranslationsObject } from './types.js';
|
|
3
|
+
export declare const translations: SupportedLanguages<PluginDefaultTranslationsObject>;
|
|
4
|
+
export type PluginMultiTenantTranslations = GenericTranslationsObject;
|
|
5
|
+
export type PluginMultiTenantTranslationKeys = NestedKeysStripped<PluginMultiTenantTranslations>;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAA;AAyCjE,eAAO,MAAM,YAAY,EAuCpB,kBAAkB,CAAC,+BAA+B,CAAC,CAAA;AAExD,MAAM,MAAM,6BAA6B,GAAG,yBAAyB,CAAA;AAErE,MAAM,MAAM,gCAAgC,GAAG,kBAAkB,CAAC,6BAA6B,CAAC,CAAA"}
|