@firecms/user_management 3.0.0-canary.93 → 3.0.0-canary.95
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/index.es.js +10 -6
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +10 -6
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -5
- package/src/hooks/useBuildUserManagement.tsx +10 -6
package/dist/index.es.js
CHANGED
@@ -172,18 +172,20 @@ function useBuildUserManagement({
|
|
172
172
|
if (!equal(newRoles, roles))
|
173
173
|
setRoles(newRoles);
|
174
174
|
} catch (e) {
|
175
|
+
setRoles([]);
|
175
176
|
console.error("Error loading roles", e);
|
176
177
|
setRolesError(e);
|
177
178
|
}
|
178
179
|
setRolesLoading(false);
|
179
180
|
},
|
180
181
|
onError(e) {
|
182
|
+
setRoles([]);
|
181
183
|
console.error("Error loading roles", e);
|
182
184
|
setRolesError(e);
|
183
185
|
setRolesLoading(false);
|
184
186
|
}
|
185
187
|
});
|
186
|
-
}, [dataSourceDelegate, rolesPath]);
|
188
|
+
}, [dataSourceDelegate?.initialised, rolesPath]);
|
187
189
|
useEffect(() => {
|
188
190
|
if (!dataSourceDelegate || !usersPath) return;
|
189
191
|
if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
|
@@ -196,18 +198,20 @@ function useBuildUserManagement({
|
|
196
198
|
if (!equal(newUsers, usersWithRoleIds))
|
197
199
|
setUsersWithRoleIds(newUsers);
|
198
200
|
} catch (e) {
|
201
|
+
setUsersWithRoleIds([]);
|
199
202
|
console.error("Error loading users", e);
|
200
203
|
setUsersError(e);
|
201
204
|
}
|
202
205
|
setUsersLoading(false);
|
203
206
|
},
|
204
207
|
onError(e) {
|
208
|
+
setUsersWithRoleIds([]);
|
205
209
|
console.error("Error loading users", e);
|
206
210
|
setUsersError(e);
|
207
211
|
setUsersLoading(false);
|
208
212
|
}
|
209
213
|
});
|
210
|
-
}, [dataSourceDelegate, usersPath]);
|
214
|
+
}, [dataSourceDelegate?.initialised, usersPath]);
|
211
215
|
const saveUser = useCallback(async (user) => {
|
212
216
|
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
213
217
|
if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
|
@@ -235,7 +239,7 @@ function useBuildUserManagement({
|
|
235
239
|
values: data
|
236
240
|
}).then(() => user);
|
237
241
|
}
|
238
|
-
}, [usersPath, dataSourceDelegate]);
|
242
|
+
}, [usersPath, dataSourceDelegate?.initialised]);
|
239
243
|
const saveRole = useCallback((role) => {
|
240
244
|
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
241
245
|
if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
|
@@ -252,7 +256,7 @@ function useBuildUserManagement({
|
|
252
256
|
}).then(() => {
|
253
257
|
return;
|
254
258
|
});
|
255
|
-
}, [rolesPath, dataSourceDelegate]);
|
259
|
+
}, [rolesPath, dataSourceDelegate?.initialised]);
|
256
260
|
const deleteUser = useCallback(async (user) => {
|
257
261
|
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
258
262
|
if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
|
@@ -264,7 +268,7 @@ function useBuildUserManagement({
|
|
264
268
|
values: {}
|
265
269
|
};
|
266
270
|
await dataSourceDelegate.deleteEntity({ entity });
|
267
|
-
}, [usersPath, dataSourceDelegate]);
|
271
|
+
}, [usersPath, dataSourceDelegate?.initialised]);
|
268
272
|
const deleteRole = useCallback(async (role) => {
|
269
273
|
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
270
274
|
if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
|
@@ -276,7 +280,7 @@ function useBuildUserManagement({
|
|
276
280
|
values: {}
|
277
281
|
};
|
278
282
|
await dataSourceDelegate.deleteEntity({ entity });
|
279
|
-
}, [rolesPath, dataSourceDelegate]);
|
283
|
+
}, [rolesPath, dataSourceDelegate?.initialised]);
|
280
284
|
const collectionPermissions = useCallback(({
|
281
285
|
collection,
|
282
286
|
user
|
package/dist/index.es.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/utils/permissions.ts","../src/utils/local_storage.ts","../src/utils/colors.ts","../src/hooks/useBuildUserManagement.tsx","../src/UserManagementProvider.tsx","../src/hooks/useUserManagement.tsx","../src/components/roles/RoleChip.tsx","../src/components/roles/RolesDetailsForm.tsx","../src/components/roles/default_roles.tsx","../src/components/roles/RolesTable.tsx","../src/components/roles/RolesView.tsx","../src/components/users/UserDetailsForm.tsx","../src/components/users/UsersTable.tsx","../src/components/users/UsersView.tsx","../src/useUserManagementPlugin.tsx","../src/admin_views.tsx"],"sourcesContent":["import { EntityCollection, Permissions, Role, User } from \"@firecms/core\";\n\nexport const RESERVED_GROUPS = [\"Admin\"];\n\nconst DEFAULT_PERMISSIONS = {\n read: false,\n edit: false,\n create: false,\n delete: false\n};\n\nexport function resolveUserRolePermissions<UserType extends User>\n({\n collection,\n user\n }: {\n collection: EntityCollection<any>,\n user: UserType | null\n}): Permissions {\n\n const roles = user?.roles;\n if (!roles) {\n return DEFAULT_PERMISSIONS;\n } else if (collection.ownerId === user?.uid) {\n return {\n read: true,\n create: true,\n edit: true,\n delete: true\n };\n } else {\n const basePermissions = {\n read: false,\n create: false,\n edit: false,\n delete: false\n };\n\n return roles\n .map(role => resolveCollectionRole(role, collection.id))\n .reduce(mergePermissions, basePermissions);\n }\n}\n\nfunction resolveCollectionRole(role: Role, id: string): Permissions {\n\n const basePermissions = {\n read: role.isAdmin || role.defaultPermissions?.read,\n create: role.isAdmin || role.defaultPermissions?.create,\n edit: role.isAdmin || role.defaultPermissions?.edit,\n delete: role.isAdmin || role.defaultPermissions?.delete\n };\n if (role.collectionPermissions && role.collectionPermissions[id]) {\n return mergePermissions(role.collectionPermissions[id], basePermissions);\n } else if (role.defaultPermissions) {\n return mergePermissions(role.defaultPermissions, basePermissions);\n } else {\n return basePermissions;\n }\n}\n\nconst mergePermissions = (permA: Permissions, permB: Permissions) => {\n return {\n read: permA.read || permB.read,\n create: permA.create || permB.create,\n edit: permA.edit || permB.edit,\n delete: permA.delete || permB.delete\n };\n}\n\nexport function getUserRoles(roles: Role[], fireCMSUser: User): Role[] | undefined {\n return !roles\n ? undefined\n : (fireCMSUser.roles\n ? fireCMSUser.roles\n .map(role => roles.find((r) => r.id === role.id))\n .filter(Boolean) as Role[]\n : []);\n}\n\nexport const areRolesEqual = (rolesA: Role[], rolesB: Role[]) => {\n const rolesAIds = rolesA.map(r => r.id);\n const rolesBIds = rolesB.map(r => r.id);\n return rolesAIds.length === rolesB.length && rolesAIds.every((role) => rolesBIds.includes(role));\n}\n","// const tokens = new Map<string, {\n// token: string,\n// expiry: Date\n// }>();\n\nexport function cacheDelegatedLoginToken(projectId: string, delegatedToken?: string) {\n if (!delegatedToken) {\n return;\n }\n\n const data = parseJwt(delegatedToken);\n // @ts-ignore\n const expiry = new Date(data.exp * 1000);\n localStorage.setItem(`auth_token::${projectId}`, JSON.stringify({\n token: delegatedToken,\n expiry\n }));\n\n}\n\nexport function getDelegatedLoginTokenFromCache(projectId: string) {\n const entry = localStorage.getItem(`auth_token::${projectId}`);\n if (entry) {\n const data = JSON.parse(entry);\n data.expiry = new Date(data.expiry);\n if (data.expiry > new Date()) {\n return data.token;\n }\n }\n return undefined;\n}\n\nexport function clearDelegatedLoginTokensCache() {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(\"auth_token::\")) {\n localStorage.removeItem(key);\n }\n }\n}\n\nfunction parseJwt(token?: string): object {\n if (!token) {\n throw new Error(\"No JWT token\");\n }\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const jsonPayload = decodeURIComponent(window.atob(base64).split(\"\").map(function (c) {\n return \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2);\n }).join(\"\"));\n\n return JSON.parse(jsonPayload);\n}\n","export function darkenColor(hexColor: string, darkenBy = 10): string {\n // Check input validity\n if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(hexColor)) {\n throw new Error(\"Invalid color format\");\n }\n\n // If shorthand form, convert to full form\n let color = hexColor.substring(1).split(\"\");\n if (color.length === 3) {\n color = [color[0], color[0], color[1], color[1], color[2], color[2]];\n }\n\n // Convert to RGB values\n let r = parseInt(color[0] + color[1], 16);\n let g = parseInt(color[2] + color[3], 16);\n let b = parseInt(color[4] + color[5], 16);\n\n // Reduce each color component by the specified percentage (darkenBy)\n r = Math.floor(r * (1 - darkenBy / 100));\n g = Math.floor(g * (1 - darkenBy / 100));\n b = Math.floor(b * (1 - darkenBy / 100));\n\n // Recombine into hex and return\n return \"#\" +\n (r < 16 ? \"0\" : \"\") + r.toString(16) +\n (g < 16 ? \"0\" : \"\") + g.toString(16) +\n (b < 16 ? \"0\" : \"\") + b.toString(16);\n}\n\nexport function hexToRgbaWithOpacity(hexColor: string, opacity = 10): string {\n // Check input validity\n if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(hexColor)) {\n throw new Error(\"Invalid color format\");\n }\n\n // If shorthand form, convert to full form\n let color = hexColor.substring(1).split(\"\");\n if (color.length === 3) {\n color = [color[0], color[0], color[1], color[1], color[2], color[2]];\n }\n\n // Convert to RGB values\n const r = parseInt(color[0] + color[1], 16);\n const g = parseInt(color[2] + color[3], 16);\n const b = parseInt(color[4] + color[5], 16);\n\n // Convert opacity to a decimal for CSS\n const alpha = opacity / 100;\n\n // Construct and return the RGBA color\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n","import React, { useCallback, useEffect } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport { UserManagement } from \"../types\";\nimport { Authenticator, DataSourceDelegate, Entity, PermissionsBuilder, Role, User } from \"@firecms/core\";\nimport { resolveUserRolePermissions } from \"../utils\";\n\ntype UserWithRoleIds = User & { roles: string[] };\n\nexport interface UserManagementParams {\n\n /**\n * The delegate in charge of persisting the data.\n */\n dataSourceDelegate?: DataSourceDelegate;\n\n /**\n * Path where the plugin users configuration is stored.\n * Default: __FIRECMS/config/users\n * You can specify a different path if you want to store the user management configuration in a different place.\n * Please keep in mind that the FireCMS users are not necessarily the same as the Firebase users (but they can be).\n * The path should be relative to the root of the database, and should always have an odd number of segments.\n */\n usersPath?: string;\n\n /**\n * Path where the plugin roles configuration is stored.\n * Default: __FIRECMS/config/roles\n */\n rolesPath?: string;\n\n /**\n * Maximum number of users that can be created.\n */\n usersLimit?: number;\n\n /**\n * Can the logged user edit roles\n */\n canEditRoles?: boolean;\n\n /**\n * If there are no roles in the database, provide a button to create the default roles.\n */\n allowDefaultRolesCreation?: boolean;\n\n /**\n * Include the collection config permissions in the user management system.\n */\n includeCollectionConfigPermissions?: boolean;\n\n}\n\n/**\n * This hook is used to build a user management object that can be used to\n * manage users and roles in a Firestore backend.\n * @param dataSourceDelegate\n * @param usersPath\n * @param rolesPath\n * @param usersLimit\n * @param canEditRoles\n * @param allowDefaultRolesCreation\n * @param includeCollectionConfigPermissions\n */\nexport function useBuildUserManagement({\n dataSourceDelegate,\n usersPath = \"__FIRECMS/config/users\",\n rolesPath = \"__FIRECMS/config/roles\",\n usersLimit,\n canEditRoles = true,\n allowDefaultRolesCreation,\n includeCollectionConfigPermissions\n }: UserManagementParams): UserManagement {\n\n const [rolesLoading, setRolesLoading] = React.useState<boolean>(true);\n const [usersLoading, setUsersLoading] = React.useState<boolean>(true);\n const [roles, setRoles] = React.useState<Role[]>([]);\n const [usersWithRoleIds, setUsersWithRoleIds] = React.useState<UserWithRoleIds[]>([]);\n\n const users = usersWithRoleIds.map(u => ({\n ...u,\n roles: roles.filter(r => u.roles?.includes(r.id))\n }) as User);\n\n const [rolesError, setRolesError] = React.useState<Error | undefined>();\n const [usersError, setUsersError] = React.useState<Error | undefined>();\n\n const loading = rolesLoading || usersLoading;\n\n useEffect(() => {\n if (!dataSourceDelegate || !rolesPath) return;\n if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;\n\n return dataSourceDelegate.listenCollection?.({\n path: rolesPath,\n onUpdate(entities: Entity<any>[]): void {\n setRolesError(undefined);\n try {\n const newRoles = entityToRoles(entities);\n if (!equal(newRoles, roles))\n setRoles(newRoles);\n } catch (e) {\n console.error(\"Error loading roles\", e);\n setRolesError(e as Error);\n }\n setRolesLoading(false);\n },\n onError(e: any): void {\n console.error(\"Error loading roles\", e);\n setRolesError(e);\n setRolesLoading(false);\n }\n });\n\n }, [dataSourceDelegate, rolesPath]);\n\n useEffect(() => {\n if (!dataSourceDelegate || !usersPath) return;\n if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;\n\n return dataSourceDelegate.listenCollection?.({\n path: usersPath,\n onUpdate(entities: Entity<any>[]): void {\n setUsersError(undefined);\n try {\n const newUsers = entitiesToUsers(entities);\n if (!equal(newUsers, usersWithRoleIds))\n setUsersWithRoleIds(newUsers);\n } catch (e) {\n console.error(\"Error loading users\", e);\n setUsersError(e as Error);\n }\n setUsersLoading(false);\n },\n onError(e: any): void {\n console.error(\"Error loading users\", e);\n setUsersError(e);\n setUsersLoading(false);\n }\n });\n\n }, [dataSourceDelegate, usersPath]);\n\n const saveUser = useCallback(async (user: User): Promise<User> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!usersPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n\n console.debug(\"Persisting user\", user);\n\n const roleIds = user.roles?.map(r => r.id);\n const {\n uid,\n ...userData\n } = user;\n const data = {\n ...userData,\n roles: roleIds\n };\n if (uid) {\n return dataSourceDelegate.saveEntity({\n status: \"existing\",\n path: usersPath,\n entityId: uid,\n values: data\n }).then(() => user);\n } else {\n return dataSourceDelegate.saveEntity({\n status: \"new\",\n path: usersPath,\n values: data\n }).then(() => user);\n }\n }, [usersPath, dataSourceDelegate]);\n\n const saveRole = useCallback((role: Role): Promise<void> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!rolesPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n console.debug(\"Persisting role\", role);\n const {\n id,\n ...roleData\n } = role;\n return dataSourceDelegate.saveEntity({\n status: \"existing\",\n path: rolesPath,\n entityId: id,\n values: roleData\n }).then(() => {\n return;\n });\n }, [rolesPath, dataSourceDelegate]);\n\n const deleteUser = useCallback(async (user: User): Promise<void> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!usersPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n console.debug(\"Deleting\", user);\n const { uid } = user;\n const entity: Entity<any> = {\n path: usersPath,\n id: uid,\n values: {}\n };\n await dataSourceDelegate.deleteEntity({ entity })\n }, [usersPath, dataSourceDelegate]);\n\n const deleteRole = useCallback(async (role: Role): Promise<void> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!rolesPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n console.debug(\"Deleting\", role);\n const { id } = role;\n const entity: Entity<any> = {\n path: usersPath,\n id: id,\n values: {}\n };\n await dataSourceDelegate.deleteEntity({ entity })\n }, [rolesPath, dataSourceDelegate]);\n\n const collectionPermissions: PermissionsBuilder = useCallback(({\n collection,\n user\n }) => resolveUserRolePermissions({\n collection,\n user\n }), []);\n\n const defineRolesFor: ((user: User) => Role[] | undefined) = useCallback((user) => {\n if (!users) throw Error(\"Users not loaded\");\n const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());\n return mgmtUser?.roles;\n }, [users]);\n\n const authenticator: Authenticator = useCallback(({ user }) => {\n console.debug(\"Authenticating user\", user);\n\n if (loading) {\n console.warn(\"User management is still loading\");\n return false;\n }\n\n // This is an example of how you can link the access system to the user management plugin\n if (users.length === 0) {\n return true; // If there are no users created yet, we allow access to every user\n }\n\n const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());\n if (mgmtUser) {\n return true;\n }\n\n throw Error(\"Could not find a user with the provided email in the user management system.\");\n }, [loading, users]);\n\n const isAdmin = roles.some(r => r.id === \"admin\");\n\n return {\n loading,\n roles,\n users,\n saveUser,\n saveRole,\n rolesError,\n deleteUser,\n deleteRole,\n usersLimit,\n usersError,\n isAdmin,\n canEditRoles: canEditRoles === undefined ? true : canEditRoles,\n allowDefaultRolesCreation: allowDefaultRolesCreation === undefined ? true : allowDefaultRolesCreation,\n includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),\n collectionPermissions,\n defineRolesFor,\n authenticator\n }\n}\n\nconst entitiesToUsers = (docs: Entity<Omit<UserWithRoleIds, \"id\">>[]): (UserWithRoleIds)[] => {\n return docs.map((doc) => {\n const data = doc.values as any;\n const newVar = {\n uid: doc.id,\n ...data,\n created_on: data?.created_on,\n updated_on: data?.updated_on\n };\n return newVar as (UserWithRoleIds);\n });\n}\n\nconst entityToRoles = (entities: Entity<Omit<Role, \"id\">>[]): Role[] => {\n return entities.map((doc) => ({\n id: doc.id,\n ...doc.values\n } as Role));\n}\n","import React, { PropsWithChildren } from \"react\";\nimport { UserManagement } from \"./types\";\nimport { User } from \"@firecms/core\";\n\nexport const UserManagementContext = React.createContext<UserManagement<any>>({} as any);\n\nexport interface UserManagementProviderProps<U extends User = User> {\n userManagement: UserManagement<U>\n}\n\nexport function UserManagementProvider<U extends User = User>({\n children,\n userManagement\n }: PropsWithChildren<UserManagementProviderProps<U>>) {\n return (\n <UserManagementContext.Provider value={userManagement}>\n {children}\n </UserManagementContext.Provider>\n );\n};\n","import { useContext } from \"react\";\nimport { UserManagement } from \"../types\";\nimport { UserManagementContext } from \"../UserManagementProvider\";\nimport { User } from \"@firecms/core\";\nexport const useUserManagement = <USER extends User>() => useContext<UserManagement<USER>>(UserManagementContext);\n","import { Chip, getColorSchemeForSeed } from \"@firecms/ui\";\nimport { Role } from \"@firecms/core\";\n\nexport type RoleChipProps = {\n role: Role;\n}\n\nexport function RoleChip({ role }: RoleChipProps) {\n let colorScheme;\n if (role.isAdmin) {\n colorScheme = \"blueDarker\";\n } else if (role.id === \"editor\") {\n colorScheme = \"yellowLight\";\n } else if (role.id === \"viewer\") {\n colorScheme = \"grayLight\";\n } else {\n colorScheme = getColorSchemeForSeed(role.id);\n }\n\n return (\n <Chip\n colorScheme={colorScheme}\n key={role.id}>\n {role.name}\n </Chip>\n );\n\n}\n","import React, { useCallback, useState } from \"react\";\nimport * as Yup from \"yup\";\n\nimport { EntityCollection, FieldCaption, Role, toSnakeCase, } from \"@firecms/core\";\nimport {\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DoneIcon,\n LoadingButton,\n Paper,\n Select,\n SelectItem,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n TextField,\n Tooltip,\n Typography\n} from \"@firecms/ui\";\nimport { useUserManagement } from \"../../hooks\";\nimport { Formex, getIn, useCreateFormex } from \"@firecms/formex\";\n\nexport const RoleYupSchema = Yup.object().shape({\n id: Yup.string().required(\"Required\"),\n name: Yup.string().required(\"Required\")\n});\n\nexport function RolesDetailsForm({\n open,\n role,\n editable,\n handleClose,\n collections\n }: {\n open: boolean,\n editable?: boolean,\n role?: Role,\n handleClose: () => void,\n collections?: EntityCollection[]\n}) {\n\n const { saveRole } = useUserManagement();\n const isNewRole = !role;\n\n const [savingError, setSavingError] = useState<Error | undefined>();\n\n const onRoleUpdated = useCallback((role: Role) => {\n setSavingError(undefined);\n return saveRole(role);\n }, [saveRole]);\n\n const formex = useCreateFormex({\n initialValues: role ?? {\n name: \"\"\n } as Role,\n onSubmit: (role: Role, formexController) => {\n return onRoleUpdated(role)\n .then(() => {\n formexController.resetForm({\n values: role\n });\n handleClose();\n })\n .catch(e => setSavingError(e));\n },\n validation: (values) => {\n return RoleYupSchema.validate(values, { abortEarly: false })\n .then(() => ({}))\n .catch((e) => {\n const errors: Record<string, string> = {};\n e.inner.forEach((error: any) => {\n errors[error.path] = error.message;\n });\n return errors;\n });\n }\n\n });\n\n const {\n isSubmitting,\n touched,\n values,\n errors,\n handleChange,\n setFieldValue,\n dirty,\n setFieldTouched\n } = formex;\n\n const isAdmin = values.isAdmin ?? false;\n const defaultCreate = values.defaultPermissions?.create ?? false;\n const defaultRead = values.defaultPermissions?.read ?? false;\n const defaultEdit = values.defaultPermissions?.edit ?? false;\n const defaultDelete = values.defaultPermissions?.delete ?? false;\n\n React.useEffect(() => {\n const idTouched = getIn(touched, \"id\");\n if (!idTouched && values.name) {\n setFieldValue(\"id\", toSnakeCase(values.name))\n }\n }, [touched, values.name]);\n\n return (\n <Dialog\n open={open}\n maxWidth={\"4xl\"}\n >\n <Formex value={formex}>\n <form noValidate\n autoComplete={\"off\"}\n onSubmit={formex.handleSubmit}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\n height: \"100%\"\n }}>\n <DialogContent className=\"flex-grow\">\n <div\n className=\"flex flex-row pt-12 pb-8\">\n <Typography variant={\"h4\"}\n className=\"flex-grow\">\n Role\n </Typography>\n </div>\n\n <div className={\"grid grid-cols-12 gap-8\"}>\n\n <div className={\"col-span-12 md:col-span-8\"}>\n <TextField\n name=\"name\"\n required\n error={touched.name && Boolean(errors.name)}\n value={values.name}\n disabled={isAdmin || !editable}\n onChange={handleChange}\n aria-describedby=\"name-helper-text\"\n label=\"Name\"\n />\n <FieldCaption>\n {touched.name && Boolean(errors.name) ? errors.name : \"Name of this role\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <TextField\n name=\"id\"\n required\n error={touched.id && Boolean(errors.id)}\n value={values.id}\n disabled={!isNewRole || !editable}\n onChange={(e) => {\n handleChange(e);\n setFieldTouched(\"id\", true)\n }}\n aria-describedby=\"id-helper-text\"\n label=\"ID\"\n />\n <FieldCaption>\n {touched.id && Boolean(errors.id) ? errors.id : \"ID of this role\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12\"}>\n <Paper\n\n className=\"bg-inherit\">\n <Table>\n <TableHeader>\n <TableCell></TableCell>\n <TableCell\n align=\"center\">Create\n entities\n </TableCell>\n <TableCell\n align=\"center\">Read\n entities\n </TableCell>\n <TableCell\n align=\"center\">Update\n entities\n </TableCell>\n <TableCell\n align=\"center\">Delete\n entities\n </TableCell>\n </TableHeader>\n\n <TableBody>\n <TableRow>\n <TableCell\n scope=\"row\">\n <strong>All\n collections</strong>\n </TableCell>\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Create entities in collections\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultCreate) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.create\", checked)}\n />\n </Tooltip>\n </TableCell>\n\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Access all data in every collection\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultRead) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.read\", checked)}\n />\n </Tooltip>\n </TableCell>\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Update data in any collection\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultEdit) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.edit\", checked)}\n />\n </Tooltip>\n </TableCell>\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Delete data in any collection\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultDelete) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.delete\", checked)}\n />\n\n </Tooltip>\n </TableCell>\n </TableRow>\n {collections && collections.map((col) => (\n <TableRow key={col.name}>\n <TableCell\n scope=\"row\">\n {col.name}\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultCreate || !editable}\n checked={(isAdmin || defaultCreate || getIn(values, `collectionPermissions.${col.path}.create`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.create`, checked)}/>\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultRead || !editable}\n checked={(isAdmin || defaultRead || getIn(values, `collectionPermissions.${col.path}.read`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.read`, checked)}/>\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultEdit || !editable}\n checked={(isAdmin || defaultEdit || getIn(values, `collectionPermissions.${col.path}.edit`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.edit`, checked)}/>\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultDelete || !editable}\n checked={(isAdmin || defaultDelete || getIn(values, `collectionPermissions.${col.path}.delete`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.delete`, checked)}/>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </Paper>\n <FieldCaption>\n You can customise the permissions\n that the users related to this\n role can perform in the entities\n of each collection\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <Select\n error={touched.config && Boolean(errors.config)}\n id=\"createCollections\"\n name=\"createCollections\"\n label=\"Create collections\"\n position={\"item-aligned\"}\n disabled={isAdmin || !editable}\n onChange={(event) => setFieldValue(\"config.createCollections\", event.target.value === \"true\")}\n value={isAdmin || values.config?.createCollections ? \"true\" : \"false\"}\n renderValue={(value: any) => value === \"true\" ? \"Yes\" : \"No\"}\n >\n <SelectItem\n value={\"true\"}> Yes </SelectItem>\n <SelectItem\n value={\"false\"}> No </SelectItem>\n </Select>\n\n <FieldCaption>\n {touched.config && Boolean(errors.config) ? errors.config : \"Can the user create collections\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <Select\n error={touched.config && Boolean(errors.config)}\n id=\"editCollections\"\n name=\"editCollections\"\n label=\"Edit collections\"\n disabled={isAdmin || !editable}\n position={\"item-aligned\"}\n onChange={(event) => setFieldValue(\"config.editCollections\", event.target.value === \"own\" ? \"own\" : event.target.value === \"true\")}\n value={isAdmin ? \"true\" : (values.config?.editCollections === \"own\" ? \"own\" : (values.config?.editCollections ? \"true\" : \"false\"))}\n renderValue={(value: any) => value === \"own\" ? \"Own\" : (value === \"true\" ? \"Yes\" : \"No\")}\n >\n <SelectItem\n value={\"true\"}> Yes </SelectItem>\n <SelectItem\n value={\"false\"}> No </SelectItem>\n <SelectItem\n value={\"own\"}> Only\n his/her own </SelectItem>\n </Select>\n\n <FieldCaption>\n {touched.config && Boolean(errors.config) ? errors.config : \"Can the user edit collections\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <Select\n error={touched.config && Boolean(errors.config)}\n id=\"deleteCollections\"\n name=\"deleteCollections\"\n label=\"Delete collections\"\n disabled={isAdmin || !editable}\n position={\"item-aligned\"}\n onChange={(event) => setFieldValue(\"config.deleteCollections\", event.target.value === \"own\" ? \"own\" : event.target.value === \"true\")}\n value={isAdmin ? \"true\" : (values.config?.deleteCollections === \"own\" ? \"own\" : (values.config?.deleteCollections ? \"true\" : \"false\"))}\n renderValue={(value: any) => value === \"own\" ? \"Own\" : (value === \"true\" ? \"Yes\" : \"No\")}\n >\n <SelectItem\n value={\"true\"}> Yes </SelectItem>\n <SelectItem\n value={\"false\"}> No </SelectItem>\n <SelectItem\n value={\"own\"}> Only\n his/her own </SelectItem>\n </Select>\n\n <FieldCaption>\n {touched.config && Boolean(errors.config) ? errors.config : \"Can the user delete collections\"}\n </FieldCaption>\n\n </div>\n\n </div>\n </DialogContent>\n\n <DialogActions position={\"sticky\"}>\n {savingError && <Typography className={\"text-red-500\"}>\n There was an error saving this role\n </Typography>}\n <Button variant={\"text\"}\n onClick={() => {\n handleClose();\n }}>\n Cancel\n </Button>\n <LoadingButton\n variant=\"filled\"\n color=\"primary\"\n type=\"submit\"\n disabled={!dirty}\n loading={isSubmitting}\n startIcon={<DoneIcon/>}\n >\n {isNewRole ? \"Create role\" : \"Update\"}\n </LoadingButton>\n </DialogActions>\n </form>\n\n </Formex>\n </Dialog>\n );\n}\n","import { Role } from \"@firecms/core\";\n\nexport const DEFAULT_ROLES: Role[] = [\n {\n id: \"admin\",\n name: \"Admin\",\n isAdmin: true\n },\n {\n id: \"editor\",\n name: \"Editor\",\n isAdmin: false,\n defaultPermissions: {\n read: true,\n create: true,\n edit: true,\n delete: true\n },\n config: {\n createCollections: true,\n editCollections: \"own\",\n deleteCollections: \"own\"\n }\n },\n {\n id: \"viewer\",\n name: \"Viewer\",\n isAdmin: false,\n defaultPermissions: {\n read: true,\n create: false,\n edit: false,\n delete: false\n }\n }\n];\n","import { useState } from \"react\";\nimport {\n Button,\n CenteredView,\n Checkbox,\n DeleteIcon,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n Tooltip,\n Typography\n} from \"@firecms/ui\";\nimport { DeleteConfirmationDialog, Role } from \"@firecms/core\";\nimport { useUserManagement } from \"../../hooks\";\nimport { RoleChip } from \"./RoleChip\";\nimport { DEFAULT_ROLES } from \"./default_roles\";\n\nexport function RolesTable({\n onRoleClicked,\n editable\n }: {\n onRoleClicked: (role: Role) => void;\n editable: boolean;\n}) {\n\n const {\n roles,\n saveRole,\n deleteRole,\n allowDefaultRolesCreation\n } = useUserManagement();\n\n const [roleToBeDeleted, setRoleToBeDeleted] = useState<Role | undefined>(undefined);\n const [deleteInProgress, setDeleteInProgress] = useState<boolean>(false);\n\n return <div\n className=\"w-full overflow-auto\">\n <Table>\n <TableHeader>\n <TableCell header={true} className=\"w-16\"></TableCell>\n <TableCell header={true}>Role</TableCell>\n <TableCell header={true} className={\"items-center\"}>Is Admin</TableCell>\n <TableCell header={true}>Default permissions</TableCell>\n </TableHeader>\n\n <TableBody>\n {roles && roles.map((role) => {\n const canCreateAll = role.isAdmin || role.defaultPermissions?.create;\n const canReadAll = role.isAdmin || role.defaultPermissions?.read;\n const canUpdateAll = role.isAdmin || role.defaultPermissions?.edit;\n const canDeleteAll = role.isAdmin || role.defaultPermissions?.delete;\n return (\n <TableRow\n key={role.name}\n onClick={() => {\n onRoleClicked(role);\n }}\n >\n <TableCell style={{ width: \"64px\" }}>\n {!role.isAdmin &&\n <Tooltip title={\"Delete this role\"}>\n <IconButton\n size={\"small\"}\n disabled={!editable}\n onClick={(event) => {\n event.stopPropagation();\n return setRoleToBeDeleted(role);\n }}>\n <DeleteIcon/>\n </IconButton>\n </Tooltip>}\n </TableCell>\n <TableCell>\n <RoleChip role={role}/>\n </TableCell>\n <TableCell className={\"items-center\"}>\n <Checkbox checked={role.isAdmin ?? false}/>\n </TableCell>\n <TableCell>\n <ul>\n {canCreateAll && <li>Create</li>}\n {canReadAll && <li>Read</li>}\n {canUpdateAll && <li>Update</li>}\n {canDeleteAll && <li>Delete</li>}\n </ul>\n </TableCell>\n </TableRow>\n );\n })}\n\n {(!roles || roles.length === 0) && <TableRow>\n <TableCell colspan={4}>\n <CenteredView className={\"flex flex-col gap-4 my-8 items-center\"}>\n <Typography variant={\"label\"}>\n You don't have any roles yet.\n </Typography>\n {allowDefaultRolesCreation && <Button variant={\"outlined\"}\n onClick={() => {\n DEFAULT_ROLES.forEach((role) => {\n saveRole(role);\n });\n }}>\n Create default roles\n </Button>}\n </CenteredView>\n </TableCell>\n </TableRow>}\n\n </TableBody>\n\n </Table>\n\n <DeleteConfirmationDialog\n open={Boolean(roleToBeDeleted)}\n loading={deleteInProgress}\n onAccept={() => {\n if (roleToBeDeleted) {\n setDeleteInProgress(true);\n deleteRole(roleToBeDeleted)\n .then(() => {\n setRoleToBeDeleted(undefined);\n })\n .finally(() => {\n setDeleteInProgress(false);\n })\n }\n }}\n onCancel={() => {\n setRoleToBeDeleted(undefined);\n }}\n title={<>Delete?</>}\n body={<>Are you sure you want to delete this role?</>}/>\n\n </div>;\n}\n","import React, { useCallback, useState } from \"react\";\n\nimport { Role, useNavigationController } from \"@firecms/core\";\nimport { AddIcon, Button, Container, Tooltip, Typography } from \"@firecms/ui\";\nimport { RolesTable } from \"./RolesTable\";\nimport { RolesDetailsForm } from \"./RolesDetailsForm\";\nimport { useUserManagement } from \"../../hooks\";\n\nexport const RolesView = React.memo(\n function RolesView({ children }: { children?: React.ReactNode }) {\n\n const { collections } = useNavigationController();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [selectedRole, setSelectedRole] = useState<Role | undefined>();\n\n const { canEditRoles } = useUserManagement();\n\n const onRoleClicked = useCallback((user: Role) => {\n setDialogOpen(true);\n setSelectedRole(user);\n }, []);\n\n const handleClose = () => {\n setSelectedRole(undefined);\n setDialogOpen(false);\n };\n\n return (\n <Container className=\"w-full flex flex-col py-4 gap-4\" maxWidth={\"6xl\"}>\n\n {children}\n\n <div className=\"flex items-center mt-12\">\n <Typography gutterBottom variant=\"h4\"\n className=\"flex-grow\"\n component=\"h4\">\n Roles\n </Typography>\n <Tooltip title={!canEditRoles ? \"Update plans to customise roles\" : undefined}>\n <Button\n size={\"large\"}\n disabled={!canEditRoles}\n startIcon={<AddIcon/>}\n onClick={() => setDialogOpen(true)}>\n Add role\n </Button>\n </Tooltip>\n </div>\n\n <RolesTable onRoleClicked={onRoleClicked} editable={Boolean(canEditRoles)}/>\n\n <RolesDetailsForm\n key={selectedRole?.id ?? \"new\"}\n open={dialogOpen}\n role={selectedRole}\n editable={canEditRoles}\n collections={collections}\n handleClose={handleClose}/>\n\n </Container>\n )\n });\n","import React, { useCallback } from \"react\";\nimport * as Yup from \"yup\";\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DoneIcon,\n LoadingButton,\n MultiSelect,\n MultiSelectItem,\n TextField,\n Typography,\n} from \"@firecms/ui\";\nimport { FieldCaption, Role, useAuthController, User, useSnackbarController } from \"@firecms/core\";\nimport { Formex, useCreateFormex } from \"@firecms/formex\";\n\nimport { areRolesEqual } from \"../../utils\";\nimport { useUserManagement } from \"../../hooks\";\nimport { RoleChip } from \"../roles\";\n\nexport const UserYupSchema = Yup.object().shape({\n displayName: Yup.string().required(\"Required\"),\n email: Yup.string().email().required(\"Required\"),\n roles: Yup.array().min(1)\n});\n\nfunction canUserBeEdited(loggedUser: User, user: User, users: User[], roles: Role[], prevUser?: User) {\n const admins = users.filter(u => u.roles?.map(r => r.id).includes(\"admin\"));\n const loggedUserIsAdmin = loggedUser.roles?.map(r => r.id).includes(\"admin\");\n const didRolesChange = !prevUser || !areRolesEqual(prevUser.roles ?? [], user.roles ?? []);\n\n if (didRolesChange && !loggedUserIsAdmin) {\n throw new Error(\"Only admins can change roles\");\n }\n\n // was the admin role removed\n const adminRoleRemoved = prevUser && prevUser.roles?.map(r => r.id).includes(\"admin\") && !user.roles?.map(r => r.id).includes(\"admin\");\n\n // avoid removing the last admin\n if (adminRoleRemoved && admins.length === 1) {\n throw new Error(\"There must be at least one admin\");\n }\n return true;\n}\n\nexport function UserDetailsForm({\n open,\n user: userProp,\n handleClose\n }: {\n open: boolean,\n user?: User,\n handleClose: () => void\n}) {\n\n const snackbarController = useSnackbarController();\n const {\n user: loggedInUser\n } = useAuthController();\n const {\n saveUser,\n users,\n roles,\n } = useUserManagement();\n const isNewUser = !userProp;\n\n const onUserUpdated = useCallback((savedUser: User): Promise<User> => {\n if (!loggedInUser) {\n throw new Error(\"Logged user not found\");\n }\n try {\n canUserBeEdited(loggedInUser, savedUser, users, roles, userProp);\n return saveUser(savedUser);\n } catch (e: any) {\n return Promise.reject(e);\n }\n }, [roles, saveUser, userProp, users, loggedInUser]);\n\n const formex = useCreateFormex({\n initialValues: userProp ?? {\n displayName: \"\",\n email: \"\",\n roles: roles.filter(r => r.id === \"editor\")\n } as User,\n validation: (values) => {\n return UserYupSchema.validate(values, { abortEarly: false })\n .then(() => {\n return {};\n }).catch((e) => {\n return e.inner.reduce((acc: any, error: any) => {\n acc[error.path] = error.message;\n return acc;\n }, {});\n });\n },\n onSubmit: (user: User, formexController) => {\n\n return onUserUpdated(user)\n .then(() => {\n handleClose();\n formexController.resetForm({\n values: user\n });\n }).catch((e) => {\n snackbarController.open({\n type: \"error\",\n message: e.message\n });\n });\n }\n });\n\n const {\n isSubmitting,\n touched,\n handleChange,\n values,\n errors,\n setFieldValue,\n dirty,\n handleSubmit,\n submitCount\n } = formex;\n\n return (\n <Dialog\n open={open}\n onOpenChange={(open) => !open ? handleClose() : undefined}\n maxWidth={\"4xl\"}\n >\n <Formex value={formex}>\n <form\n onSubmit={handleSubmit}\n autoComplete={\"off\"}\n noValidate\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\n height: \"100%\"\n }}>\n <DialogContent className=\"h-full flex-grow\">\n <div\n className=\"flex flex-row pt-4 pb-4\">\n <Typography variant={\"h4\"}\n className=\"flex-grow\">\n User\n </Typography>\n </div>\n\n <div className={\"grid grid-cols-12 gap-8\"}>\n\n <div className={\"col-span-12\"}>\n <TextField\n name=\"displayName\"\n required\n error={submitCount > 0 && Boolean(errors.displayName)}\n value={values.displayName ?? \"\"}\n onChange={handleChange}\n aria-describedby=\"name-helper-text\"\n label=\"Name\"\n />\n <FieldCaption>\n {submitCount > 0 && Boolean(errors.displayName) ? errors.displayName : \"Name of this user\"}\n </FieldCaption>\n </div>\n <div className={\"col-span-12\"}>\n <TextField\n required\n error={submitCount > 0 && Boolean(errors.email)}\n name=\"email\"\n value={values.email ?? \"\"}\n onChange={handleChange}\n aria-describedby=\"email-helper-text\"\n label=\"Email\"\n />\n <FieldCaption>\n {submitCount > 0 && Boolean(errors.email) ? errors.email : \"Email of this user\"}\n </FieldCaption>\n </div>\n <div className={\"col-span-12\"}>\n <MultiSelect\n label=\"Roles\"\n value={values.roles?.map(r => r.id) ?? []}\n onMultiValueChange={(value: string[]) => setFieldValue(\"roles\", value.map(id => roles.find(r => r.id === id) as Role))}\n renderValue={(value: string) => {\n const userRole = roles\n .find((role) => role.id === value);\n if (!userRole) return null;\n return <div className=\"flex flex-wrap space-x-2 space-y-2\">\n <RoleChip key={userRole?.id} role={userRole}/>\n </div>;\n }}>\n {roles.map(userRole => <MultiSelectItem key={userRole.id}\n value={userRole.id}>\n <RoleChip key={userRole?.id} role={userRole}/>\n </MultiSelectItem>)}\n </MultiSelect>\n </div>\n\n </div>\n\n </DialogContent>\n\n <DialogActions>\n\n <Button variant={\"text\"}\n onClick={() => {\n handleClose();\n }}>\n Cancel\n </Button>\n\n <LoadingButton\n variant=\"filled\"\n color=\"primary\"\n type=\"submit\"\n disabled={!dirty}\n loading={isSubmitting}\n startIcon={<DoneIcon/>}\n >\n {isNewUser ? \"Create user\" : \"Update\"}\n </LoadingButton>\n </DialogActions>\n </form>\n </Formex>\n\n </Dialog>\n );\n}\n","import { useState } from \"react\";\n\nimport { format } from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\n\nimport {\n defaultDateFormat,\n DeleteConfirmationDialog, Role,\n useAuthController,\n useCustomizationController, User,\n useSnackbarController\n} from \"@firecms/core\";\nimport {\n Button,\n CenteredView,\n DeleteIcon,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n Tooltip,\n Typography,\n} from \"@firecms/ui\";\nimport { useUserManagement } from \"../../hooks\";\nimport { RoleChip } from \"../roles\";\nimport { PersistedUser } from \"../../types\";\n\nexport function UsersTable({ onUserClicked }: {\n onUserClicked: (user: User) => void;\n}) {\n\n const {\n users,\n saveUser,\n deleteUser\n } = useUserManagement<PersistedUser>();\n\n const authController = useAuthController();\n const snackbarController = useSnackbarController();\n\n const customizationController = useCustomizationController();\n const dateUtilsLocale = customizationController?.locale ? locales[customizationController?.locale as keyof typeof locales] : undefined;\n const dateFormat: string = customizationController?.dateTimeFormat ?? defaultDateFormat;\n\n const [userToBeDeleted, setUserToBeDeleted] = useState<User | undefined>(undefined);\n const [deleteInProgress, setDeleteInProgress] = useState<boolean>(false);\n\n return (\n <div className=\"overflow-auto\">\n\n <Table>\n\n <TableHeader>\n <TableCell className=\"truncate w-16\"></TableCell>\n <TableCell>ID</TableCell>\n <TableCell>Email</TableCell>\n <TableCell>Name</TableCell>\n <TableCell>Roles</TableCell>\n <TableCell>Created on</TableCell>\n </TableHeader>\n <TableBody>\n {users && users.map((user) => {\n\n const userRoles: Role[] | undefined = user.roles;\n\n const formattedDate = user.created_on ? format(user.created_on, dateFormat, { locale: dateUtilsLocale }) : \"\";\n\n return (\n <TableRow\n key={\"row_\" + user.uid}\n onClick={() => {\n onUserClicked(user);\n }}\n >\n <TableCell className={\"w-10\"}>\n <Tooltip title={\"Delete this user\"}>\n <IconButton\n size={\"small\"}\n onClick={(event) => {\n event.stopPropagation();\n return setUserToBeDeleted(user);\n }}>\n <DeleteIcon/>\n </IconButton>\n </Tooltip>\n </TableCell>\n <TableCell>{user.uid}</TableCell>\n <TableCell>{user.email}</TableCell>\n <TableCell className={\"font-medium align-left\"}>{user.displayName}</TableCell>\n <TableCell className=\"align-left\">\n {userRoles\n ? <div className=\"flex flex-wrap gap-2\">\n {userRoles.map(userRole =>\n <RoleChip key={userRole?.id} role={userRole}/>\n )}\n </div>\n : null}\n </TableCell>\n <TableCell>{formattedDate}</TableCell>\n </TableRow>\n );\n })}\n\n {(!users || users.length === 0) && <TableRow>\n <TableCell colspan={6}>\n <CenteredView className={\"flex flex-col gap-4 my-8 items-center\"}>\n <Typography variant={\"label\"}>\n There are no users yet\n </Typography>\n <Button variant={\"outlined\"}\n onClick={() => {\n if (!authController.user?.uid) {\n throw Error(\"UsersTable, authController misconfiguration\");\n }\n saveUser({\n uid: authController.user?.uid,\n email: authController.user?.email,\n displayName: authController.user?.displayName,\n photoURL: authController.user?.photoURL,\n providerId: authController.user?.providerId,\n isAnonymous: authController.user?.isAnonymous,\n roles: [{ id: \"admin\", name: \"Admin\" }],\n created_on: new Date()\n })\n .then(() => {\n snackbarController.open({\n type: \"success\",\n message: \"User added successfully\"\n })\n })\n .catch((error) => {\n snackbarController.open({\n type: \"error\",\n message: \"Error adding user: \" + error.message,\n })\n });\n }}>\n\n Add the logged user as an admin\n </Button>\n </CenteredView>\n </TableCell>\n </TableRow>}\n\n </TableBody>\n </Table>\n\n <DeleteConfirmationDialog\n open={Boolean(userToBeDeleted)}\n loading={deleteInProgress}\n onAccept={() => {\n if (userToBeDeleted) {\n setDeleteInProgress(true);\n deleteUser(userToBeDeleted)\n .then(() => {\n setUserToBeDeleted(undefined);\n })\n .catch((error) => {\n snackbarController.open({\n type: \"error\",\n message: \"Error deleting user: \" + error.message,\n })\n })\n .finally(() => {\n setDeleteInProgress(false);\n })\n }\n }}\n onCancel={() => {\n setUserToBeDeleted(undefined);\n }}\n title={<>Delete?</>}\n body={<>Are you sure you want to delete this user?</>}/>\n </div>);\n}\n","import { AddIcon, Button, Container, Typography } from \"@firecms/ui\";\n\nimport { UsersTable } from \"./UsersTable\";\nimport { UserDetailsForm } from \"./UserDetailsForm\";\nimport React, { useCallback, useState } from \"react\";\nimport { useUserManagement } from \"../../hooks/useUserManagement\";\nimport { User } from \"@firecms/core\";\n\nexport const UsersView = function UsersView({ children }: { children?: React.ReactNode }) {\n\n const [dialogOpen, setDialogOpen] = useState<boolean>();\n const [selectedUser, setSelectedUser] = useState<User | undefined>();\n\n const { users, usersLimit } = useUserManagement();\n\n const reachedUsersLimit = usersLimit !== undefined && (users && users.length >= usersLimit);\n\n const onUserClicked = useCallback((user: User) => {\n setSelectedUser(user);\n setDialogOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setDialogOpen(false);\n setSelectedUser(undefined);\n }, []);\n\n return (\n <Container className=\"w-full flex flex-col py-4 gap-4\" maxWidth={\"6xl\"}>\n\n {children}\n\n <div\n className=\"flex items-center mt-12\">\n <Typography gutterBottom variant=\"h4\"\n className=\"flex-grow\"\n component=\"h4\">\n Users\n </Typography>\n <Button\n size={\"large\"}\n disabled={reachedUsersLimit}\n startIcon={<AddIcon/>}\n onClick={() => setDialogOpen(true)}>\n Add user\n </Button>\n </div>\n\n <UsersTable onUserClicked={onUserClicked}/>\n\n <UserDetailsForm\n key={selectedUser?.uid ?? \"new\"}\n open={dialogOpen ?? false}\n user={selectedUser}\n handleClose={handleClose}/>\n\n </Container>\n )\n};\n","import { FireCMSPlugin, useAuthController, useSnackbarController } from \"@firecms/core\";\nimport { UserManagementProvider } from \"./UserManagementProvider\";\nimport { PersistedUser, UserManagement } from \"./types\";\nimport { AddIcon, Button, Paper, Typography } from \"@firecms/ui\";\nimport { DEFAULT_ROLES } from \"./components/roles/default_roles\";\n\nexport function useUserManagementPlugin({ userManagement }: {\n userManagement: UserManagement,\n}): FireCMSPlugin {\n\n const noUsers = userManagement.users.length === 0;\n const noRoles = userManagement.roles.length === 0;\n\n return {\n key: \"user_management\",\n loading: userManagement.loading,\n\n homePage: {\n additionalChildrenStart: noUsers || noRoles\n ? <IntroWidget\n noUsers={noUsers}\n noRoles={noRoles}\n userManagement={userManagement}/>\n : undefined\n },\n provider: {\n Component: UserManagementProvider,\n props: {\n userManagement\n }\n }\n }\n}\n\nexport function IntroWidget({\n noUsers,\n noRoles,\n userManagement\n }: {\n noUsers: boolean;\n noRoles: boolean;\n userManagement: UserManagement<PersistedUser>;\n}) {\n\n const authController = useAuthController();\n const snackbarController = useSnackbarController();\n\n const buttonLabel = noUsers && noRoles\n ? \"Create default roles and add current user as admin\"\n : noUsers\n ? \"Add current user as admin\"\n : noRoles ? \"Create default roles\" : undefined;\n\n return (\n <Paper\n className={\"my-4 flex flex-col px-4 py-6 bg-white dark:bg-slate-800 gap-2\"}>\n <Typography variant={\"subtitle2\"} className={\"uppercase\"}>Create your users and roles</Typography>\n <Typography>\n You have no users or roles defined. You can create default roles and add the current user as admin.\n </Typography>\n <Button onClick={() => {\n if (!authController.user?.uid) {\n throw Error(\"UsersTable, authController misconfiguration\");\n }\n if (noUsers) {\n userManagement.saveUser({\n uid: authController.user?.uid,\n email: authController.user?.email,\n displayName: authController.user?.displayName,\n photoURL: authController.user?.photoURL,\n providerId: authController.user?.providerId,\n isAnonymous: authController.user?.isAnonymous,\n roles: [{\n id: \"admin\",\n name: \"Admin\"\n }],\n created_on: new Date()\n })\n .then(() => {\n snackbarController.open({\n type: \"success\",\n message: \"User added successfully\"\n })\n })\n .catch((error) => {\n snackbarController.open({\n type: \"error\",\n message: \"Error adding user: \" + error.message\n })\n });\n }\n if (noRoles) {\n DEFAULT_ROLES.forEach((role) => {\n userManagement.saveRole(role);\n });\n }\n }}>\n <AddIcon/>\n {buttonLabel}\n </Button>\n </Paper>\n );\n\n}\n","import { CMSView } from \"@firecms/core\";\nimport { RolesView, UsersView } from \"./components\";\n\nexport const userManagementAdminViews: CMSView[] = [\n {\n path: \"users\",\n name: \"CMS Users\",\n group: \"Admin\",\n icon: \"face\",\n view: <UsersView/>\n },\n {\n path: \"roles\",\n name: \"Roles\",\n group: \"Admin\",\n icon: \"gpp_good\",\n view: <RolesView/>\n }\n]\n"],"names":["role","values","errors","RolesView","open","UsersView"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/utils/permissions.ts","../src/utils/local_storage.ts","../src/utils/colors.ts","../src/hooks/useBuildUserManagement.tsx","../src/UserManagementProvider.tsx","../src/hooks/useUserManagement.tsx","../src/components/roles/RoleChip.tsx","../src/components/roles/RolesDetailsForm.tsx","../src/components/roles/default_roles.tsx","../src/components/roles/RolesTable.tsx","../src/components/roles/RolesView.tsx","../src/components/users/UserDetailsForm.tsx","../src/components/users/UsersTable.tsx","../src/components/users/UsersView.tsx","../src/useUserManagementPlugin.tsx","../src/admin_views.tsx"],"sourcesContent":["import { EntityCollection, Permissions, Role, User } from \"@firecms/core\";\n\nexport const RESERVED_GROUPS = [\"Admin\"];\n\nconst DEFAULT_PERMISSIONS = {\n read: false,\n edit: false,\n create: false,\n delete: false\n};\n\nexport function resolveUserRolePermissions<UserType extends User>\n({\n collection,\n user\n }: {\n collection: EntityCollection<any>,\n user: UserType | null\n}): Permissions {\n\n const roles = user?.roles;\n if (!roles) {\n return DEFAULT_PERMISSIONS;\n } else if (collection.ownerId === user?.uid) {\n return {\n read: true,\n create: true,\n edit: true,\n delete: true\n };\n } else {\n const basePermissions = {\n read: false,\n create: false,\n edit: false,\n delete: false\n };\n\n return roles\n .map(role => resolveCollectionRole(role, collection.id))\n .reduce(mergePermissions, basePermissions);\n }\n}\n\nfunction resolveCollectionRole(role: Role, id: string): Permissions {\n\n const basePermissions = {\n read: role.isAdmin || role.defaultPermissions?.read,\n create: role.isAdmin || role.defaultPermissions?.create,\n edit: role.isAdmin || role.defaultPermissions?.edit,\n delete: role.isAdmin || role.defaultPermissions?.delete\n };\n if (role.collectionPermissions && role.collectionPermissions[id]) {\n return mergePermissions(role.collectionPermissions[id], basePermissions);\n } else if (role.defaultPermissions) {\n return mergePermissions(role.defaultPermissions, basePermissions);\n } else {\n return basePermissions;\n }\n}\n\nconst mergePermissions = (permA: Permissions, permB: Permissions) => {\n return {\n read: permA.read || permB.read,\n create: permA.create || permB.create,\n edit: permA.edit || permB.edit,\n delete: permA.delete || permB.delete\n };\n}\n\nexport function getUserRoles(roles: Role[], fireCMSUser: User): Role[] | undefined {\n return !roles\n ? undefined\n : (fireCMSUser.roles\n ? fireCMSUser.roles\n .map(role => roles.find((r) => r.id === role.id))\n .filter(Boolean) as Role[]\n : []);\n}\n\nexport const areRolesEqual = (rolesA: Role[], rolesB: Role[]) => {\n const rolesAIds = rolesA.map(r => r.id);\n const rolesBIds = rolesB.map(r => r.id);\n return rolesAIds.length === rolesB.length && rolesAIds.every((role) => rolesBIds.includes(role));\n}\n","// const tokens = new Map<string, {\n// token: string,\n// expiry: Date\n// }>();\n\nexport function cacheDelegatedLoginToken(projectId: string, delegatedToken?: string) {\n if (!delegatedToken) {\n return;\n }\n\n const data = parseJwt(delegatedToken);\n // @ts-ignore\n const expiry = new Date(data.exp * 1000);\n localStorage.setItem(`auth_token::${projectId}`, JSON.stringify({\n token: delegatedToken,\n expiry\n }));\n\n}\n\nexport function getDelegatedLoginTokenFromCache(projectId: string) {\n const entry = localStorage.getItem(`auth_token::${projectId}`);\n if (entry) {\n const data = JSON.parse(entry);\n data.expiry = new Date(data.expiry);\n if (data.expiry > new Date()) {\n return data.token;\n }\n }\n return undefined;\n}\n\nexport function clearDelegatedLoginTokensCache() {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(\"auth_token::\")) {\n localStorage.removeItem(key);\n }\n }\n}\n\nfunction parseJwt(token?: string): object {\n if (!token) {\n throw new Error(\"No JWT token\");\n }\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const jsonPayload = decodeURIComponent(window.atob(base64).split(\"\").map(function (c) {\n return \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2);\n }).join(\"\"));\n\n return JSON.parse(jsonPayload);\n}\n","export function darkenColor(hexColor: string, darkenBy = 10): string {\n // Check input validity\n if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(hexColor)) {\n throw new Error(\"Invalid color format\");\n }\n\n // If shorthand form, convert to full form\n let color = hexColor.substring(1).split(\"\");\n if (color.length === 3) {\n color = [color[0], color[0], color[1], color[1], color[2], color[2]];\n }\n\n // Convert to RGB values\n let r = parseInt(color[0] + color[1], 16);\n let g = parseInt(color[2] + color[3], 16);\n let b = parseInt(color[4] + color[5], 16);\n\n // Reduce each color component by the specified percentage (darkenBy)\n r = Math.floor(r * (1 - darkenBy / 100));\n g = Math.floor(g * (1 - darkenBy / 100));\n b = Math.floor(b * (1 - darkenBy / 100));\n\n // Recombine into hex and return\n return \"#\" +\n (r < 16 ? \"0\" : \"\") + r.toString(16) +\n (g < 16 ? \"0\" : \"\") + g.toString(16) +\n (b < 16 ? \"0\" : \"\") + b.toString(16);\n}\n\nexport function hexToRgbaWithOpacity(hexColor: string, opacity = 10): string {\n // Check input validity\n if (!/^#([0-9A-Fa-f]{3}){1,2}$/.test(hexColor)) {\n throw new Error(\"Invalid color format\");\n }\n\n // If shorthand form, convert to full form\n let color = hexColor.substring(1).split(\"\");\n if (color.length === 3) {\n color = [color[0], color[0], color[1], color[1], color[2], color[2]];\n }\n\n // Convert to RGB values\n const r = parseInt(color[0] + color[1], 16);\n const g = parseInt(color[2] + color[3], 16);\n const b = parseInt(color[4] + color[5], 16);\n\n // Convert opacity to a decimal for CSS\n const alpha = opacity / 100;\n\n // Construct and return the RGBA color\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n","import React, { useCallback, useEffect } from \"react\";\nimport equal from \"react-fast-compare\"\n\nimport { UserManagement } from \"../types\";\nimport { Authenticator, DataSourceDelegate, Entity, PermissionsBuilder, Role, User } from \"@firecms/core\";\nimport { resolveUserRolePermissions } from \"../utils\";\n\ntype UserWithRoleIds = User & { roles: string[] };\n\nexport interface UserManagementParams {\n\n /**\n * The delegate in charge of persisting the data.\n */\n dataSourceDelegate?: DataSourceDelegate;\n\n /**\n * Path where the plugin users configuration is stored.\n * Default: __FIRECMS/config/users\n * You can specify a different path if you want to store the user management configuration in a different place.\n * Please keep in mind that the FireCMS users are not necessarily the same as the Firebase users (but they can be).\n * The path should be relative to the root of the database, and should always have an odd number of segments.\n */\n usersPath?: string;\n\n /**\n * Path where the plugin roles configuration is stored.\n * Default: __FIRECMS/config/roles\n */\n rolesPath?: string;\n\n /**\n * Maximum number of users that can be created.\n */\n usersLimit?: number;\n\n /**\n * Can the logged user edit roles\n */\n canEditRoles?: boolean;\n\n /**\n * If there are no roles in the database, provide a button to create the default roles.\n */\n allowDefaultRolesCreation?: boolean;\n\n /**\n * Include the collection config permissions in the user management system.\n */\n includeCollectionConfigPermissions?: boolean;\n\n}\n\n/**\n * This hook is used to build a user management object that can be used to\n * manage users and roles in a Firestore backend.\n * @param dataSourceDelegate\n * @param usersPath\n * @param rolesPath\n * @param usersLimit\n * @param canEditRoles\n * @param allowDefaultRolesCreation\n * @param includeCollectionConfigPermissions\n */\nexport function useBuildUserManagement({\n dataSourceDelegate,\n usersPath = \"__FIRECMS/config/users\",\n rolesPath = \"__FIRECMS/config/roles\",\n usersLimit,\n canEditRoles = true,\n allowDefaultRolesCreation,\n includeCollectionConfigPermissions\n }: UserManagementParams): UserManagement {\n\n const [rolesLoading, setRolesLoading] = React.useState<boolean>(true);\n const [usersLoading, setUsersLoading] = React.useState<boolean>(true);\n const [roles, setRoles] = React.useState<Role[]>([]);\n const [usersWithRoleIds, setUsersWithRoleIds] = React.useState<UserWithRoleIds[]>([]);\n\n const users = usersWithRoleIds.map(u => ({\n ...u,\n roles: roles.filter(r => u.roles?.includes(r.id))\n }) as User);\n\n const [rolesError, setRolesError] = React.useState<Error | undefined>();\n const [usersError, setUsersError] = React.useState<Error | undefined>();\n\n const loading = rolesLoading || usersLoading;\n\n useEffect(() => {\n if (!dataSourceDelegate || !rolesPath) return;\n if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;\n\n return dataSourceDelegate.listenCollection?.({\n path: rolesPath,\n onUpdate(entities: Entity<any>[]): void {\n setRolesError(undefined);\n try {\n const newRoles = entityToRoles(entities);\n if (!equal(newRoles, roles))\n setRoles(newRoles);\n } catch (e) {\n setRoles([]);\n console.error(\"Error loading roles\", e);\n setRolesError(e as Error);\n }\n setRolesLoading(false);\n },\n onError(e: any): void {\n setRoles([]);\n console.error(\"Error loading roles\", e);\n setRolesError(e);\n setRolesLoading(false);\n }\n });\n\n }, [dataSourceDelegate?.initialised, rolesPath]);\n\n useEffect(() => {\n if (!dataSourceDelegate || !usersPath) return;\n if (dataSourceDelegate.initialised !== undefined && !dataSourceDelegate.initialised) return;\n\n return dataSourceDelegate.listenCollection?.({\n path: usersPath,\n onUpdate(entities: Entity<any>[]): void {\n setUsersError(undefined);\n try {\n const newUsers = entitiesToUsers(entities);\n if (!equal(newUsers, usersWithRoleIds))\n setUsersWithRoleIds(newUsers);\n } catch (e) {\n setUsersWithRoleIds([]);\n console.error(\"Error loading users\", e);\n setUsersError(e as Error);\n }\n setUsersLoading(false);\n },\n onError(e: any): void {\n setUsersWithRoleIds([]);\n console.error(\"Error loading users\", e);\n setUsersError(e);\n setUsersLoading(false);\n }\n });\n\n }, [dataSourceDelegate?.initialised, usersPath]);\n\n const saveUser = useCallback(async (user: User): Promise<User> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!usersPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n\n console.debug(\"Persisting user\", user);\n\n const roleIds = user.roles?.map(r => r.id);\n const {\n uid,\n ...userData\n } = user;\n const data = {\n ...userData,\n roles: roleIds\n };\n if (uid) {\n return dataSourceDelegate.saveEntity({\n status: \"existing\",\n path: usersPath,\n entityId: uid,\n values: data\n }).then(() => user);\n } else {\n return dataSourceDelegate.saveEntity({\n status: \"new\",\n path: usersPath,\n values: data\n }).then(() => user);\n }\n }, [usersPath, dataSourceDelegate?.initialised]);\n\n const saveRole = useCallback((role: Role): Promise<void> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!rolesPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n console.debug(\"Persisting role\", role);\n const {\n id,\n ...roleData\n } = role;\n return dataSourceDelegate.saveEntity({\n status: \"existing\",\n path: rolesPath,\n entityId: id,\n values: roleData\n }).then(() => {\n return;\n });\n }, [rolesPath, dataSourceDelegate?.initialised]);\n\n const deleteUser = useCallback(async (user: User): Promise<void> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!usersPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n console.debug(\"Deleting\", user);\n const { uid } = user;\n const entity: Entity<any> = {\n path: usersPath,\n id: uid,\n values: {}\n };\n await dataSourceDelegate.deleteEntity({ entity })\n }, [usersPath, dataSourceDelegate?.initialised]);\n\n const deleteRole = useCallback(async (role: Role): Promise<void> => {\n if (!dataSourceDelegate) throw Error(\"useBuildUserManagement Firebase not initialised\");\n if (!rolesPath) throw Error(\"useBuildUserManagement Firestore not initialised\");\n console.debug(\"Deleting\", role);\n const { id } = role;\n const entity: Entity<any> = {\n path: usersPath,\n id: id,\n values: {}\n };\n await dataSourceDelegate.deleteEntity({ entity })\n }, [rolesPath, dataSourceDelegate?.initialised]);\n\n const collectionPermissions: PermissionsBuilder = useCallback(({\n collection,\n user\n }) => resolveUserRolePermissions({\n collection,\n user\n }), []);\n\n const defineRolesFor: ((user: User) => Role[] | undefined) = useCallback((user) => {\n if (!users) throw Error(\"Users not loaded\");\n const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());\n return mgmtUser?.roles;\n }, [users]);\n\n const authenticator: Authenticator = useCallback(({ user }) => {\n console.debug(\"Authenticating user\", user);\n\n if (loading) {\n console.warn(\"User management is still loading\");\n return false;\n }\n\n // This is an example of how you can link the access system to the user management plugin\n if (users.length === 0) {\n return true; // If there are no users created yet, we allow access to every user\n }\n\n const mgmtUser = users.find(u => u.email?.toLowerCase() === user?.email?.toLowerCase());\n if (mgmtUser) {\n return true;\n }\n\n throw Error(\"Could not find a user with the provided email in the user management system.\");\n }, [loading, users]);\n\n const isAdmin = roles.some(r => r.id === \"admin\");\n\n return {\n loading,\n roles,\n users,\n saveUser,\n saveRole,\n rolesError,\n deleteUser,\n deleteRole,\n usersLimit,\n usersError,\n isAdmin,\n canEditRoles: canEditRoles === undefined ? true : canEditRoles,\n allowDefaultRolesCreation: allowDefaultRolesCreation === undefined ? true : allowDefaultRolesCreation,\n includeCollectionConfigPermissions: Boolean(includeCollectionConfigPermissions),\n collectionPermissions,\n defineRolesFor,\n authenticator\n }\n}\n\nconst entitiesToUsers = (docs: Entity<Omit<UserWithRoleIds, \"id\">>[]): (UserWithRoleIds)[] => {\n return docs.map((doc) => {\n const data = doc.values as any;\n const newVar = {\n uid: doc.id,\n ...data,\n created_on: data?.created_on,\n updated_on: data?.updated_on\n };\n return newVar as (UserWithRoleIds);\n });\n}\n\nconst entityToRoles = (entities: Entity<Omit<Role, \"id\">>[]): Role[] => {\n return entities.map((doc) => ({\n id: doc.id,\n ...doc.values\n } as Role));\n}\n","import React, { PropsWithChildren } from \"react\";\nimport { UserManagement } from \"./types\";\nimport { User } from \"@firecms/core\";\n\nexport const UserManagementContext = React.createContext<UserManagement<any>>({} as any);\n\nexport interface UserManagementProviderProps<U extends User = User> {\n userManagement: UserManagement<U>\n}\n\nexport function UserManagementProvider<U extends User = User>({\n children,\n userManagement\n }: PropsWithChildren<UserManagementProviderProps<U>>) {\n return (\n <UserManagementContext.Provider value={userManagement}>\n {children}\n </UserManagementContext.Provider>\n );\n};\n","import { useContext } from \"react\";\nimport { UserManagement } from \"../types\";\nimport { UserManagementContext } from \"../UserManagementProvider\";\nimport { User } from \"@firecms/core\";\nexport const useUserManagement = <USER extends User>() => useContext<UserManagement<USER>>(UserManagementContext);\n","import { Chip, getColorSchemeForSeed } from \"@firecms/ui\";\nimport { Role } from \"@firecms/core\";\n\nexport type RoleChipProps = {\n role: Role;\n}\n\nexport function RoleChip({ role }: RoleChipProps) {\n let colorScheme;\n if (role.isAdmin) {\n colorScheme = \"blueDarker\";\n } else if (role.id === \"editor\") {\n colorScheme = \"yellowLight\";\n } else if (role.id === \"viewer\") {\n colorScheme = \"grayLight\";\n } else {\n colorScheme = getColorSchemeForSeed(role.id);\n }\n\n return (\n <Chip\n colorScheme={colorScheme}\n key={role.id}>\n {role.name}\n </Chip>\n );\n\n}\n","import React, { useCallback, useState } from \"react\";\nimport * as Yup from \"yup\";\n\nimport { EntityCollection, FieldCaption, Role, toSnakeCase, } from \"@firecms/core\";\nimport {\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DoneIcon,\n LoadingButton,\n Paper,\n Select,\n SelectItem,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n TextField,\n Tooltip,\n Typography\n} from \"@firecms/ui\";\nimport { useUserManagement } from \"../../hooks\";\nimport { Formex, getIn, useCreateFormex } from \"@firecms/formex\";\n\nexport const RoleYupSchema = Yup.object().shape({\n id: Yup.string().required(\"Required\"),\n name: Yup.string().required(\"Required\")\n});\n\nexport function RolesDetailsForm({\n open,\n role,\n editable,\n handleClose,\n collections\n }: {\n open: boolean,\n editable?: boolean,\n role?: Role,\n handleClose: () => void,\n collections?: EntityCollection[]\n}) {\n\n const { saveRole } = useUserManagement();\n const isNewRole = !role;\n\n const [savingError, setSavingError] = useState<Error | undefined>();\n\n const onRoleUpdated = useCallback((role: Role) => {\n setSavingError(undefined);\n return saveRole(role);\n }, [saveRole]);\n\n const formex = useCreateFormex({\n initialValues: role ?? {\n name: \"\"\n } as Role,\n onSubmit: (role: Role, formexController) => {\n return onRoleUpdated(role)\n .then(() => {\n formexController.resetForm({\n values: role\n });\n handleClose();\n })\n .catch(e => setSavingError(e));\n },\n validation: (values) => {\n return RoleYupSchema.validate(values, { abortEarly: false })\n .then(() => ({}))\n .catch((e) => {\n const errors: Record<string, string> = {};\n e.inner.forEach((error: any) => {\n errors[error.path] = error.message;\n });\n return errors;\n });\n }\n\n });\n\n const {\n isSubmitting,\n touched,\n values,\n errors,\n handleChange,\n setFieldValue,\n dirty,\n setFieldTouched\n } = formex;\n\n const isAdmin = values.isAdmin ?? false;\n const defaultCreate = values.defaultPermissions?.create ?? false;\n const defaultRead = values.defaultPermissions?.read ?? false;\n const defaultEdit = values.defaultPermissions?.edit ?? false;\n const defaultDelete = values.defaultPermissions?.delete ?? false;\n\n React.useEffect(() => {\n const idTouched = getIn(touched, \"id\");\n if (!idTouched && values.name) {\n setFieldValue(\"id\", toSnakeCase(values.name))\n }\n }, [touched, values.name]);\n\n return (\n <Dialog\n open={open}\n maxWidth={\"4xl\"}\n >\n <Formex value={formex}>\n <form noValidate\n autoComplete={\"off\"}\n onSubmit={formex.handleSubmit}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\n height: \"100%\"\n }}>\n <DialogContent className=\"flex-grow\">\n <div\n className=\"flex flex-row pt-12 pb-8\">\n <Typography variant={\"h4\"}\n className=\"flex-grow\">\n Role\n </Typography>\n </div>\n\n <div className={\"grid grid-cols-12 gap-8\"}>\n\n <div className={\"col-span-12 md:col-span-8\"}>\n <TextField\n name=\"name\"\n required\n error={touched.name && Boolean(errors.name)}\n value={values.name}\n disabled={isAdmin || !editable}\n onChange={handleChange}\n aria-describedby=\"name-helper-text\"\n label=\"Name\"\n />\n <FieldCaption>\n {touched.name && Boolean(errors.name) ? errors.name : \"Name of this role\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <TextField\n name=\"id\"\n required\n error={touched.id && Boolean(errors.id)}\n value={values.id}\n disabled={!isNewRole || !editable}\n onChange={(e) => {\n handleChange(e);\n setFieldTouched(\"id\", true)\n }}\n aria-describedby=\"id-helper-text\"\n label=\"ID\"\n />\n <FieldCaption>\n {touched.id && Boolean(errors.id) ? errors.id : \"ID of this role\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12\"}>\n <Paper\n\n className=\"bg-inherit\">\n <Table>\n <TableHeader>\n <TableCell></TableCell>\n <TableCell\n align=\"center\">Create\n entities\n </TableCell>\n <TableCell\n align=\"center\">Read\n entities\n </TableCell>\n <TableCell\n align=\"center\">Update\n entities\n </TableCell>\n <TableCell\n align=\"center\">Delete\n entities\n </TableCell>\n </TableHeader>\n\n <TableBody>\n <TableRow>\n <TableCell\n scope=\"row\">\n <strong>All\n collections</strong>\n </TableCell>\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Create entities in collections\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultCreate) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.create\", checked)}\n />\n </Tooltip>\n </TableCell>\n\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Access all data in every collection\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultRead) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.read\", checked)}\n />\n </Tooltip>\n </TableCell>\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Update data in any collection\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultEdit) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.edit\", checked)}\n />\n </Tooltip>\n </TableCell>\n <TableCell\n align=\"center\">\n <Tooltip\n title=\"Delete data in any collection\">\n <Checkbox\n disabled={isAdmin || !editable}\n checked={(isAdmin || defaultDelete) ?? false}\n onCheckedChange={(checked) => setFieldValue(\"defaultPermissions.delete\", checked)}\n />\n\n </Tooltip>\n </TableCell>\n </TableRow>\n {collections && collections.map((col) => (\n <TableRow key={col.name}>\n <TableCell\n scope=\"row\">\n {col.name}\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultCreate || !editable}\n checked={(isAdmin || defaultCreate || getIn(values, `collectionPermissions.${col.path}.create`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.create`, checked)}/>\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultRead || !editable}\n checked={(isAdmin || defaultRead || getIn(values, `collectionPermissions.${col.path}.read`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.read`, checked)}/>\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultEdit || !editable}\n checked={(isAdmin || defaultEdit || getIn(values, `collectionPermissions.${col.path}.edit`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.edit`, checked)}/>\n </TableCell>\n <TableCell\n align=\"center\">\n <Checkbox\n disabled={isAdmin || defaultDelete || !editable}\n checked={(isAdmin || defaultDelete || getIn(values, `collectionPermissions.${col.path}.delete`)) ?? false}\n onCheckedChange={(checked) => setFieldValue(`collectionPermissions.${col.path}.delete`, checked)}/>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </Paper>\n <FieldCaption>\n You can customise the permissions\n that the users related to this\n role can perform in the entities\n of each collection\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <Select\n error={touched.config && Boolean(errors.config)}\n id=\"createCollections\"\n name=\"createCollections\"\n label=\"Create collections\"\n position={\"item-aligned\"}\n disabled={isAdmin || !editable}\n onChange={(event) => setFieldValue(\"config.createCollections\", event.target.value === \"true\")}\n value={isAdmin || values.config?.createCollections ? \"true\" : \"false\"}\n renderValue={(value: any) => value === \"true\" ? \"Yes\" : \"No\"}\n >\n <SelectItem\n value={\"true\"}> Yes </SelectItem>\n <SelectItem\n value={\"false\"}> No </SelectItem>\n </Select>\n\n <FieldCaption>\n {touched.config && Boolean(errors.config) ? errors.config : \"Can the user create collections\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <Select\n error={touched.config && Boolean(errors.config)}\n id=\"editCollections\"\n name=\"editCollections\"\n label=\"Edit collections\"\n disabled={isAdmin || !editable}\n position={\"item-aligned\"}\n onChange={(event) => setFieldValue(\"config.editCollections\", event.target.value === \"own\" ? \"own\" : event.target.value === \"true\")}\n value={isAdmin ? \"true\" : (values.config?.editCollections === \"own\" ? \"own\" : (values.config?.editCollections ? \"true\" : \"false\"))}\n renderValue={(value: any) => value === \"own\" ? \"Own\" : (value === \"true\" ? \"Yes\" : \"No\")}\n >\n <SelectItem\n value={\"true\"}> Yes </SelectItem>\n <SelectItem\n value={\"false\"}> No </SelectItem>\n <SelectItem\n value={\"own\"}> Only\n his/her own </SelectItem>\n </Select>\n\n <FieldCaption>\n {touched.config && Boolean(errors.config) ? errors.config : \"Can the user edit collections\"}\n </FieldCaption>\n </div>\n\n <div className={\"col-span-12 md:col-span-4\"}>\n <Select\n error={touched.config && Boolean(errors.config)}\n id=\"deleteCollections\"\n name=\"deleteCollections\"\n label=\"Delete collections\"\n disabled={isAdmin || !editable}\n position={\"item-aligned\"}\n onChange={(event) => setFieldValue(\"config.deleteCollections\", event.target.value === \"own\" ? \"own\" : event.target.value === \"true\")}\n value={isAdmin ? \"true\" : (values.config?.deleteCollections === \"own\" ? \"own\" : (values.config?.deleteCollections ? \"true\" : \"false\"))}\n renderValue={(value: any) => value === \"own\" ? \"Own\" : (value === \"true\" ? \"Yes\" : \"No\")}\n >\n <SelectItem\n value={\"true\"}> Yes </SelectItem>\n <SelectItem\n value={\"false\"}> No </SelectItem>\n <SelectItem\n value={\"own\"}> Only\n his/her own </SelectItem>\n </Select>\n\n <FieldCaption>\n {touched.config && Boolean(errors.config) ? errors.config : \"Can the user delete collections\"}\n </FieldCaption>\n\n </div>\n\n </div>\n </DialogContent>\n\n <DialogActions position={\"sticky\"}>\n {savingError && <Typography className={\"text-red-500\"}>\n There was an error saving this role\n </Typography>}\n <Button variant={\"text\"}\n onClick={() => {\n handleClose();\n }}>\n Cancel\n </Button>\n <LoadingButton\n variant=\"filled\"\n color=\"primary\"\n type=\"submit\"\n disabled={!dirty}\n loading={isSubmitting}\n startIcon={<DoneIcon/>}\n >\n {isNewRole ? \"Create role\" : \"Update\"}\n </LoadingButton>\n </DialogActions>\n </form>\n\n </Formex>\n </Dialog>\n );\n}\n","import { Role } from \"@firecms/core\";\n\nexport const DEFAULT_ROLES: Role[] = [\n {\n id: \"admin\",\n name: \"Admin\",\n isAdmin: true\n },\n {\n id: \"editor\",\n name: \"Editor\",\n isAdmin: false,\n defaultPermissions: {\n read: true,\n create: true,\n edit: true,\n delete: true\n },\n config: {\n createCollections: true,\n editCollections: \"own\",\n deleteCollections: \"own\"\n }\n },\n {\n id: \"viewer\",\n name: \"Viewer\",\n isAdmin: false,\n defaultPermissions: {\n read: true,\n create: false,\n edit: false,\n delete: false\n }\n }\n];\n","import { useState } from \"react\";\nimport {\n Button,\n CenteredView,\n Checkbox,\n DeleteIcon,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n Tooltip,\n Typography\n} from \"@firecms/ui\";\nimport { DeleteConfirmationDialog, Role } from \"@firecms/core\";\nimport { useUserManagement } from \"../../hooks\";\nimport { RoleChip } from \"./RoleChip\";\nimport { DEFAULT_ROLES } from \"./default_roles\";\n\nexport function RolesTable({\n onRoleClicked,\n editable\n }: {\n onRoleClicked: (role: Role) => void;\n editable: boolean;\n}) {\n\n const {\n roles,\n saveRole,\n deleteRole,\n allowDefaultRolesCreation\n } = useUserManagement();\n\n const [roleToBeDeleted, setRoleToBeDeleted] = useState<Role | undefined>(undefined);\n const [deleteInProgress, setDeleteInProgress] = useState<boolean>(false);\n\n return <div\n className=\"w-full overflow-auto\">\n <Table>\n <TableHeader>\n <TableCell header={true} className=\"w-16\"></TableCell>\n <TableCell header={true}>Role</TableCell>\n <TableCell header={true} className={\"items-center\"}>Is Admin</TableCell>\n <TableCell header={true}>Default permissions</TableCell>\n </TableHeader>\n\n <TableBody>\n {roles && roles.map((role) => {\n const canCreateAll = role.isAdmin || role.defaultPermissions?.create;\n const canReadAll = role.isAdmin || role.defaultPermissions?.read;\n const canUpdateAll = role.isAdmin || role.defaultPermissions?.edit;\n const canDeleteAll = role.isAdmin || role.defaultPermissions?.delete;\n return (\n <TableRow\n key={role.name}\n onClick={() => {\n onRoleClicked(role);\n }}\n >\n <TableCell style={{ width: \"64px\" }}>\n {!role.isAdmin &&\n <Tooltip title={\"Delete this role\"}>\n <IconButton\n size={\"small\"}\n disabled={!editable}\n onClick={(event) => {\n event.stopPropagation();\n return setRoleToBeDeleted(role);\n }}>\n <DeleteIcon/>\n </IconButton>\n </Tooltip>}\n </TableCell>\n <TableCell>\n <RoleChip role={role}/>\n </TableCell>\n <TableCell className={\"items-center\"}>\n <Checkbox checked={role.isAdmin ?? false}/>\n </TableCell>\n <TableCell>\n <ul>\n {canCreateAll && <li>Create</li>}\n {canReadAll && <li>Read</li>}\n {canUpdateAll && <li>Update</li>}\n {canDeleteAll && <li>Delete</li>}\n </ul>\n </TableCell>\n </TableRow>\n );\n })}\n\n {(!roles || roles.length === 0) && <TableRow>\n <TableCell colspan={4}>\n <CenteredView className={\"flex flex-col gap-4 my-8 items-center\"}>\n <Typography variant={\"label\"}>\n You don't have any roles yet.\n </Typography>\n {allowDefaultRolesCreation && <Button variant={\"outlined\"}\n onClick={() => {\n DEFAULT_ROLES.forEach((role) => {\n saveRole(role);\n });\n }}>\n Create default roles\n </Button>}\n </CenteredView>\n </TableCell>\n </TableRow>}\n\n </TableBody>\n\n </Table>\n\n <DeleteConfirmationDialog\n open={Boolean(roleToBeDeleted)}\n loading={deleteInProgress}\n onAccept={() => {\n if (roleToBeDeleted) {\n setDeleteInProgress(true);\n deleteRole(roleToBeDeleted)\n .then(() => {\n setRoleToBeDeleted(undefined);\n })\n .finally(() => {\n setDeleteInProgress(false);\n })\n }\n }}\n onCancel={() => {\n setRoleToBeDeleted(undefined);\n }}\n title={<>Delete?</>}\n body={<>Are you sure you want to delete this role?</>}/>\n\n </div>;\n}\n","import React, { useCallback, useState } from \"react\";\n\nimport { Role, useNavigationController } from \"@firecms/core\";\nimport { AddIcon, Button, Container, Tooltip, Typography } from \"@firecms/ui\";\nimport { RolesTable } from \"./RolesTable\";\nimport { RolesDetailsForm } from \"./RolesDetailsForm\";\nimport { useUserManagement } from \"../../hooks\";\n\nexport const RolesView = React.memo(\n function RolesView({ children }: { children?: React.ReactNode }) {\n\n const { collections } = useNavigationController();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [selectedRole, setSelectedRole] = useState<Role | undefined>();\n\n const { canEditRoles } = useUserManagement();\n\n const onRoleClicked = useCallback((user: Role) => {\n setDialogOpen(true);\n setSelectedRole(user);\n }, []);\n\n const handleClose = () => {\n setSelectedRole(undefined);\n setDialogOpen(false);\n };\n\n return (\n <Container className=\"w-full flex flex-col py-4 gap-4\" maxWidth={\"6xl\"}>\n\n {children}\n\n <div className=\"flex items-center mt-12\">\n <Typography gutterBottom variant=\"h4\"\n className=\"flex-grow\"\n component=\"h4\">\n Roles\n </Typography>\n <Tooltip title={!canEditRoles ? \"Update plans to customise roles\" : undefined}>\n <Button\n size={\"large\"}\n disabled={!canEditRoles}\n startIcon={<AddIcon/>}\n onClick={() => setDialogOpen(true)}>\n Add role\n </Button>\n </Tooltip>\n </div>\n\n <RolesTable onRoleClicked={onRoleClicked} editable={Boolean(canEditRoles)}/>\n\n <RolesDetailsForm\n key={selectedRole?.id ?? \"new\"}\n open={dialogOpen}\n role={selectedRole}\n editable={canEditRoles}\n collections={collections}\n handleClose={handleClose}/>\n\n </Container>\n )\n });\n","import React, { useCallback } from \"react\";\nimport * as Yup from \"yup\";\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DoneIcon,\n LoadingButton,\n MultiSelect,\n MultiSelectItem,\n TextField,\n Typography,\n} from \"@firecms/ui\";\nimport { FieldCaption, Role, useAuthController, User, useSnackbarController } from \"@firecms/core\";\nimport { Formex, useCreateFormex } from \"@firecms/formex\";\n\nimport { areRolesEqual } from \"../../utils\";\nimport { useUserManagement } from \"../../hooks\";\nimport { RoleChip } from \"../roles\";\n\nexport const UserYupSchema = Yup.object().shape({\n displayName: Yup.string().required(\"Required\"),\n email: Yup.string().email().required(\"Required\"),\n roles: Yup.array().min(1)\n});\n\nfunction canUserBeEdited(loggedUser: User, user: User, users: User[], roles: Role[], prevUser?: User) {\n const admins = users.filter(u => u.roles?.map(r => r.id).includes(\"admin\"));\n const loggedUserIsAdmin = loggedUser.roles?.map(r => r.id).includes(\"admin\");\n const didRolesChange = !prevUser || !areRolesEqual(prevUser.roles ?? [], user.roles ?? []);\n\n if (didRolesChange && !loggedUserIsAdmin) {\n throw new Error(\"Only admins can change roles\");\n }\n\n // was the admin role removed\n const adminRoleRemoved = prevUser && prevUser.roles?.map(r => r.id).includes(\"admin\") && !user.roles?.map(r => r.id).includes(\"admin\");\n\n // avoid removing the last admin\n if (adminRoleRemoved && admins.length === 1) {\n throw new Error(\"There must be at least one admin\");\n }\n return true;\n}\n\nexport function UserDetailsForm({\n open,\n user: userProp,\n handleClose\n }: {\n open: boolean,\n user?: User,\n handleClose: () => void\n}) {\n\n const snackbarController = useSnackbarController();\n const {\n user: loggedInUser\n } = useAuthController();\n const {\n saveUser,\n users,\n roles,\n } = useUserManagement();\n const isNewUser = !userProp;\n\n const onUserUpdated = useCallback((savedUser: User): Promise<User> => {\n if (!loggedInUser) {\n throw new Error(\"Logged user not found\");\n }\n try {\n canUserBeEdited(loggedInUser, savedUser, users, roles, userProp);\n return saveUser(savedUser);\n } catch (e: any) {\n return Promise.reject(e);\n }\n }, [roles, saveUser, userProp, users, loggedInUser]);\n\n const formex = useCreateFormex({\n initialValues: userProp ?? {\n displayName: \"\",\n email: \"\",\n roles: roles.filter(r => r.id === \"editor\")\n } as User,\n validation: (values) => {\n return UserYupSchema.validate(values, { abortEarly: false })\n .then(() => {\n return {};\n }).catch((e) => {\n return e.inner.reduce((acc: any, error: any) => {\n acc[error.path] = error.message;\n return acc;\n }, {});\n });\n },\n onSubmit: (user: User, formexController) => {\n\n return onUserUpdated(user)\n .then(() => {\n handleClose();\n formexController.resetForm({\n values: user\n });\n }).catch((e) => {\n snackbarController.open({\n type: \"error\",\n message: e.message\n });\n });\n }\n });\n\n const {\n isSubmitting,\n touched,\n handleChange,\n values,\n errors,\n setFieldValue,\n dirty,\n handleSubmit,\n submitCount\n } = formex;\n\n return (\n <Dialog\n open={open}\n onOpenChange={(open) => !open ? handleClose() : undefined}\n maxWidth={\"4xl\"}\n >\n <Formex value={formex}>\n <form\n onSubmit={handleSubmit}\n autoComplete={\"off\"}\n noValidate\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\n height: \"100%\"\n }}>\n <DialogContent className=\"h-full flex-grow\">\n <div\n className=\"flex flex-row pt-4 pb-4\">\n <Typography variant={\"h4\"}\n className=\"flex-grow\">\n User\n </Typography>\n </div>\n\n <div className={\"grid grid-cols-12 gap-8\"}>\n\n <div className={\"col-span-12\"}>\n <TextField\n name=\"displayName\"\n required\n error={submitCount > 0 && Boolean(errors.displayName)}\n value={values.displayName ?? \"\"}\n onChange={handleChange}\n aria-describedby=\"name-helper-text\"\n label=\"Name\"\n />\n <FieldCaption>\n {submitCount > 0 && Boolean(errors.displayName) ? errors.displayName : \"Name of this user\"}\n </FieldCaption>\n </div>\n <div className={\"col-span-12\"}>\n <TextField\n required\n error={submitCount > 0 && Boolean(errors.email)}\n name=\"email\"\n value={values.email ?? \"\"}\n onChange={handleChange}\n aria-describedby=\"email-helper-text\"\n label=\"Email\"\n />\n <FieldCaption>\n {submitCount > 0 && Boolean(errors.email) ? errors.email : \"Email of this user\"}\n </FieldCaption>\n </div>\n <div className={\"col-span-12\"}>\n <MultiSelect\n label=\"Roles\"\n value={values.roles?.map(r => r.id) ?? []}\n onMultiValueChange={(value: string[]) => setFieldValue(\"roles\", value.map(id => roles.find(r => r.id === id) as Role))}\n renderValue={(value: string) => {\n const userRole = roles\n .find((role) => role.id === value);\n if (!userRole) return null;\n return <div className=\"flex flex-wrap space-x-2 space-y-2\">\n <RoleChip key={userRole?.id} role={userRole}/>\n </div>;\n }}>\n {roles.map(userRole => <MultiSelectItem key={userRole.id}\n value={userRole.id}>\n <RoleChip key={userRole?.id} role={userRole}/>\n </MultiSelectItem>)}\n </MultiSelect>\n </div>\n\n </div>\n\n </DialogContent>\n\n <DialogActions>\n\n <Button variant={\"text\"}\n onClick={() => {\n handleClose();\n }}>\n Cancel\n </Button>\n\n <LoadingButton\n variant=\"filled\"\n color=\"primary\"\n type=\"submit\"\n disabled={!dirty}\n loading={isSubmitting}\n startIcon={<DoneIcon/>}\n >\n {isNewUser ? \"Create user\" : \"Update\"}\n </LoadingButton>\n </DialogActions>\n </form>\n </Formex>\n\n </Dialog>\n );\n}\n","import { useState } from \"react\";\n\nimport { format } from \"date-fns\";\nimport * as locales from \"date-fns/locale\";\n\nimport {\n defaultDateFormat,\n DeleteConfirmationDialog, Role,\n useAuthController,\n useCustomizationController, User,\n useSnackbarController\n} from \"@firecms/core\";\nimport {\n Button,\n CenteredView,\n DeleteIcon,\n IconButton,\n Table,\n TableBody,\n TableCell,\n TableHeader,\n TableRow,\n Tooltip,\n Typography,\n} from \"@firecms/ui\";\nimport { useUserManagement } from \"../../hooks\";\nimport { RoleChip } from \"../roles\";\nimport { PersistedUser } from \"../../types\";\n\nexport function UsersTable({ onUserClicked }: {\n onUserClicked: (user: User) => void;\n}) {\n\n const {\n users,\n saveUser,\n deleteUser\n } = useUserManagement<PersistedUser>();\n\n const authController = useAuthController();\n const snackbarController = useSnackbarController();\n\n const customizationController = useCustomizationController();\n const dateUtilsLocale = customizationController?.locale ? locales[customizationController?.locale as keyof typeof locales] : undefined;\n const dateFormat: string = customizationController?.dateTimeFormat ?? defaultDateFormat;\n\n const [userToBeDeleted, setUserToBeDeleted] = useState<User | undefined>(undefined);\n const [deleteInProgress, setDeleteInProgress] = useState<boolean>(false);\n\n return (\n <div className=\"overflow-auto\">\n\n <Table>\n\n <TableHeader>\n <TableCell className=\"truncate w-16\"></TableCell>\n <TableCell>ID</TableCell>\n <TableCell>Email</TableCell>\n <TableCell>Name</TableCell>\n <TableCell>Roles</TableCell>\n <TableCell>Created on</TableCell>\n </TableHeader>\n <TableBody>\n {users && users.map((user) => {\n\n const userRoles: Role[] | undefined = user.roles;\n\n const formattedDate = user.created_on ? format(user.created_on, dateFormat, { locale: dateUtilsLocale }) : \"\";\n\n return (\n <TableRow\n key={\"row_\" + user.uid}\n onClick={() => {\n onUserClicked(user);\n }}\n >\n <TableCell className={\"w-10\"}>\n <Tooltip title={\"Delete this user\"}>\n <IconButton\n size={\"small\"}\n onClick={(event) => {\n event.stopPropagation();\n return setUserToBeDeleted(user);\n }}>\n <DeleteIcon/>\n </IconButton>\n </Tooltip>\n </TableCell>\n <TableCell>{user.uid}</TableCell>\n <TableCell>{user.email}</TableCell>\n <TableCell className={\"font-medium align-left\"}>{user.displayName}</TableCell>\n <TableCell className=\"align-left\">\n {userRoles\n ? <div className=\"flex flex-wrap gap-2\">\n {userRoles.map(userRole =>\n <RoleChip key={userRole?.id} role={userRole}/>\n )}\n </div>\n : null}\n </TableCell>\n <TableCell>{formattedDate}</TableCell>\n </TableRow>\n );\n })}\n\n {(!users || users.length === 0) && <TableRow>\n <TableCell colspan={6}>\n <CenteredView className={\"flex flex-col gap-4 my-8 items-center\"}>\n <Typography variant={\"label\"}>\n There are no users yet\n </Typography>\n <Button variant={\"outlined\"}\n onClick={() => {\n if (!authController.user?.uid) {\n throw Error(\"UsersTable, authController misconfiguration\");\n }\n saveUser({\n uid: authController.user?.uid,\n email: authController.user?.email,\n displayName: authController.user?.displayName,\n photoURL: authController.user?.photoURL,\n providerId: authController.user?.providerId,\n isAnonymous: authController.user?.isAnonymous,\n roles: [{ id: \"admin\", name: \"Admin\" }],\n created_on: new Date()\n })\n .then(() => {\n snackbarController.open({\n type: \"success\",\n message: \"User added successfully\"\n })\n })\n .catch((error) => {\n snackbarController.open({\n type: \"error\",\n message: \"Error adding user: \" + error.message,\n })\n });\n }}>\n\n Add the logged user as an admin\n </Button>\n </CenteredView>\n </TableCell>\n </TableRow>}\n\n </TableBody>\n </Table>\n\n <DeleteConfirmationDialog\n open={Boolean(userToBeDeleted)}\n loading={deleteInProgress}\n onAccept={() => {\n if (userToBeDeleted) {\n setDeleteInProgress(true);\n deleteUser(userToBeDeleted)\n .then(() => {\n setUserToBeDeleted(undefined);\n })\n .catch((error) => {\n snackbarController.open({\n type: \"error\",\n message: \"Error deleting user: \" + error.message,\n })\n })\n .finally(() => {\n setDeleteInProgress(false);\n })\n }\n }}\n onCancel={() => {\n setUserToBeDeleted(undefined);\n }}\n title={<>Delete?</>}\n body={<>Are you sure you want to delete this user?</>}/>\n </div>);\n}\n","import { AddIcon, Button, Container, Typography } from \"@firecms/ui\";\n\nimport { UsersTable } from \"./UsersTable\";\nimport { UserDetailsForm } from \"./UserDetailsForm\";\nimport React, { useCallback, useState } from \"react\";\nimport { useUserManagement } from \"../../hooks/useUserManagement\";\nimport { User } from \"@firecms/core\";\n\nexport const UsersView = function UsersView({ children }: { children?: React.ReactNode }) {\n\n const [dialogOpen, setDialogOpen] = useState<boolean>();\n const [selectedUser, setSelectedUser] = useState<User | undefined>();\n\n const { users, usersLimit } = useUserManagement();\n\n const reachedUsersLimit = usersLimit !== undefined && (users && users.length >= usersLimit);\n\n const onUserClicked = useCallback((user: User) => {\n setSelectedUser(user);\n setDialogOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setDialogOpen(false);\n setSelectedUser(undefined);\n }, []);\n\n return (\n <Container className=\"w-full flex flex-col py-4 gap-4\" maxWidth={\"6xl\"}>\n\n {children}\n\n <div\n className=\"flex items-center mt-12\">\n <Typography gutterBottom variant=\"h4\"\n className=\"flex-grow\"\n component=\"h4\">\n Users\n </Typography>\n <Button\n size={\"large\"}\n disabled={reachedUsersLimit}\n startIcon={<AddIcon/>}\n onClick={() => setDialogOpen(true)}>\n Add user\n </Button>\n </div>\n\n <UsersTable onUserClicked={onUserClicked}/>\n\n <UserDetailsForm\n key={selectedUser?.uid ?? \"new\"}\n open={dialogOpen ?? false}\n user={selectedUser}\n handleClose={handleClose}/>\n\n </Container>\n )\n};\n","import { FireCMSPlugin, useAuthController, useSnackbarController } from \"@firecms/core\";\nimport { UserManagementProvider } from \"./UserManagementProvider\";\nimport { PersistedUser, UserManagement } from \"./types\";\nimport { AddIcon, Button, Paper, Typography } from \"@firecms/ui\";\nimport { DEFAULT_ROLES } from \"./components/roles/default_roles\";\n\nexport function useUserManagementPlugin({ userManagement }: {\n userManagement: UserManagement,\n}): FireCMSPlugin {\n\n const noUsers = userManagement.users.length === 0;\n const noRoles = userManagement.roles.length === 0;\n\n return {\n key: \"user_management\",\n loading: userManagement.loading,\n\n homePage: {\n additionalChildrenStart: noUsers || noRoles\n ? <IntroWidget\n noUsers={noUsers}\n noRoles={noRoles}\n userManagement={userManagement}/>\n : undefined\n },\n provider: {\n Component: UserManagementProvider,\n props: {\n userManagement\n }\n }\n }\n}\n\nexport function IntroWidget({\n noUsers,\n noRoles,\n userManagement\n }: {\n noUsers: boolean;\n noRoles: boolean;\n userManagement: UserManagement<PersistedUser>;\n}) {\n\n const authController = useAuthController();\n const snackbarController = useSnackbarController();\n\n const buttonLabel = noUsers && noRoles\n ? \"Create default roles and add current user as admin\"\n : noUsers\n ? \"Add current user as admin\"\n : noRoles ? \"Create default roles\" : undefined;\n\n return (\n <Paper\n className={\"my-4 flex flex-col px-4 py-6 bg-white dark:bg-slate-800 gap-2\"}>\n <Typography variant={\"subtitle2\"} className={\"uppercase\"}>Create your users and roles</Typography>\n <Typography>\n You have no users or roles defined. You can create default roles and add the current user as admin.\n </Typography>\n <Button onClick={() => {\n if (!authController.user?.uid) {\n throw Error(\"UsersTable, authController misconfiguration\");\n }\n if (noUsers) {\n userManagement.saveUser({\n uid: authController.user?.uid,\n email: authController.user?.email,\n displayName: authController.user?.displayName,\n photoURL: authController.user?.photoURL,\n providerId: authController.user?.providerId,\n isAnonymous: authController.user?.isAnonymous,\n roles: [{\n id: \"admin\",\n name: \"Admin\"\n }],\n created_on: new Date()\n })\n .then(() => {\n snackbarController.open({\n type: \"success\",\n message: \"User added successfully\"\n })\n })\n .catch((error) => {\n snackbarController.open({\n type: \"error\",\n message: \"Error adding user: \" + error.message\n })\n });\n }\n if (noRoles) {\n DEFAULT_ROLES.forEach((role) => {\n userManagement.saveRole(role);\n });\n }\n }}>\n <AddIcon/>\n {buttonLabel}\n </Button>\n </Paper>\n );\n\n}\n","import { CMSView } from \"@firecms/core\";\nimport { RolesView, UsersView } from \"./components\";\n\nexport const userManagementAdminViews: CMSView[] = [\n {\n path: \"users\",\n name: \"CMS Users\",\n group: \"Admin\",\n icon: \"face\",\n view: <UsersView/>\n },\n {\n path: \"roles\",\n name: \"Roles\",\n group: \"Admin\",\n icon: \"gpp_good\",\n view: <RolesView/>\n }\n]\n"],"names":["role","values","errors","RolesView","open","UsersView"],"mappings":"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"}
|