@payloadcms/plugin-multi-tenant 3.44.0-internal.6b79dc2 → 3.44.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/WatchTenantCollection/index.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,qBAAqB,YA2BjC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/WatchTenantCollection/index.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,qBAAqB,YA0CjC,CAAA"}
@@ -5,12 +5,13 @@ import { useTenantSelection } from '../../providers/TenantSelectionProvider/inde
5
5
  export const WatchTenantCollection = ()=>{
6
6
  const { id, collectionSlug } = useDocumentInfo();
7
7
  const { title } = useDocumentTitle();
8
+ const addedNewTenant = React.useRef(false);
8
9
  const { getEntityConfig } = useConfig();
9
10
  const [useAsTitleName] = React.useState(()=>getEntityConfig({
10
11
  collectionSlug
11
12
  }).admin.useAsTitle);
12
13
  const titleField = useFormFields(([fields])=>useAsTitleName ? fields[useAsTitleName] : {});
13
- const { updateTenants } = useTenantSelection();
14
+ const { options, updateTenants } = useTenantSelection();
14
15
  const syncTenantTitle = useEffectEvent(()=>{
15
16
  if (id) {
16
17
  updateTenants({
@@ -19,6 +20,24 @@ export const WatchTenantCollection = ()=>{
19
20
  });
20
21
  }
21
22
  });
23
+ React.useEffect(()=>{
24
+ if (!id || !title || addedNewTenant.current) {
25
+ return;
26
+ }
27
+ // Track tenant creation and add it to the tenant selector
28
+ const exists = options.some((opt)=>opt.value === id);
29
+ if (!exists) {
30
+ addedNewTenant.current = true;
31
+ updateTenants({
32
+ id,
33
+ label: title
34
+ });
35
+ }
36
+ // eslint-disable-next-line react-compiler/react-compiler
37
+ // eslint-disable-next-line react-hooks/exhaustive-deps
38
+ }, [
39
+ id
40
+ ]);
22
41
  React.useEffect(()=>{
23
42
  // only update the tenant selector when the document saves
24
43
  // → aka when initial value changes
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/WatchTenantCollection/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientCollectionConfig } from 'payload'\n\nimport {\n useConfig,\n useDocumentInfo,\n useDocumentTitle,\n useEffectEvent,\n useFormFields,\n} from '@payloadcms/ui'\nimport React from 'react'\n\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\n\nexport const WatchTenantCollection = () => {\n const { id, collectionSlug } = useDocumentInfo()\n const { title } = useDocumentTitle()\n\n const { getEntityConfig } = useConfig()\n const [useAsTitleName] = React.useState(\n () => (getEntityConfig({ collectionSlug }) as ClientCollectionConfig).admin.useAsTitle,\n )\n const titleField = useFormFields(([fields]) => (useAsTitleName ? 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","useDocumentTitle","useEffectEvent","useFormFields","React","useTenantSelection","WatchTenantCollection","id","collectionSlug","title","getEntityConfig","useAsTitleName","useState","admin","useAsTitle","titleField","fields","updateTenants","syncTenantTitle","label","useEffect","initialValue"],"mappings":"AAAA;AAIA,SACEA,SAAS,EACTC,eAAe,EACfC,gBAAgB,EAChBC,cAAc,EACdC,aAAa,QACR,iBAAgB;AACvB,OAAOC,WAAW,QAAO;AAEzB,SAASC,kBAAkB,QAAQ,0DAAyD;AAE5F,OAAO,MAAMC,wBAAwB;IACnC,MAAM,EAAEC,EAAE,EAAEC,cAAc,EAAE,GAAGR;IAC/B,MAAM,EAAES,KAAK,EAAE,GAAGR;IAElB,MAAM,EAAES,eAAe,EAAE,GAAGX;IAC5B,MAAM,CAACY,eAAe,GAAGP,MAAMQ,QAAQ,CACrC,IAAM,AAACF,gBAAgB;YAAEF;QAAe,GAA8BK,KAAK,CAACC,UAAU;IAExF,MAAMC,aAAaZ,cAAc,CAAC,CAACa,OAAO,GAAML,iBAAiBK,MAAM,CAACL,eAAe,GAAG,CAAC;IAE3F,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"}
1
+ {"version":3,"sources":["../../../src/components/WatchTenantCollection/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientCollectionConfig } from 'payload'\n\nimport {\n useConfig,\n useDocumentInfo,\n useDocumentTitle,\n useEffectEvent,\n useFormFields,\n} from '@payloadcms/ui'\nimport React from 'react'\n\nimport { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'\n\nexport const WatchTenantCollection = () => {\n const { id, collectionSlug } = useDocumentInfo()\n const { title } = useDocumentTitle()\n const addedNewTenant = React.useRef(false)\n\n const { getEntityConfig } = useConfig()\n const [useAsTitleName] = React.useState(\n () => (getEntityConfig({ collectionSlug }) as ClientCollectionConfig).admin.useAsTitle,\n )\n const titleField = useFormFields(([fields]) => (useAsTitleName ? fields[useAsTitleName] : {}))\n\n const { options, updateTenants } = useTenantSelection()\n\n const syncTenantTitle = useEffectEvent(() => {\n if (id) {\n updateTenants({ id, label: title })\n }\n })\n\n React.useEffect(() => {\n if (!id || !title || addedNewTenant.current) {\n return\n }\n // Track tenant creation and add it to the tenant selector\n const exists = options.some((opt) => opt.value === id)\n if (!exists) {\n addedNewTenant.current = true\n updateTenants({ id, label: title })\n }\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id])\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","useDocumentTitle","useEffectEvent","useFormFields","React","useTenantSelection","WatchTenantCollection","id","collectionSlug","title","addedNewTenant","useRef","getEntityConfig","useAsTitleName","useState","admin","useAsTitle","titleField","fields","options","updateTenants","syncTenantTitle","label","useEffect","current","exists","some","opt","value","initialValue"],"mappings":"AAAA;AAIA,SACEA,SAAS,EACTC,eAAe,EACfC,gBAAgB,EAChBC,cAAc,EACdC,aAAa,QACR,iBAAgB;AACvB,OAAOC,WAAW,QAAO;AAEzB,SAASC,kBAAkB,QAAQ,0DAAyD;AAE5F,OAAO,MAAMC,wBAAwB;IACnC,MAAM,EAAEC,EAAE,EAAEC,cAAc,EAAE,GAAGR;IAC/B,MAAM,EAAES,KAAK,EAAE,GAAGR;IAClB,MAAMS,iBAAiBN,MAAMO,MAAM,CAAC;IAEpC,MAAM,EAAEC,eAAe,EAAE,GAAGb;IAC5B,MAAM,CAACc,eAAe,GAAGT,MAAMU,QAAQ,CACrC,IAAM,AAACF,gBAAgB;YAAEJ;QAAe,GAA8BO,KAAK,CAACC,UAAU;IAExF,MAAMC,aAAad,cAAc,CAAC,CAACe,OAAO,GAAML,iBAAiBK,MAAM,CAACL,eAAe,GAAG,CAAC;IAE3F,MAAM,EAAEM,OAAO,EAAEC,aAAa,EAAE,GAAGf;IAEnC,MAAMgB,kBAAkBnB,eAAe;QACrC,IAAIK,IAAI;YACNa,cAAc;gBAAEb;gBAAIe,OAAOb;YAAM;QACnC;IACF;IAEAL,MAAMmB,SAAS,CAAC;QACd,IAAI,CAAChB,MAAM,CAACE,SAASC,eAAec,OAAO,EAAE;YAC3C;QACF;QACA,0DAA0D;QAC1D,MAAMC,SAASN,QAAQO,IAAI,CAAC,CAACC,MAAQA,IAAIC,KAAK,KAAKrB;QACnD,IAAI,CAACkB,QAAQ;YACXf,eAAec,OAAO,GAAG;YACzBJ,cAAc;gBAAEb;gBAAIe,OAAOb;YAAM;QACnC;IACA,yDAAyD;IACzD,uDAAuD;IACzD,GAAG;QAACF;KAAG;IAEPH,MAAMmB,SAAS,CAAC;QACd,0DAA0D;QAC1D,mCAAmC;QACnC,IAAIhB,MAAMU,YAAYY,cAAc;YAClCR;QACF;IACF,GAAG;QAACd;QAAIU,YAAYY;KAAa;IAEjC,OAAO;AACT,EAAC"}
@@ -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,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,sBAmHA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAA2B,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,sBAiIA,CAAA;AAED,eAAO,MAAM,kBAAkB,mBAA2B,CAAA"}
@@ -58,15 +58,30 @@ export const TenantSelectionProviderClient = ({ children, initialValue, tenantCo
58
58
  ]);
59
59
  const updateTenants = React.useCallback(({ id, label })=>{
60
60
  setTenantOptions((prev)=>{
61
- return prev.map((currentTenant)=>{
62
- if (id === currentTenant.value) {
61
+ const stringID = String(id);
62
+ let exists = false;
63
+ const updated = prev.map((currentTenant)=>{
64
+ if (stringID === String(currentTenant.value)) {
65
+ exists = true;
63
66
  return {
64
67
  label,
65
- value: id
68
+ value: stringID
66
69
  };
67
70
  }
68
71
  return currentTenant;
69
72
  });
73
+ if (!exists) {
74
+ updated.push({
75
+ label,
76
+ value: stringID
77
+ });
78
+ }
79
+ // Sort alphabetically by label (or value as fallback)
80
+ return updated.sort((a, b)=>{
81
+ const aKey = typeof a.label === 'string' ? a.label : String(a.value);
82
+ const bKey = typeof b.label === 'string' ? b.label : String(b.value);
83
+ return aKey.localeCompare(bKey);
84
+ });
70
85
  });
71
86
  }, []);
72
87
  React.useEffect(()=>{
@@ -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 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 // eslint-disable-next-line react-compiler/react-compiler -- TODO: fix\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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"}
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 // eslint-disable-next-line react-compiler/react-compiler -- TODO: fix\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 const stringID = String(id)\n let exists = false\n const updated = prev.map((currentTenant) => {\n if (stringID === String(currentTenant.value)) {\n exists = true\n return {\n label,\n value: stringID,\n }\n }\n return currentTenant\n })\n\n if (!exists) {\n updated.push({ label, value: stringID })\n }\n\n // Sort alphabetically by label (or value as fallback)\n return updated.sort((a, b) => {\n const aKey = typeof a.label === 'string' ? a.label : String(a.value)\n const bKey = typeof b.label === 'string' ? b.label : String(b.value)\n return aKey.localeCompare(bKey)\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","stringID","exists","updated","map","currentTenant","push","sort","a","b","aKey","bKey","localeCompare","useEffect","span","data-selected-tenant-id","data-selected-tenant-title","useTenantSelection","use"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-multi-tenant",
3
- "version": "3.44.0-internal.6b79dc2",
3
+ "version": "3.44.0",
4
4
  "description": "Multi Tenant plugin for Payload",
5
5
  "keywords": [
6
6
  "payload",
@@ -80,15 +80,15 @@
80
80
  "types.d.ts"
81
81
  ],
82
82
  "devDependencies": {
83
- "payload": "3.44.0-internal.6b79dc2",
84
- "@payloadcms/ui": "3.44.0-internal.6b79dc2",
83
+ "@payloadcms/translations": "3.44.0",
84
+ "@payloadcms/ui": "3.44.0",
85
85
  "@payloadcms/eslint-config": "3.28.0",
86
- "@payloadcms/translations": "3.44.0-internal.6b79dc2"
86
+ "payload": "3.44.0"
87
87
  },
88
88
  "peerDependencies": {
89
89
  "next": "^15.2.3",
90
- "@payloadcms/ui": "3.44.0-internal.6b79dc2",
91
- "payload": "3.44.0-internal.6b79dc2"
90
+ "@payloadcms/ui": "3.44.0",
91
+ "payload": "3.44.0"
92
92
  },
93
93
  "homepage:": "https://payloadcms.com",
94
94
  "scripts": {