@payloadcms/plugin-multi-tenant
Version:
Multi Tenant plugin for Payload
197 lines (196 loc) • 6.73 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { FieldContext, FieldPathContext, Pill, RelationshipField, useDocumentInfo, useField, useForm, useFormModified, useModal } from '@payloadcms/ui';
import React from 'react';
import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js';
import { AssignTenantFieldModal, assignTenantModalSlug } from '../AssignTenantFieldModal/index.client.js';
import './index.scss';
const baseClass = 'tenantField';
export const TenantField = ({ debug, unique, ...fieldArgs })=>{
const { entityType, options, selectedTenantID, setEntityType, setTenant } = useTenantSelection();
const tenantField = useField();
const { setValue, showError, value } = tenantField;
const { isValid: isFormValid } = useForm();
const { id: docID, collectionSlug } = useDocumentInfo();
const { isModalOpen, openModal } = useModal();
const isEditManyModalOpen = collectionSlug ? isModalOpen(`edit-${collectionSlug}`) || isModalOpen(`edit-${collectionSlug}-bulk-uploads`) : false;
const [modalValue, setModalValue] = React.useState(value);
const localTenantField = React.useMemo(()=>({
...tenantField,
initialValue: modalValue,
setValue: (nextValue)=>{
setModalValue(nextValue);
},
value: modalValue
}), [
modalValue,
tenantField
]);
const showField = options.length > 1 && !fieldArgs.field.admin?.hidden && !fieldArgs.field.hidden || debug;
function getTenantIDToSelect({ selectedTenantID, value }) {
if (Array.isArray(value)) {
if (!value.length) {
return undefined;
}
if (!selectedTenantID || !value.includes(selectedTenantID)) {
return value[0];
}
return undefined;
}
if (value && selectedTenantID !== value) {
return value;
}
return undefined;
}
const syncTenantSelectionFromValue = React.useCallback((tenantValue)=>{
const tenantID = getTenantIDToSelect({
selectedTenantID,
value: tenantValue
});
if (tenantID) {
setTenant({
id: tenantID,
refresh: false
});
}
}, [
selectedTenantID,
setTenant
]);
const onConfirm = React.useCallback(()=>{
if (hasTenantValueChanged({
hasMany: fieldArgs.field.hasMany,
modalValue,
value
})) {
setValue(modalValue);
syncTenantSelectionFromValue(modalValue);
}
}, [
fieldArgs.field.hasMany,
modalValue,
setValue,
syncTenantSelectionFromValue,
value
]);
const afterModalOpen = React.useCallback(()=>{
setModalValue(value);
}, [
value
]);
React.useEffect(()=>{
if (!entityType) {
setEntityType(unique ? 'global' : 'document');
} else {
// unique documents are controlled from the global TenantSelector
if (!unique) {
syncTenantSelectionFromValue(value);
}
}
return ()=>{
if (entityType) {
setEntityType(undefined);
}
};
}, [
entityType,
setEntityType,
syncTenantSelectionFromValue,
unique,
value
]);
React.useEffect(()=>{
if (unique || debug || isEditManyModalOpen) {
return;
}
if (showField && (!isFormValid && showError || !value && !selectedTenantID)) {
openModal(assignTenantModalSlug);
}
}, [
debug,
isEditManyModalOpen,
isFormValid,
showError,
showField,
openModal,
value,
docID,
selectedTenantID,
unique
]);
if (showField) {
if (debug || isEditManyModalOpen) {
return /*#__PURE__*/ _jsx(TenantRelationshipField, {
debug: debug,
fieldArgs: fieldArgs,
unique: unique
});
}
if (!unique) {
/** Editing a non-global tenant document */ return /*#__PURE__*/ _jsx(AssignTenantFieldModal, {
afterModalOpen: afterModalOpen,
onConfirm: onConfirm,
children: /*#__PURE__*/ _jsx(FieldPathContext, {
value: tenantField.path,
children: /*#__PURE__*/ _jsx(FieldContext, {
value: localTenantField,
children: /*#__PURE__*/ _jsx(TenantRelationshipField, {
fieldArgs: fieldArgs,
unique: unique
})
})
})
});
}
return /*#__PURE__*/ _jsx(SyncFormModified, {});
}
return null;
};
const hasTenantValueChanged = ({ hasMany, modalValue, value })=>{
if (hasMany) {
const currentValue = value || [];
const nextValue = modalValue || [];
return currentValue.length !== nextValue.length || nextValue.some((nextValueItem)=>!currentValue.includes(nextValueItem));
}
return value !== modalValue;
};
const TenantRelationshipField = ({ debug, fieldArgs, unique })=>{
return /*#__PURE__*/ _jsx("div", {
className: baseClass,
children: /*#__PURE__*/ _jsxs("div", {
className: `${baseClass}__wrapper`,
children: [
debug && /*#__PURE__*/ _jsx(Pill, {
className: `${baseClass}__debug-pill`,
pillStyle: "success",
size: "small",
children: "Multi-Tenant Debug Enabled"
}),
/*#__PURE__*/ _jsx(RelationshipField, {
...fieldArgs,
field: {
...fieldArgs.field,
required: true
},
readOnly: fieldArgs.readOnly || fieldArgs.field.admin?.readOnly || unique
})
]
})
});
};
/**
* Tells the global selector when the form has been modified
* so it can display the "Leave without saving" confirmation modal
* if modified and attempting to change the tenant
*/ const SyncFormModified = ()=>{
const modified = useFormModified();
const { setModified } = useTenantSelection();
React.useEffect(()=>{
setModified(modified);
}, [
modified,
setModified
]);
return null;
};
//# sourceMappingURL=index.client.js.map