@rebasepro/client-firebase 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/RebaseFirebaseAppProps.d.ts +2 -2
- package/dist/hooks/useBuildUserManagement.d.ts +1 -0
- package/dist/hooks/useFirestoreDriver.d.ts +3 -3
- package/dist/index.es.js +328 -313
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +326 -311
- package/dist/index.umd.js.map +1 -1
- package/dist/types/text_search.d.ts +3 -3
- package/dist/utils/collections_firestore.d.ts +3 -3
- package/package.json +19 -19
- package/src/components/RebaseFirebaseApp.tsx +10 -5
- package/src/components/RebaseFirebaseAppProps.tsx +2 -2
- package/src/hooks/useBuildUserManagement.tsx +27 -28
- package/src/hooks/useFirebaseRealTimeDBDelegate.ts +47 -52
- package/src/hooks/useFirebaseStorageSource.ts +2 -2
- package/src/hooks/useFirestoreDriver.ts +380 -355
- package/src/types/text_search.ts +3 -3
- package/src/utils/collections_firestore.ts +5 -5
- package/src/utils/database.ts +2 -2
- package/src/utils/local_text_search_controller.ts +6 -6
- package/src/utils/pinecone.ts +2 -2
- package/src/utils/rebase_search_controller.ts +3 -3
- package/src/utils/text_search_controller.ts +2 -2
package/dist/index.es.js
CHANGED
|
@@ -4,7 +4,7 @@ import { FacebookAuthProvider, GithubAuthProvider, GoogleAuthProvider, OAuthProv
|
|
|
4
4
|
import { deleteObject, getDownloadURL, getMetadata, getStorage, list, ref, uploadBytesResumable } from "@firebase/storage";
|
|
5
5
|
import { deleteApp, getApps, initializeApp } from "@firebase/app";
|
|
6
6
|
import { getToken, initializeAppCheck } from "@firebase/app-check";
|
|
7
|
-
import { EntityReference, GeoPoint } from "@rebasepro/types";
|
|
7
|
+
import { DEFAULT_DATA_SOURCE_KEY, EntityReference, GeoPoint } from "@rebasepro/types";
|
|
8
8
|
import { DocumentReference, GeoPoint as GeoPoint$1, Timestamp, VectorValue, collection, deleteDoc, deleteField, doc, getCountFromServer, getDoc, getDocs, getFirestore, limit, onSnapshot, orderBy, query, serverTimestamp, setDoc, startAfter, vector, where } from "@firebase/firestore";
|
|
9
9
|
import { COLLECTION_PATH_SEPARATOR, buildRebaseData, sortProperties, stripCollectionPath } from "@rebasepro/common";
|
|
10
10
|
import Fuse from "fuse.js";
|
|
@@ -12,7 +12,7 @@ import { getFunctions, httpsCallable } from "@firebase/functions";
|
|
|
12
12
|
import { get, getDatabase, limitToFirst, onValue, orderByChild, orderByKey, push, query as query$1, ref as ref$1, remove, set, startAt } from "@firebase/database";
|
|
13
13
|
import { removeUndefined } from "@rebasepro/utils";
|
|
14
14
|
import { AdminModeControllerProvider, ErrorView, ModeControllerProvider, Rebase, RebaseLogo, RebaseRoutes, SnackbarProvider, useBrowserTitleAndIcon, useBuildAdminModeController, useBuildLocalConfigurationPersistence, useBuildModeController, useModeController, useSnackbarController } from "@rebasepro/core";
|
|
15
|
-
import { AppBar, CollectionRegistryContext, Drawer, NavigationStateContext, RebaseRoute, Scaffold, SideDialogs,
|
|
15
|
+
import { AppBar, CollectionRegistryContext, Drawer, NavigationStateContext, RebaseRoute, Scaffold, SideDialogs, SidePanelProvider, UrlContext, useBuildCollectionRegistryController, useBuildNavigationStateController, useBuildUrlController } from "@rebasepro/admin";
|
|
16
16
|
import { ArrowLeftIcon, Button, CenteredView, CircularProgress, CircularProgressCenter, IconButton, LoadingButton, MailIcon, PhoneIcon, TextField, Typography, UserIcon, cls, iconSize } from "@rebasepro/ui";
|
|
17
17
|
import { Navigate, Outlet, Route } from "react-router-dom";
|
|
18
18
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -262,8 +262,8 @@ function useFirebaseStorageSource({ firebaseApp, bucketUrl }) {
|
|
|
262
262
|
}, 5e3);
|
|
263
263
|
};
|
|
264
264
|
setProgressTimeout();
|
|
265
|
-
uploadTask.on("state_changed", (
|
|
266
|
-
const progress =
|
|
265
|
+
uploadTask.on("state_changed", (entity) => {
|
|
266
|
+
const progress = entity.bytesTransferred / entity.totalBytes * 100;
|
|
267
267
|
if (progress > lastProgress) {
|
|
268
268
|
lastProgress = progress;
|
|
269
269
|
setProgressTimeout();
|
|
@@ -586,8 +586,8 @@ function normalizePropertiesEnumValues(properties, sortObjectFormat = false) {
|
|
|
586
586
|
//#region src/utils/database.ts
|
|
587
587
|
async function getFirestoreDataInPath(firebaseApp, path, parentPaths, limit$2) {
|
|
588
588
|
const firestore = getFirestore(firebaseApp);
|
|
589
|
-
if (!parentPaths || parentPaths.length === 0) return getDocs(query(collection(firestore, path), limit(limit$2))).then((
|
|
590
|
-
return
|
|
589
|
+
if (!parentPaths || parentPaths.length === 0) return getDocs(query(collection(firestore, path), limit(limit$2))).then((queryEntity) => {
|
|
590
|
+
return queryEntity.docs.map((doc) => doc.data());
|
|
591
591
|
});
|
|
592
592
|
else {
|
|
593
593
|
let currentDocs = void 0;
|
|
@@ -699,9 +699,9 @@ var localSearchControllerBuilder = ({ firebaseApp }) => {
|
|
|
699
699
|
if (collectionProp) {
|
|
700
700
|
console.debug("Init local search controller", path);
|
|
701
701
|
listeners[path] = onSnapshot(query(collection(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path)), {
|
|
702
|
-
next: (
|
|
703
|
-
if (
|
|
704
|
-
const docs =
|
|
702
|
+
next: (entity) => {
|
|
703
|
+
if (entity.metadata.fromCache && entity.metadata.hasPendingWrites) return;
|
|
704
|
+
const docs = entity.docs.map((doc) => ({
|
|
705
705
|
id: doc.id,
|
|
706
706
|
...doc.data()
|
|
707
707
|
}));
|
|
@@ -968,6 +968,15 @@ function useFirestoreDriver({ firebaseApp, textSearchControllerBuilder, firestor
|
|
|
968
968
|
const queryParams = [];
|
|
969
969
|
if (filter) Object.entries(filter).filter(([_, entry]) => !!entry).forEach(([key, filterParameter]) => {
|
|
970
970
|
const [op, value] = filterParameter;
|
|
971
|
+
if (op === "is-null") {
|
|
972
|
+
queryParams.push(where(key, "==", null));
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
if (op === "is-not-null") {
|
|
976
|
+
queryParams.push(where(key, "!=", null));
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
if (op === "like" || op === "ilike" || op === "not-like" || op === "not-ilike") throw new Error(`Firestore does not support the "${op}" operator (SQL pattern matching). Use a full-text search index or the collection's searchString instead.`);
|
|
971
980
|
queryParams.push(where(key, op, cmsToFirestoreModel(value, firestore)));
|
|
972
981
|
});
|
|
973
982
|
if (orderBy$1 && order) queryParams.push(orderBy(orderBy$1, order));
|
|
@@ -975,19 +984,19 @@ function useFirestoreDriver({ firebaseApp, textSearchControllerBuilder, firestor
|
|
|
975
984
|
if (limit$1) queryParams.push(limit(limit$1));
|
|
976
985
|
return query(collectionReference, ...queryParams);
|
|
977
986
|
}, [firebaseApp]);
|
|
978
|
-
const getAndBuildEntity = useCallback((path,
|
|
987
|
+
const getAndBuildEntity = useCallback((path, id, databaseId) => {
|
|
979
988
|
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
980
|
-
return getDoc(doc(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path, String(
|
|
981
|
-
if (!
|
|
982
|
-
return
|
|
989
|
+
return getDoc(doc(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path, String(id))).then((docEntity) => {
|
|
990
|
+
if (!docEntity.exists()) return;
|
|
991
|
+
return createRowFromDocument(docEntity);
|
|
983
992
|
});
|
|
984
993
|
}, [firebaseApp]);
|
|
985
|
-
const
|
|
994
|
+
const listenOne = useCallback(({ path, id, collection, onUpdate, onError }) => {
|
|
986
995
|
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
987
996
|
const databaseId = collection?.databaseId;
|
|
988
|
-
return onSnapshot(doc(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path, String(
|
|
989
|
-
next: (
|
|
990
|
-
onUpdate(
|
|
997
|
+
return onSnapshot(doc(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path, String(id)), {
|
|
998
|
+
next: (docEntity) => {
|
|
999
|
+
onUpdate(docEntity.exists() ? createRowFromDocument(docEntity) : null);
|
|
991
1000
|
},
|
|
992
1001
|
error: onError
|
|
993
1002
|
});
|
|
@@ -1010,22 +1019,23 @@ function useFirestoreDriver({ firebaseApp, textSearchControllerBuilder, firestor
|
|
|
1010
1019
|
subscriptions = [];
|
|
1011
1020
|
onUpdate([]);
|
|
1012
1021
|
}
|
|
1013
|
-
const
|
|
1022
|
+
const rows = [];
|
|
1014
1023
|
const addedEntitiesSet = /* @__PURE__ */ new Set();
|
|
1015
|
-
subscriptions = (ids ?? []).map((
|
|
1016
|
-
return
|
|
1024
|
+
subscriptions = (ids ?? []).map((id) => {
|
|
1025
|
+
return listenOne({
|
|
1017
1026
|
path,
|
|
1018
|
-
|
|
1019
|
-
onUpdate: (
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1027
|
+
id,
|
|
1028
|
+
onUpdate: (row) => {
|
|
1029
|
+
const incomingId = row?.id;
|
|
1030
|
+
if (row && incomingId !== void 0) {
|
|
1031
|
+
if (!addedEntitiesSet.has(incomingId)) {
|
|
1032
|
+
addedEntitiesSet.add(incomingId);
|
|
1033
|
+
rows.push(row);
|
|
1034
|
+
onUpdate(rows);
|
|
1025
1035
|
}
|
|
1026
|
-
} else
|
|
1027
|
-
addedEntitiesSet.delete(
|
|
1028
|
-
onUpdate([...
|
|
1036
|
+
} else {
|
|
1037
|
+
addedEntitiesSet.delete(id);
|
|
1038
|
+
onUpdate([...rows.filter((r) => r.id !== id)]);
|
|
1029
1039
|
}
|
|
1030
1040
|
}
|
|
1031
1041
|
});
|
|
@@ -1034,231 +1044,237 @@ function useFirestoreDriver({ firebaseApp, textSearchControllerBuilder, firestor
|
|
|
1034
1044
|
return () => {
|
|
1035
1045
|
subscriptions.forEach((p) => p());
|
|
1036
1046
|
};
|
|
1037
|
-
}, [firebaseApp,
|
|
1038
|
-
|
|
1047
|
+
}, [firebaseApp, listenOne]);
|
|
1048
|
+
const initTextSearch = useCallback(async (props) => {
|
|
1049
|
+
console.debug("Init text search controller", searchControllerRef.current, props.path);
|
|
1050
|
+
if (!searchControllerRef.current) {
|
|
1051
|
+
console.warn("You are trying to use text search, but have not provided a text search controller in `useFirestoreDriver`. You can also set the flag `localTextSearchEnabled` to use local search in `useFirestoreDriver`. Local text search can incur in performance issues and higher costs for large datasets.");
|
|
1052
|
+
return false;
|
|
1053
|
+
}
|
|
1054
|
+
try {
|
|
1055
|
+
return searchControllerRef.current.init(props);
|
|
1056
|
+
} catch (e) {
|
|
1057
|
+
console.error("Error initializing text search controller", e);
|
|
1058
|
+
return false;
|
|
1059
|
+
}
|
|
1060
|
+
}, []);
|
|
1061
|
+
/**
|
|
1062
|
+
* Fetch entities in a Firestore path
|
|
1063
|
+
* @param path
|
|
1064
|
+
* @param collection
|
|
1065
|
+
* @param filter
|
|
1066
|
+
* @param limit
|
|
1067
|
+
* @param startAfter
|
|
1068
|
+
* @param searchString
|
|
1069
|
+
* @param orderBy
|
|
1070
|
+
* @param order
|
|
1071
|
+
* @return Function to cancel subscription
|
|
1072
|
+
* @see useCollection if you need this functionality implemented as a hook
|
|
1073
|
+
* @group Firestore
|
|
1074
|
+
*/
|
|
1075
|
+
const fetchCollection = useCallback(async ({ path, filter, limit, startAfter, searchString, orderBy, order, collection }) => {
|
|
1076
|
+
const databaseId = collection?.databaseId;
|
|
1077
|
+
const resolvedPath = path;
|
|
1078
|
+
console.debug("Fetching collection", {
|
|
1079
|
+
path,
|
|
1080
|
+
limit,
|
|
1081
|
+
filter,
|
|
1082
|
+
startAfter,
|
|
1083
|
+
orderBy,
|
|
1084
|
+
order
|
|
1085
|
+
});
|
|
1086
|
+
return (await getDocs(buildQuery(resolvedPath, filter, orderBy, order, startAfter, limit, databaseId))).docs.map((doc) => createRowFromDocument(doc));
|
|
1087
|
+
}, [buildQuery]);
|
|
1088
|
+
/**
|
|
1089
|
+
* Listen to a entities in a given path
|
|
1090
|
+
* @param path
|
|
1091
|
+
* @param collection
|
|
1092
|
+
* @param onError
|
|
1093
|
+
* @param filter
|
|
1094
|
+
* @param limit
|
|
1095
|
+
* @param startAfter
|
|
1096
|
+
* @param searchString
|
|
1097
|
+
* @param orderBy
|
|
1098
|
+
* @param order
|
|
1099
|
+
* @param onUpdate
|
|
1100
|
+
* @return Function to cancel subscription
|
|
1101
|
+
* @see useCollection if you need this functionality implemented as a hook
|
|
1102
|
+
* @group Firestore
|
|
1103
|
+
*/
|
|
1104
|
+
const listenCollection = useCallback(({ path, filter, limit, startAfter, searchString, orderBy, order, onUpdate, onError, collection }) => {
|
|
1105
|
+
console.debug("Listening collection", {
|
|
1106
|
+
path,
|
|
1107
|
+
searchString,
|
|
1108
|
+
limit,
|
|
1109
|
+
filter,
|
|
1110
|
+
startAfter,
|
|
1111
|
+
orderBy,
|
|
1112
|
+
order,
|
|
1113
|
+
collection
|
|
1114
|
+
});
|
|
1115
|
+
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1116
|
+
const databaseId = collection?.databaseId;
|
|
1117
|
+
if (searchString) return performTextSearch({
|
|
1118
|
+
path,
|
|
1119
|
+
searchString,
|
|
1120
|
+
onUpdate,
|
|
1121
|
+
databaseId
|
|
1122
|
+
});
|
|
1123
|
+
const resolvedPath = path;
|
|
1124
|
+
console.debug("Resolved path for listening", {
|
|
1125
|
+
path,
|
|
1126
|
+
resolvedPath
|
|
1127
|
+
});
|
|
1128
|
+
return onSnapshot(buildQuery(resolvedPath, filter, orderBy, order, startAfter, limit, databaseId), {
|
|
1129
|
+
next: (entity) => {
|
|
1130
|
+
if (!searchString) onUpdate(entity.docs.map((doc) => createRowFromDocument(doc)));
|
|
1131
|
+
},
|
|
1132
|
+
error: onError
|
|
1133
|
+
});
|
|
1134
|
+
}, [
|
|
1135
|
+
buildQuery,
|
|
1136
|
+
firebaseApp,
|
|
1137
|
+
performTextSearch
|
|
1138
|
+
]);
|
|
1139
|
+
/**
|
|
1140
|
+
* Retrieve a entity given a path and a collection
|
|
1141
|
+
* @param path
|
|
1142
|
+
* @param id
|
|
1143
|
+
* @param collection
|
|
1144
|
+
* @group Firestore
|
|
1145
|
+
*/
|
|
1146
|
+
const fetchOne = useCallback(({ path, id, collection }) => {
|
|
1147
|
+
return getAndBuildEntity(path, id, collection?.databaseId);
|
|
1148
|
+
}, [getAndBuildEntity]);
|
|
1149
|
+
/**
|
|
1150
|
+
* Save entity to the specified path. Note that Firestore does not allow
|
|
1151
|
+
* undefined values.
|
|
1152
|
+
* @param path
|
|
1153
|
+
* @param id
|
|
1154
|
+
* @param values
|
|
1155
|
+
* @param schemaId
|
|
1156
|
+
* @param collection
|
|
1157
|
+
* @param status
|
|
1158
|
+
* @group Firestore
|
|
1159
|
+
*/
|
|
1160
|
+
const save = useCallback(({ path, id, values: valuesProp, collection: collection$1, status }) => {
|
|
1161
|
+
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1162
|
+
console.debug("1", {
|
|
1163
|
+
path,
|
|
1164
|
+
id,
|
|
1165
|
+
values: valuesProp,
|
|
1166
|
+
collection: collection$1
|
|
1167
|
+
});
|
|
1168
|
+
const values = cmsToFirestoreModel(valuesProp, getFirestore(firebaseApp));
|
|
1169
|
+
console.debug("2", {
|
|
1170
|
+
path,
|
|
1171
|
+
id,
|
|
1172
|
+
values: valuesProp,
|
|
1173
|
+
collection: collection$1
|
|
1174
|
+
});
|
|
1175
|
+
const databaseId = collection$1?.databaseId;
|
|
1176
|
+
const collectionReference = collection(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path);
|
|
1177
|
+
console.debug("Saving entity", {
|
|
1178
|
+
path,
|
|
1179
|
+
id,
|
|
1180
|
+
values,
|
|
1181
|
+
databaseId
|
|
1182
|
+
});
|
|
1183
|
+
let documentReference;
|
|
1184
|
+
if (id) documentReference = doc(collectionReference, String(id));
|
|
1185
|
+
else documentReference = doc(collectionReference);
|
|
1186
|
+
return setDoc(documentReference, values, { merge: true }).then(() => {
|
|
1187
|
+
return {
|
|
1188
|
+
...firestoreToCMSModel(values),
|
|
1189
|
+
id: documentReference.id
|
|
1190
|
+
};
|
|
1191
|
+
}).catch((error) => {
|
|
1192
|
+
console.error("Error saving entity", error);
|
|
1193
|
+
throw error;
|
|
1194
|
+
});
|
|
1195
|
+
}, [firebaseApp]);
|
|
1196
|
+
/**
|
|
1197
|
+
* Delete a entity
|
|
1198
|
+
* @param entity
|
|
1199
|
+
* @param collection
|
|
1200
|
+
* @group Firestore
|
|
1201
|
+
*/
|
|
1202
|
+
const deleteOne = useCallback(({ row, collection }) => {
|
|
1203
|
+
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1204
|
+
const databaseId = collection?.databaseId;
|
|
1205
|
+
return deleteDoc(doc(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), row.path, String(row.id)));
|
|
1206
|
+
}, [firebaseApp]);
|
|
1207
|
+
/**
|
|
1208
|
+
* Check if the given property is unique in the given collection
|
|
1209
|
+
* @param path Collection path
|
|
1210
|
+
* @param name of the property
|
|
1211
|
+
* @param value
|
|
1212
|
+
* @param property
|
|
1213
|
+
* @param id
|
|
1214
|
+
* @return `true` if there are no other fields besides the given entity
|
|
1215
|
+
* @group Firestore
|
|
1216
|
+
*/
|
|
1217
|
+
const checkUniqueField = useCallback(async (path, name, value, id, collection$2) => {
|
|
1218
|
+
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1219
|
+
const databaseId = collection$2?.databaseId;
|
|
1220
|
+
const firestore = databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp);
|
|
1221
|
+
if (value === void 0 || value === null) return Promise.resolve(true);
|
|
1222
|
+
return (await getDocs(query(collection(firestore, path), where(name, "==", cmsToFirestoreModel(value, firestore))))).docs.filter((doc) => doc.id !== id).length === 0;
|
|
1223
|
+
}, [firebaseApp]);
|
|
1224
|
+
const count = useCallback(async ({ path, filter, order, orderBy, collection }) => {
|
|
1225
|
+
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1226
|
+
const databaseId = collection?.databaseId;
|
|
1227
|
+
return (await getCountFromServer(buildQuery(path, filter, orderBy, order, void 0, void 0, databaseId))).data().count;
|
|
1228
|
+
}, [firebaseApp]);
|
|
1229
|
+
const isFilterCombinationValid = useCallback(({ path, collection, filterValues, sortBy }) => {
|
|
1230
|
+
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1231
|
+
if (firestoreIndexesBuilder === void 0) return true;
|
|
1232
|
+
const indexes = firestoreIndexesBuilder?.({
|
|
1233
|
+
path,
|
|
1234
|
+
collection
|
|
1235
|
+
});
|
|
1236
|
+
const sortKey = sortBy ? sortBy[0] : void 0;
|
|
1237
|
+
const sortDirection = sortBy ? sortBy[1] : void 0;
|
|
1238
|
+
const values = Object.values(filterValues);
|
|
1239
|
+
const filterKeys = Object.keys(filterValues);
|
|
1240
|
+
const filtersCount = filterKeys.length;
|
|
1241
|
+
if (!sortKey && values.every((v) => v[0] === "==")) return true;
|
|
1242
|
+
if (filtersCount === 1 && (!sortKey || sortKey === filterKeys[0])) return true;
|
|
1243
|
+
if (!indexes && filtersCount > 1) return false;
|
|
1244
|
+
return !!indexes && indexes.filter((compositeIndex) => !sortKey || sortKey in compositeIndex).find((compositeIndex) => Object.entries(filterValues).every(([key, value]) => compositeIndex[key] !== void 0 && (!sortDirection || compositeIndex[key] === sortDirection))) !== void 0;
|
|
1245
|
+
}, [firebaseApp]);
|
|
1246
|
+
return useMemo(() => ({
|
|
1039
1247
|
key: "firestore",
|
|
1040
1248
|
currentTime,
|
|
1041
1249
|
initialised: Boolean(firebaseApp),
|
|
1042
|
-
initTextSearch
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
* @return Function to cancel subscription
|
|
1066
|
-
* @see useCollectionFetch if you need this functionality implemented as a hook
|
|
1067
|
-
* @group Firestore
|
|
1068
|
-
*/
|
|
1069
|
-
fetchCollection: useCallback(async ({ path, filter, limit, startAfter, searchString, orderBy, order, collection }) => {
|
|
1070
|
-
const databaseId = collection?.databaseId;
|
|
1071
|
-
const resolvedPath = path;
|
|
1072
|
-
console.debug("Fetching collection", {
|
|
1073
|
-
path,
|
|
1074
|
-
limit,
|
|
1075
|
-
filter,
|
|
1076
|
-
startAfter,
|
|
1077
|
-
orderBy,
|
|
1078
|
-
order
|
|
1079
|
-
});
|
|
1080
|
-
return (await getDocs(buildQuery(resolvedPath, filter, orderBy, order, startAfter, limit, databaseId))).docs.map((doc) => createEntityFromDocument(doc, databaseId));
|
|
1081
|
-
}, [buildQuery]),
|
|
1082
|
-
/**
|
|
1083
|
-
* Listen to a entities in a given path
|
|
1084
|
-
* @param path
|
|
1085
|
-
* @param collection
|
|
1086
|
-
* @param onError
|
|
1087
|
-
* @param filter
|
|
1088
|
-
* @param limit
|
|
1089
|
-
* @param startAfter
|
|
1090
|
-
* @param searchString
|
|
1091
|
-
* @param orderBy
|
|
1092
|
-
* @param order
|
|
1093
|
-
* @param onUpdate
|
|
1094
|
-
* @return Function to cancel subscription
|
|
1095
|
-
* @see useCollectionFetch if you need this functionality implemented as a hook
|
|
1096
|
-
* @group Firestore
|
|
1097
|
-
*/
|
|
1098
|
-
listenCollection: useCallback(({ path, filter, limit, startAfter, searchString, orderBy, order, onUpdate, onError, collection }) => {
|
|
1099
|
-
console.debug("Listening collection", {
|
|
1100
|
-
path,
|
|
1101
|
-
searchString,
|
|
1102
|
-
limit,
|
|
1103
|
-
filter,
|
|
1104
|
-
startAfter,
|
|
1105
|
-
orderBy,
|
|
1106
|
-
order,
|
|
1107
|
-
collection
|
|
1108
|
-
});
|
|
1109
|
-
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1110
|
-
const databaseId = collection?.databaseId;
|
|
1111
|
-
if (searchString) return performTextSearch({
|
|
1112
|
-
path,
|
|
1113
|
-
searchString,
|
|
1114
|
-
onUpdate,
|
|
1115
|
-
databaseId
|
|
1116
|
-
});
|
|
1117
|
-
const resolvedPath = path;
|
|
1118
|
-
console.debug("Resolved path for listening", {
|
|
1119
|
-
path,
|
|
1120
|
-
resolvedPath
|
|
1121
|
-
});
|
|
1122
|
-
return onSnapshot(buildQuery(resolvedPath, filter, orderBy, order, startAfter, limit, databaseId), {
|
|
1123
|
-
next: (snapshot) => {
|
|
1124
|
-
if (!searchString) onUpdate(snapshot.docs.map((doc) => createEntityFromDocument(doc, databaseId)));
|
|
1125
|
-
},
|
|
1126
|
-
error: onError
|
|
1127
|
-
});
|
|
1128
|
-
}, [
|
|
1129
|
-
buildQuery,
|
|
1130
|
-
firebaseApp,
|
|
1131
|
-
performTextSearch
|
|
1132
|
-
]),
|
|
1133
|
-
/**
|
|
1134
|
-
* Retrieve an entity given a path and a collection
|
|
1135
|
-
* @param path
|
|
1136
|
-
* @param entityId
|
|
1137
|
-
* @param collection
|
|
1138
|
-
* @group Firestore
|
|
1139
|
-
*/
|
|
1140
|
-
fetchEntity: useCallback(({ path, entityId, collection }) => {
|
|
1141
|
-
return getAndBuildEntity(path, entityId, collection?.databaseId);
|
|
1142
|
-
}, [getAndBuildEntity]),
|
|
1143
|
-
/**
|
|
1144
|
-
*
|
|
1145
|
-
* @param path
|
|
1146
|
-
* @param entityId
|
|
1147
|
-
* @param collection
|
|
1148
|
-
* @param onUpdate
|
|
1149
|
-
* @param onError
|
|
1150
|
-
* @return Function to cancel subscription
|
|
1151
|
-
* @group Firestore
|
|
1152
|
-
*/
|
|
1153
|
-
listenEntity,
|
|
1154
|
-
/**
|
|
1155
|
-
* Save entity to the specified path. Note that Firestore does not allow
|
|
1156
|
-
* undefined values.
|
|
1157
|
-
* @param path
|
|
1158
|
-
* @param entityId
|
|
1159
|
-
* @param values
|
|
1160
|
-
* @param schemaId
|
|
1161
|
-
* @param collection
|
|
1162
|
-
* @param status
|
|
1163
|
-
* @group Firestore
|
|
1164
|
-
*/
|
|
1165
|
-
saveEntity: useCallback(({ path, entityId, values: valuesProp, collection: collection$1, status }) => {
|
|
1166
|
-
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1167
|
-
console.debug("1", {
|
|
1168
|
-
path,
|
|
1169
|
-
entityId,
|
|
1170
|
-
values: valuesProp,
|
|
1171
|
-
collection: collection$1
|
|
1172
|
-
});
|
|
1173
|
-
const values = cmsToFirestoreModel(valuesProp, getFirestore(firebaseApp));
|
|
1174
|
-
console.debug("2", {
|
|
1175
|
-
path,
|
|
1176
|
-
entityId,
|
|
1177
|
-
values: valuesProp,
|
|
1178
|
-
collection: collection$1
|
|
1179
|
-
});
|
|
1180
|
-
const databaseId = collection$1?.databaseId;
|
|
1181
|
-
const collectionReference = collection(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), path);
|
|
1182
|
-
console.debug("Saving entity", {
|
|
1183
|
-
path,
|
|
1184
|
-
entityId,
|
|
1185
|
-
values,
|
|
1186
|
-
databaseId
|
|
1187
|
-
});
|
|
1188
|
-
let documentReference;
|
|
1189
|
-
if (entityId) documentReference = doc(collectionReference, String(entityId));
|
|
1190
|
-
else documentReference = doc(collectionReference);
|
|
1191
|
-
return setDoc(documentReference, values, { merge: true }).then(() => {
|
|
1192
|
-
return {
|
|
1193
|
-
id: documentReference.id,
|
|
1194
|
-
path,
|
|
1195
|
-
values: firestoreToCMSModel(values)
|
|
1196
|
-
};
|
|
1197
|
-
}).catch((error) => {
|
|
1198
|
-
console.error("Error saving entity", error);
|
|
1199
|
-
throw error;
|
|
1200
|
-
});
|
|
1201
|
-
}, [firebaseApp]),
|
|
1202
|
-
/**
|
|
1203
|
-
* Delete an entity
|
|
1204
|
-
* @param entity
|
|
1205
|
-
* @param collection
|
|
1206
|
-
* @group Firestore
|
|
1207
|
-
*/
|
|
1208
|
-
deleteEntity: useCallback(({ entity }) => {
|
|
1209
|
-
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1210
|
-
const databaseId = entity.databaseId;
|
|
1211
|
-
return deleteDoc(doc(databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp), entity.path, String(entity.id)));
|
|
1212
|
-
}, [firebaseApp]),
|
|
1213
|
-
/**
|
|
1214
|
-
* Check if the given property is unique in the given collection
|
|
1215
|
-
* @param path Collection path
|
|
1216
|
-
* @param name of the property
|
|
1217
|
-
* @param value
|
|
1218
|
-
* @param property
|
|
1219
|
-
* @param entityId
|
|
1220
|
-
* @return `true` if there are no other fields besides the given entity
|
|
1221
|
-
* @group Firestore
|
|
1222
|
-
*/
|
|
1223
|
-
checkUniqueField: useCallback(async (path, name, value, entityId, collection$2) => {
|
|
1224
|
-
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1225
|
-
const databaseId = collection$2?.databaseId;
|
|
1226
|
-
const firestore = databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp);
|
|
1227
|
-
if (value === void 0 || value === null) return Promise.resolve(true);
|
|
1228
|
-
return (await getDocs(query(collection(firestore, path), where(name, "==", cmsToFirestoreModel(value, firestore))))).docs.filter((doc) => doc.id !== entityId).length === 0;
|
|
1229
|
-
}, [firebaseApp]),
|
|
1230
|
-
countEntities: useCallback(async ({ path, filter, order, orderBy, collection }) => {
|
|
1231
|
-
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1232
|
-
const databaseId = collection?.databaseId;
|
|
1233
|
-
return (await getCountFromServer(buildQuery(path, filter, orderBy, order, void 0, void 0, databaseId))).data().count;
|
|
1234
|
-
}, [firebaseApp]),
|
|
1235
|
-
isFilterCombinationValid: useCallback(({ path, collection, filterValues, sortBy }) => {
|
|
1236
|
-
if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
|
|
1237
|
-
if (firestoreIndexesBuilder === void 0) return true;
|
|
1238
|
-
const indexes = firestoreIndexesBuilder?.({
|
|
1239
|
-
path,
|
|
1240
|
-
collection
|
|
1241
|
-
});
|
|
1242
|
-
const sortKey = sortBy ? sortBy[0] : void 0;
|
|
1243
|
-
const sortDirection = sortBy ? sortBy[1] : void 0;
|
|
1244
|
-
const values = Object.values(filterValues);
|
|
1245
|
-
const filterKeys = Object.keys(filterValues);
|
|
1246
|
-
const filtersCount = filterKeys.length;
|
|
1247
|
-
if (!sortKey && values.every((v) => v[0] === "==")) return true;
|
|
1248
|
-
if (filtersCount === 1 && (!sortKey || sortKey === filterKeys[0])) return true;
|
|
1249
|
-
if (!indexes && filtersCount > 1) return false;
|
|
1250
|
-
return !!indexes && indexes.filter((compositeIndex) => !sortKey || sortKey in compositeIndex).find((compositeIndex) => Object.entries(filterValues).every(([key, value]) => compositeIndex[key] !== void 0 && (!sortDirection || compositeIndex[key] === sortDirection))) !== void 0;
|
|
1251
|
-
}, [firebaseApp])
|
|
1252
|
-
};
|
|
1250
|
+
initTextSearch,
|
|
1251
|
+
fetchCollection,
|
|
1252
|
+
listenCollection,
|
|
1253
|
+
fetchOne,
|
|
1254
|
+
listenOne,
|
|
1255
|
+
save,
|
|
1256
|
+
delete: deleteOne,
|
|
1257
|
+
checkUniqueField,
|
|
1258
|
+
count,
|
|
1259
|
+
isFilterCombinationValid
|
|
1260
|
+
}), [
|
|
1261
|
+
firebaseApp,
|
|
1262
|
+
initTextSearch,
|
|
1263
|
+
fetchCollection,
|
|
1264
|
+
listenCollection,
|
|
1265
|
+
fetchOne,
|
|
1266
|
+
listenOne,
|
|
1267
|
+
save,
|
|
1268
|
+
deleteOne,
|
|
1269
|
+
checkUniqueField,
|
|
1270
|
+
count,
|
|
1271
|
+
isFilterCombinationValid
|
|
1272
|
+
]);
|
|
1253
1273
|
}
|
|
1254
|
-
var
|
|
1255
|
-
const values = firestoreToCMSModel(docSnap.data());
|
|
1256
|
-
const path = getCMSPathFromFirestorePath(docSnap.ref.path);
|
|
1274
|
+
var createRowFromDocument = (docSnap) => {
|
|
1257
1275
|
return {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
values,
|
|
1261
|
-
databaseId
|
|
1276
|
+
...firestoreToCMSModel(docSnap.data()),
|
|
1277
|
+
id: docSnap.id
|
|
1262
1278
|
};
|
|
1263
1279
|
};
|
|
1264
1280
|
/**
|
|
@@ -1373,70 +1389,65 @@ function useFirebaseRTDBDelegate({ firebaseApp }) {
|
|
|
1373
1389
|
let dbQuery = query$1(ref$1(getDatabase(firebaseApp), path));
|
|
1374
1390
|
if (startAfter !== void 0) dbQuery = query$1(dbQuery, orderByKey(), startAt(String(startAfter)));
|
|
1375
1391
|
if (limit !== void 0) dbQuery = query$1(dbQuery, limitToFirst(limit));
|
|
1376
|
-
const
|
|
1377
|
-
if (
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
values: delegateToCMSModel(values)
|
|
1392
|
+
const entity = await get(dbQuery);
|
|
1393
|
+
if (entity.exists()) return Object.entries(entity.val()).map(([id, values]) => ({
|
|
1394
|
+
...delegateToCMSModel(values),
|
|
1395
|
+
id
|
|
1381
1396
|
}));
|
|
1382
1397
|
return [];
|
|
1383
1398
|
}, [firebaseApp]),
|
|
1384
1399
|
listenCollection: useCallback(({ path, onUpdate }) => {
|
|
1385
1400
|
if (!firebaseApp) throw new Error("Firebase app not provided");
|
|
1386
|
-
const unsubscribe = onValue(ref$1(getDatabase(firebaseApp), path), (
|
|
1387
|
-
if (
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
values: delegateToCMSModel(values)
|
|
1401
|
+
const unsubscribe = onValue(ref$1(getDatabase(firebaseApp), path), (entity) => {
|
|
1402
|
+
if (entity.exists()) onUpdate(Object.entries(entity.val()).map(([id, values]) => ({
|
|
1403
|
+
...delegateToCMSModel(values),
|
|
1404
|
+
id
|
|
1391
1405
|
})));
|
|
1392
1406
|
else onUpdate([]);
|
|
1393
1407
|
});
|
|
1394
1408
|
return () => unsubscribe();
|
|
1395
1409
|
}, [firebaseApp]),
|
|
1396
|
-
|
|
1410
|
+
fetchOne: useCallback(async ({ path, id }) => {
|
|
1397
1411
|
if (!firebaseApp) throw new Error("Firebase app not provided");
|
|
1398
|
-
const
|
|
1399
|
-
if (
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
values: delegateToCMSModel(snapshot.val())
|
|
1412
|
+
const entity = await get(ref$1(getDatabase(firebaseApp), `${path}/${id}`));
|
|
1413
|
+
if (entity.exists()) return {
|
|
1414
|
+
...delegateToCMSModel(entity.val()),
|
|
1415
|
+
id
|
|
1403
1416
|
};
|
|
1404
1417
|
}, [firebaseApp]),
|
|
1405
|
-
|
|
1418
|
+
listenOne: useCallback(({ path, id, onUpdate, onError }) => {
|
|
1406
1419
|
if (!firebaseApp) throw new Error("Firebase app not provided");
|
|
1407
|
-
const unsubscribe = onValue(ref$1(getDatabase(firebaseApp), `${path}/${
|
|
1408
|
-
if (
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
values: delegateToCMSModel(snapshot.val())
|
|
1420
|
+
const unsubscribe = onValue(ref$1(getDatabase(firebaseApp), `${path}/${id}`), (entity) => {
|
|
1421
|
+
if (entity.exists()) onUpdate({
|
|
1422
|
+
...delegateToCMSModel(entity.val()),
|
|
1423
|
+
id
|
|
1412
1424
|
});
|
|
1413
1425
|
else onError?.(/* @__PURE__ */ new Error("Entity does not exist"));
|
|
1414
1426
|
});
|
|
1415
1427
|
return () => unsubscribe();
|
|
1416
1428
|
}, [firebaseApp]),
|
|
1417
|
-
|
|
1429
|
+
save: useCallback(async ({ path, id, values }) => {
|
|
1418
1430
|
if (!firebaseApp) throw new Error("Firebase app not provided");
|
|
1419
1431
|
const database = getDatabase(firebaseApp);
|
|
1420
|
-
const finalId =
|
|
1432
|
+
const finalId = id ?? push(ref$1(database, path)).key;
|
|
1421
1433
|
if (!finalId) throw new Error("Could not generate a new id");
|
|
1422
1434
|
const transformedValues = cmsToRTDBModel(values, database);
|
|
1423
1435
|
await set(ref$1(database, `${path}/${finalId}`), transformedValues);
|
|
1424
1436
|
return {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
values
|
|
1437
|
+
...values,
|
|
1438
|
+
id: finalId
|
|
1428
1439
|
};
|
|
1429
1440
|
}, [firebaseApp]),
|
|
1430
|
-
|
|
1441
|
+
delete: useCallback(async ({ row }) => {
|
|
1431
1442
|
if (!firebaseApp) throw new Error("Firebase app not provided");
|
|
1432
|
-
await remove(ref$1(getDatabase(firebaseApp), `${
|
|
1443
|
+
await remove(ref$1(getDatabase(firebaseApp), `${row.path}/${row.id}`));
|
|
1433
1444
|
}, [firebaseApp]),
|
|
1434
|
-
checkUniqueField: useCallback(async (slug, name, value,
|
|
1445
|
+
checkUniqueField: useCallback(async (slug, name, value, id) => {
|
|
1435
1446
|
if (!firebaseApp) throw new Error("Firebase app not provided");
|
|
1436
|
-
const
|
|
1437
|
-
if (!
|
|
1438
|
-
const [key, entityValue] = Object.entries(
|
|
1439
|
-
if (entityValue && typeof entityValue === "object" && entityValue[name] === value && key ===
|
|
1447
|
+
const entity = await get(query$1(ref$1(getDatabase(firebaseApp), slug), orderByChild(name), startAt(value), limitToFirst(1)));
|
|
1448
|
+
if (!entity.exists()) return true;
|
|
1449
|
+
const [key, entityValue] = Object.entries(entity.val())[0];
|
|
1450
|
+
if (entityValue && typeof entityValue === "object" && entityValue[name] === value && key === id) return true;
|
|
1440
1451
|
return false;
|
|
1441
1452
|
}, [firebaseApp]),
|
|
1442
1453
|
isFilterCombinationValid: useCallback(({ path, filter, sortBy }) => {
|
|
@@ -1526,11 +1537,11 @@ function useBuildUserManagement({ authController, dataSourceDelegate, roles: rol
|
|
|
1526
1537
|
setRolesLoading(true);
|
|
1527
1538
|
return dataSourceDelegate.listenCollection?.({
|
|
1528
1539
|
path: rolesPath,
|
|
1529
|
-
onUpdate(
|
|
1540
|
+
onUpdate(rows) {
|
|
1530
1541
|
setRolesError(void 0);
|
|
1531
|
-
console.debug("Updating roles",
|
|
1542
|
+
console.debug("Updating roles", rows);
|
|
1532
1543
|
try {
|
|
1533
|
-
const newRoles =
|
|
1544
|
+
const newRoles = rowsToRoles(rows);
|
|
1534
1545
|
if (!deepEqual(newRoles, roles)) setRoles(newRoles);
|
|
1535
1546
|
} catch (e) {
|
|
1536
1547
|
setRoles([]);
|
|
@@ -1560,11 +1571,11 @@ function useBuildUserManagement({ authController, dataSourceDelegate, roles: rol
|
|
|
1560
1571
|
setUsersLoading(true);
|
|
1561
1572
|
return dataSourceDelegate.listenCollection?.({
|
|
1562
1573
|
path: usersPath,
|
|
1563
|
-
onUpdate(
|
|
1564
|
-
console.debug("Updating users",
|
|
1574
|
+
onUpdate(rows) {
|
|
1575
|
+
console.debug("Updating users", rows);
|
|
1565
1576
|
setUsersError(void 0);
|
|
1566
1577
|
try {
|
|
1567
|
-
setUsersWithRoleIds(
|
|
1578
|
+
setUsersWithRoleIds(rowsToUsers(rows));
|
|
1568
1579
|
} catch (e) {
|
|
1569
1580
|
setUsersWithRoleIds([]);
|
|
1570
1581
|
console.error("Error loading users", e);
|
|
@@ -1599,21 +1610,21 @@ function useBuildUserManagement({ authController, dataSourceDelegate, roles: rol
|
|
|
1599
1610
|
...userExists ? {} : { created_on: /* @__PURE__ */ new Date() }
|
|
1600
1611
|
};
|
|
1601
1612
|
if (userExists && userExists.uid !== user.uid) {
|
|
1602
|
-
const
|
|
1613
|
+
const row = {
|
|
1603
1614
|
values: {},
|
|
1604
1615
|
path: usersPath,
|
|
1605
1616
|
id: userExists.uid
|
|
1606
1617
|
};
|
|
1607
|
-
await dataSourceDelegate.
|
|
1618
|
+
await dataSourceDelegate.delete({ row }).then(() => {
|
|
1608
1619
|
console.debug("Deleted previous user", userExists);
|
|
1609
1620
|
}).catch((e) => {
|
|
1610
1621
|
console.error("Error deleting user", e);
|
|
1611
1622
|
});
|
|
1612
1623
|
}
|
|
1613
|
-
return dataSourceDelegate.
|
|
1624
|
+
return dataSourceDelegate.save({
|
|
1614
1625
|
status: "existing",
|
|
1615
1626
|
path: usersPath,
|
|
1616
|
-
|
|
1627
|
+
id: email,
|
|
1617
1628
|
values: removeUndefined(data)
|
|
1618
1629
|
}).then(() => user);
|
|
1619
1630
|
}, [usersPath, dataSourceDelegate?.initialised]);
|
|
@@ -1622,10 +1633,10 @@ function useBuildUserManagement({ authController, dataSourceDelegate, roles: rol
|
|
|
1622
1633
|
if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
|
|
1623
1634
|
console.debug("Persisting role", role);
|
|
1624
1635
|
const { id, ...roleData } = role;
|
|
1625
|
-
return dataSourceDelegate.
|
|
1636
|
+
return dataSourceDelegate.save({
|
|
1626
1637
|
status: "existing",
|
|
1627
1638
|
path: rolesPath,
|
|
1628
|
-
|
|
1639
|
+
id,
|
|
1629
1640
|
values: removeUndefined(roleData)
|
|
1630
1641
|
}).then(() => {});
|
|
1631
1642
|
}, [rolesPath, dataSourceDelegate?.initialised]);
|
|
@@ -1634,24 +1645,24 @@ function useBuildUserManagement({ authController, dataSourceDelegate, roles: rol
|
|
|
1634
1645
|
if (!usersPath) throw Error("useBuildUserManagement Firestore not initialised");
|
|
1635
1646
|
console.debug("Deleting", user);
|
|
1636
1647
|
const { uid } = user;
|
|
1637
|
-
const
|
|
1648
|
+
const row = {
|
|
1638
1649
|
path: usersPath,
|
|
1639
1650
|
id: uid,
|
|
1640
1651
|
values: {}
|
|
1641
1652
|
};
|
|
1642
|
-
await dataSourceDelegate.
|
|
1653
|
+
await dataSourceDelegate.delete({ row });
|
|
1643
1654
|
}, [usersPath, dataSourceDelegate?.initialised]);
|
|
1644
1655
|
const deleteRole = useCallback(async (role) => {
|
|
1645
1656
|
if (!dataSourceDelegate) throw Error("useBuildUserManagement Firebase not initialised");
|
|
1646
1657
|
if (!rolesPath) throw Error("useBuildUserManagement Firestore not initialised");
|
|
1647
1658
|
console.debug("Deleting", role);
|
|
1648
1659
|
const { id } = role;
|
|
1649
|
-
const
|
|
1660
|
+
const row = {
|
|
1650
1661
|
path: rolesPath,
|
|
1651
1662
|
id,
|
|
1652
1663
|
values: {}
|
|
1653
1664
|
};
|
|
1654
|
-
await dataSourceDelegate.
|
|
1665
|
+
await dataSourceDelegate.delete({ row });
|
|
1655
1666
|
}, [rolesPath, dataSourceDelegate?.initialised]);
|
|
1656
1667
|
const defineRolesFor = useCallback((user) => {
|
|
1657
1668
|
if (!usersWithRoleIds) throw Error("Users not loaded");
|
|
@@ -1727,22 +1738,21 @@ function useBuildUserManagement({ authController, dataSourceDelegate, roles: rol
|
|
|
1727
1738
|
} : null
|
|
1728
1739
|
};
|
|
1729
1740
|
}
|
|
1730
|
-
var
|
|
1731
|
-
return
|
|
1732
|
-
const data =
|
|
1733
|
-
const record = data;
|
|
1741
|
+
var rowsToUsers = (rows) => {
|
|
1742
|
+
return rows.map((row) => {
|
|
1743
|
+
const { id, ...data } = row;
|
|
1734
1744
|
return {
|
|
1735
1745
|
...data,
|
|
1736
|
-
uid:
|
|
1737
|
-
created_on:
|
|
1738
|
-
updated_on:
|
|
1746
|
+
uid: id,
|
|
1747
|
+
created_on: data.created_on,
|
|
1748
|
+
updated_on: data.updated_on
|
|
1739
1749
|
};
|
|
1740
1750
|
});
|
|
1741
1751
|
};
|
|
1742
|
-
var
|
|
1743
|
-
return
|
|
1744
|
-
|
|
1745
|
-
|
|
1752
|
+
var rowsToRoles = (rows) => {
|
|
1753
|
+
return rows.map((row) => ({
|
|
1754
|
+
...row,
|
|
1755
|
+
id: row.id
|
|
1746
1756
|
}));
|
|
1747
1757
|
};
|
|
1748
1758
|
//#endregion
|
|
@@ -2570,7 +2580,12 @@ function RebaseFirebaseApp({ name, logo, logoDark, accessGate, collections, view
|
|
|
2570
2580
|
authController,
|
|
2571
2581
|
userConfigPersistence,
|
|
2572
2582
|
dateTimeFormat,
|
|
2573
|
-
|
|
2583
|
+
dataSources: [{
|
|
2584
|
+
key: DEFAULT_DATA_SOURCE_KEY,
|
|
2585
|
+
engine: "firestore",
|
|
2586
|
+
transport: "direct",
|
|
2587
|
+
driver: firestoreDelegate
|
|
2588
|
+
}],
|
|
2574
2589
|
storageSource,
|
|
2575
2590
|
entityLinkBuilder: ({ entity }) => `https://console.firebase.google.com/project/${firebaseApp.options.projectId}/firestore/data/${entity.path}/${entity.id}`,
|
|
2576
2591
|
locale,
|
|
@@ -2596,7 +2611,7 @@ function RebaseFirebaseApp({ name, logo, logoDark, accessGate, collections, view
|
|
|
2596
2611
|
to: urlController.buildUrlCollectionPath(firstCollectionEntry.id),
|
|
2597
2612
|
replace: true
|
|
2598
2613
|
}) : /* @__PURE__ */ jsx(CenteredView, { children: "No home page or collections provided." });
|
|
2599
|
-
component = /* @__PURE__ */ jsx(
|
|
2614
|
+
component = /* @__PURE__ */ jsx(SidePanelProvider, { children: /* @__PURE__ */ jsx(RebaseRoutes, { children: /* @__PURE__ */ jsxs(Route, {
|
|
2600
2615
|
element: /* @__PURE__ */ jsxs(Scaffold, {
|
|
2601
2616
|
logo: usedLogo,
|
|
2602
2617
|
autoOpenDrawer,
|