@firecms/user_management 3.0.0-canary.84 → 3.0.0-canary.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- export * from "./useFirestoreUserManagement";
1
+ export * from "./useBuildUserManagement";
2
2
  export * from "./useUserManagement";
@@ -1,17 +1,16 @@
1
- import { FirebaseApp } from "@firebase/app";
2
1
  import { UserManagement } from "../types";
2
+ import { DataSourceDelegate } from "@firecms/core";
3
3
  export interface UserManagementParams {
4
4
  /**
5
- * The Firebase app to use for the user management. The config will be saved in the Firestore
6
- * collection indicated by `configPath`.
5
+ * The delegate in charge of persisting the data.
7
6
  */
8
- firebaseApp?: FirebaseApp;
7
+ dataSourceDelegate?: DataSourceDelegate;
9
8
  /**
10
9
  * Path where the plugin users configuration is stored.
11
10
  * Default: __FIRECMS/config/users
12
11
  * You can specify a different path if you want to store the user management configuration in a different place.
13
12
  * Please keep in mind that the FireCMS users are not necessarily the same as the Firebase users (but they can be).
14
- * The path should be relative to the root of the Firestore database, and should always have an odd number of segments.
13
+ * The path should be relative to the root of the database, and should always have an odd number of segments.
15
14
  */
16
15
  usersPath?: string;
17
16
  /**
@@ -39,10 +38,12 @@ export interface UserManagementParams {
39
38
  /**
40
39
  * This hook is used to build a user management object that can be used to
41
40
  * manage users and roles in a Firestore backend.
42
- * @param backendFirebaseApp
41
+ * @param dataSourceDelegate
43
42
  * @param usersPath
44
43
  * @param rolesPath
45
44
  * @param usersLimit
46
45
  * @param canEditRoles
46
+ * @param allowDefaultRolesCreation
47
+ * @param includeCollectionConfigPermissions
47
48
  */
48
- export declare function useFirestoreUserManagement({ firebaseApp, usersPath, rolesPath, usersLimit, canEditRoles, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementParams): UserManagement;
49
+ export declare function useBuildUserManagement({ dataSourceDelegate, usersPath, rolesPath, usersLimit, canEditRoles, allowDefaultRolesCreation, includeCollectionConfigPermissions }: UserManagementParams): UserManagement;
package/dist/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useCallback, useContext, useState } from "react";
2
- import { getFirestore, onSnapshot, collection, setDoc, doc, addDoc, deleteDoc } from "@firebase/firestore";
2
+ import equal from "react-fast-compare";
3
3
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
4
4
  import { getColorSchemeForSeed, Chip, Dialog, DialogContent, Typography, TextField, Paper, Table, TableHeader, TableCell, TableBody, TableRow, Tooltip, Checkbox, Select, SelectItem, DialogActions, Button, LoadingButton, DoneIcon, IconButton, DeleteIcon, CenteredView, Container, AddIcon, MultiSelect, MultiSelectItem } from "@firecms/ui";
5
5
  import * as Yup from "yup";
@@ -15,13 +15,13 @@ const DEFAULT_PERMISSIONS = {
15
15
  delete: false
16
16
  };
17
17
  function resolveUserRolePermissions({
18
- collection: collection2,
18
+ collection,
19
19
  user
20
20
  }) {
21
21
  const roles = user?.roles;
22
22
  if (!roles) {
23
23
  return DEFAULT_PERMISSIONS;
24
- } else if (collection2.ownerId === user?.uid) {
24
+ } else if (collection.ownerId === user?.uid) {
25
25
  return {
26
26
  read: true,
27
27
  create: true,
@@ -35,7 +35,7 @@ function resolveUserRolePermissions({
35
35
  edit: false,
36
36
  delete: false
37
37
  };
38
- return roles.map((role) => resolveCollectionRole(role, collection2.id)).reduce(mergePermissions, basePermissions);
38
+ return roles.map((role) => resolveCollectionRole(role, collection.id)).reduce(mergePermissions, basePermissions);
39
39
  }
40
40
  }
41
41
  function resolveCollectionRole(role, id) {
@@ -140,8 +140,8 @@ function hexToRgbaWithOpacity(hexColor, opacity = 10) {
140
140
  const alpha = opacity / 100;
141
141
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
142
142
  }
143
- function useFirestoreUserManagement({
144
- firebaseApp,
143
+ function useBuildUserManagement({
144
+ dataSourceDelegate,
145
145
  usersPath = "__FIRECMS/config/users",
146
146
  rolesPath = "__FIRECMS/config/roles",
147
147
  usersLimit,
@@ -161,59 +161,56 @@ function useFirestoreUserManagement({
161
161
  const [usersError, setUsersError] = React.useState();
162
162
  const loading = rolesLoading || usersLoading;
163
163
  useEffect(() => {
164
- if (!firebaseApp || !rolesPath) return;
165
- const firestore = getFirestore(firebaseApp);
166
- return onSnapshot(
167
- collection(firestore, rolesPath),
168
- {
169
- next: (snapshot) => {
170
- setRolesError(void 0);
171
- try {
172
- const newRoles = docsToRoles(snapshot.docs);
164
+ if (!dataSourceDelegate || !rolesPath) return;
165
+ if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
166
+ return dataSourceDelegate.listenCollection?.({
167
+ path: rolesPath,
168
+ onUpdate(entities) {
169
+ setRolesError(void 0);
170
+ try {
171
+ const newRoles = entityToRoles(entities);
172
+ if (!equal(newRoles, roles))
173
173
  setRoles(newRoles);
174
- } catch (e) {
175
- console.error("Error loading roles", e);
176
- setRolesError(e);
177
- }
178
- setRolesLoading(false);
179
- },
180
- error: (e) => {
174
+ } catch (e) {
181
175
  console.error("Error loading roles", e);
182
176
  setRolesError(e);
183
- setRolesLoading(false);
184
177
  }
178
+ setRolesLoading(false);
179
+ },
180
+ onError(e) {
181
+ console.error("Error loading roles", e);
182
+ setRolesError(e);
183
+ setRolesLoading(false);
185
184
  }
186
- );
187
- }, [firebaseApp, rolesPath]);
185
+ });
186
+ }, [dataSourceDelegate, rolesPath]);
188
187
  useEffect(() => {
189
- if (!firebaseApp || !usersPath) return;
190
- const firestore = getFirestore(firebaseApp);
191
- return onSnapshot(
192
- collection(firestore, usersPath),
193
- {
194
- next: (snapshot) => {
195
- setUsersError(void 0);
196
- try {
197
- const newUsers = docsToUsers(snapshot.docs);
188
+ if (!dataSourceDelegate || !usersPath) return;
189
+ if (dataSourceDelegate.initialised !== void 0 && !dataSourceDelegate.initialised) return;
190
+ return dataSourceDelegate.listenCollection?.({
191
+ path: usersPath,
192
+ onUpdate(entities) {
193
+ setUsersError(void 0);
194
+ try {
195
+ const newUsers = entitiesToUsers(entities);
196
+ if (!equal(newUsers, usersWithRoleIds))
198
197
  setUsersWithRoleIds(newUsers);
199
- } catch (e) {
200
- console.error("Error loading users", e);
201
- setUsersError(e);
202
- }
203
- setUsersLoading(false);
204
- },
205
- error: (e) => {
198
+ } catch (e) {
206
199
  console.error("Error loading users", e);
207
200
  setUsersError(e);
208
- setUsersLoading(false);
209
201
  }
202
+ setUsersLoading(false);
203
+ },
204
+ onError(e) {
205
+ console.error("Error loading users", e);
206
+ setUsersError(e);
207
+ setUsersLoading(false);
210
208
  }
211
- );
212
- }, [firebaseApp, usersPath]);
209
+ });
210
+ }, [dataSourceDelegate, usersPath]);
213
211
  const saveUser = useCallback(async (user) => {
214
- if (!firebaseApp) throw Error("useFirestoreUserManagement Firebase not initialised");
215
- const firestore = getFirestore(firebaseApp);
216
- if (!firestore || !usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
212
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
213
+ if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
217
214
  console.debug("Persisting user", user);
218
215
  const roleIds = user.roles?.map((r) => r.id);
219
216
  const {
@@ -225,45 +222,66 @@ function useFirestoreUserManagement({
225
222
  roles: roleIds
226
223
  };
227
224
  if (uid) {
228
- return setDoc(doc(firestore, usersPath, uid), data, { merge: true }).then(() => user);
225
+ return dataSourceDelegate.saveEntity({
226
+ status: "existing",
227
+ path: usersPath,
228
+ entityId: uid,
229
+ values: data
230
+ }).then(() => user);
229
231
  } else {
230
- return addDoc(collection(firestore, usersPath), data).then(() => user);
232
+ return dataSourceDelegate.saveEntity({
233
+ status: "new",
234
+ path: usersPath,
235
+ values: data
236
+ }).then(() => user);
231
237
  }
232
- }, [usersPath, firebaseApp]);
238
+ }, [usersPath, dataSourceDelegate]);
233
239
  const saveRole = useCallback((role) => {
234
- if (!firebaseApp) throw Error("useFirestoreUserManagement Firebase not initialised");
235
- const firestore = getFirestore(firebaseApp);
236
- if (!firestore || !rolesPath) throw Error("useFirestoreUserManagement Firestore not initialised");
240
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
241
+ if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
237
242
  console.debug("Persisting role", role);
238
243
  const {
239
244
  id,
240
245
  ...roleData
241
246
  } = role;
242
- const ref = doc(firestore, rolesPath, id);
243
- return setDoc(ref, roleData, { merge: true });
244
- }, [rolesPath, firebaseApp]);
247
+ return dataSourceDelegate.saveEntity({
248
+ status: "existing",
249
+ path: rolesPath,
250
+ entityId: id,
251
+ values: roleData
252
+ }).then(() => {
253
+ return;
254
+ });
255
+ }, [rolesPath, dataSourceDelegate]);
245
256
  const deleteUser = useCallback(async (user) => {
246
- if (!firebaseApp) throw Error("useFirestoreUserManagement Firebase not initialised");
247
- const firestore = getFirestore(firebaseApp);
248
- if (!firestore || !usersPath) throw Error("useFirestoreUserManagement Firestore not initialised");
257
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
258
+ if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
249
259
  console.debug("Deleting", user);
250
260
  const { uid } = user;
251
- return deleteDoc(doc(firestore, usersPath, uid));
252
- }, [usersPath, firebaseApp]);
253
- const deleteRole = useCallback((role) => {
254
- if (!firebaseApp) throw Error("useFirestoreUserManagement Firebase not initialised");
255
- const firestore = getFirestore(firebaseApp);
256
- if (!firestore || !rolesPath) throw Error("useFirestoreUserManagement Firestore not initialised");
261
+ const entity = {
262
+ path: usersPath,
263
+ id: uid,
264
+ values: {}
265
+ };
266
+ await dataSourceDelegate.deleteEntity({ entity });
267
+ }, [usersPath, dataSourceDelegate]);
268
+ const deleteRole = useCallback(async (role) => {
269
+ if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
270
+ if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
257
271
  console.debug("Deleting", role);
258
272
  const { id } = role;
259
- const ref = doc(firestore, rolesPath, id);
260
- return deleteDoc(ref);
261
- }, [rolesPath, firebaseApp]);
273
+ const entity = {
274
+ path: usersPath,
275
+ id,
276
+ values: {}
277
+ };
278
+ await dataSourceDelegate.deleteEntity({ entity });
279
+ }, [rolesPath, dataSourceDelegate]);
262
280
  const collectionPermissions = useCallback(({
263
- collection: collection2,
281
+ collection,
264
282
  user
265
283
  }) => resolveUserRolePermissions({
266
- collection: collection2,
284
+ collection,
267
285
  user
268
286
  }), []);
269
287
  const defineRolesFor = useCallback((user) => {
@@ -307,22 +325,22 @@ function useFirestoreUserManagement({
307
325
  authenticator
308
326
  };
309
327
  }
310
- const docsToUsers = (docs) => {
311
- return docs.map((doc2) => {
312
- const data = doc2.data();
328
+ const entitiesToUsers = (docs) => {
329
+ return docs.map((doc) => {
330
+ const data = doc.values;
313
331
  const newVar = {
314
- uid: doc2.id,
332
+ uid: doc.id,
315
333
  ...data,
316
- created_on: data?.created_on?.toDate(),
317
- updated_on: data?.updated_on?.toDate()
334
+ created_on: data?.created_on,
335
+ updated_on: data?.updated_on
318
336
  };
319
337
  return newVar;
320
338
  });
321
339
  };
322
- const docsToRoles = (docs) => {
323
- return docs.map((doc2) => ({
324
- id: doc2.id,
325
- ...doc2.data()
340
+ const entityToRoles = (entities) => {
341
+ return entities.map((doc) => ({
342
+ id: doc.id,
343
+ ...doc.values
326
344
  }));
327
345
  };
328
346
  const UserManagementContext = React.createContext({});
@@ -1519,7 +1537,7 @@ export {
1519
1537
  getUserRoles,
1520
1538
  hexToRgbaWithOpacity,
1521
1539
  resolveUserRolePermissions,
1522
- useFirestoreUserManagement,
1540
+ useBuildUserManagement,
1523
1541
  useUserManagement,
1524
1542
  useUserManagementPlugin,
1525
1543
  userManagementAdminViews