@rebasepro/core 0.2.3 → 0.2.5

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.
Files changed (40) hide show
  1. package/dist/components/LoginView/LoginView.d.ts +25 -1
  2. package/dist/components/common/types.d.ts +10 -7
  3. package/dist/components/common/useDebouncedData.d.ts +1 -1
  4. package/dist/core/RebaseProps.d.ts +13 -2
  5. package/dist/core/RebaseRouter.d.ts +1 -1
  6. package/dist/hooks/data/useCollectionFetch.d.ts +12 -1
  7. package/dist/hooks/index.d.ts +0 -1
  8. package/dist/index.es.js +565 -454
  9. package/dist/index.es.js.map +1 -1
  10. package/dist/index.umd.js +565 -454
  11. package/dist/index.umd.js.map +1 -1
  12. package/dist/util/entity_cache.d.ts +0 -5
  13. package/dist/util/index.d.ts +0 -2
  14. package/dist/util/useStorageUploadController.d.ts +2 -2
  15. package/package.json +6 -6
  16. package/src/components/BootstrapAdminBanner.tsx +12 -3
  17. package/src/components/LoginView/LoginView.tsx +177 -10
  18. package/src/components/UserSettingsView.tsx +95 -2
  19. package/src/components/common/types.tsx +7 -7
  20. package/src/components/common/useDebouncedData.ts +2 -2
  21. package/src/core/Rebase.tsx +3 -2
  22. package/src/core/RebaseProps.tsx +15 -2
  23. package/src/core/RebaseRouter.tsx +1 -1
  24. package/src/hooks/data/useCollectionFetch.tsx +27 -4
  25. package/src/hooks/data/useUserSelector.tsx +1 -1
  26. package/src/hooks/index.tsx +0 -1
  27. package/src/hooks/useResolvedComponent.tsx +4 -3
  28. package/src/locales/en.ts +13 -0
  29. package/src/locales/es.ts +11 -1
  30. package/src/util/entity_cache.ts +1 -27
  31. package/src/util/icon_list.ts +2 -2
  32. package/src/util/index.ts +2 -2
  33. package/src/util/previews.ts +9 -1
  34. package/src/util/useStorageUploadController.tsx +4 -4
  35. package/dist/hooks/useValidateAuthenticator.d.ts +0 -21
  36. package/dist/util/icon_synonyms.d.ts +0 -1
  37. package/dist/util/useTraceUpdate.d.ts +0 -2
  38. package/src/hooks/useValidateAuthenticator.tsx +0 -116
  39. package/src/util/icon_synonyms.ts +0 -1
  40. package/src/util/useTraceUpdate.tsx +0 -24
@@ -1,5 +1,10 @@
1
1
  import React from "react";
2
- import { Locale, User, AuthController, AnalyticsEvent, DataDriver, StorageSource, UserConfigurationPersistence, CollectionRegistryController, DatabaseAdmin, UrlController, NavigationStateController, RebaseData, RebaseClient, RebaseContext, UserManagementDelegate, EntityLinkBuilder, RebasePlugin, SlotContribution, PropertyConfig, EntityCustomView, EntityAction } from "@rebasepro/types";
2
+ import { Locale, User, AuthController, AnalyticsEvent, DataDriver, StorageSource, UserConfigurationPersistence, CollectionRegistryController, DatabaseAdmin, UrlController, NavigationStateController, RebaseData, RebaseClient, RebaseContext, UserManagementDelegate, EntityLinkBuilder, RebasePlugin, SlotContribution, PropertyConfig, EntityCustomView, EntityAction, RebaseTranslations } from "@rebasepro/types";
3
+
4
+ /** DeepPartial helper — allows partial overrides at any nesting level */
5
+ type DeepPartial<T> = T extends object
6
+ ? { [K in keyof T]?: DeepPartial<T[K]> }
7
+ : T;
3
8
 
4
9
  /**
5
10
  * Controller to simulate different roles when dev mode is active.
@@ -138,7 +143,7 @@ export type RebaseProps<USER extends User> = {
138
143
  /**
139
144
  * Entity Views
140
145
  */
141
- entityViews?: EntityCustomView<any>[];
146
+ entityViews?: EntityCustomView[];
142
147
 
143
148
  /**
144
149
  * Entity Actions
@@ -161,4 +166,12 @@ export type RebaseProps<USER extends User> = {
161
166
  */
162
167
  effectiveRoleController?: EffectiveRoleController;
163
168
 
169
+ /**
170
+ * Override or extend any Rebase UI string, keyed by locale.
171
+ */
172
+ translations?: {
173
+ [locale: string]: DeepPartial<RebaseTranslations>;
174
+ };
175
+
164
176
  };
177
+
@@ -5,7 +5,7 @@ export function RebaseRouter({
5
5
  children,
6
6
  basePath
7
7
  }: {
8
- children: any,
8
+ children: React.ReactNode,
9
9
  basePath?: string;
10
10
  }) {
11
11
  return <RouterProvider router={createBrowserRouter([
@@ -22,6 +22,16 @@ export interface CollectionFetchProps<M extends Record<string, any>> {
22
22
  */
23
23
  itemCount?: number;
24
24
 
25
+ /**
26
+ * Number of items to skip
27
+ */
28
+ offset?: number;
29
+
30
+ /**
31
+ * Page number (1-indexed), alternative to offset
32
+ */
33
+ page?: number;
34
+
25
35
  /**
26
36
  * Filter the fetched data by the property
27
37
  */
@@ -46,6 +56,7 @@ export interface CollectionFetchResult<M extends Record<string, any>> {
46
56
  dataLoading: boolean;
47
57
  noMoreToLoad: boolean;
48
58
  dataLoadingError?: Error;
59
+ totalCount?: number;
49
60
  }
50
61
 
51
62
  /**
@@ -55,6 +66,8 @@ export interface CollectionFetchResult<M extends Record<string, any>> {
55
66
  * @param filterValues
56
67
  * @param sortBy
57
68
  * @param itemCount
69
+ * @param offset
70
+ * @param page
58
71
  * @param searchString
59
72
  * @group Hooks and utilities
60
73
  */
@@ -65,6 +78,8 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
65
78
  filterValues,
66
79
  sortBy,
67
80
  itemCount,
81
+ offset,
82
+ page,
68
83
  searchString
69
84
  }: CollectionFetchProps<M>): CollectionFetchResult<M> {
70
85
  const dataClient = useData();
@@ -99,12 +114,13 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
99
114
  const [dataLoading, setDataLoading] = useState<boolean>(false);
100
115
  const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();
101
116
  const [noMoreToLoad, setNoMoreToLoad] = useState<boolean>(false);
117
+ const [totalCount, setTotalCount] = useState<number | undefined>();
102
118
 
103
119
  useEffect(() => {
104
120
 
105
121
  setDataLoading(true);
106
122
 
107
- const onEntitiesUpdate = async (res: { data: Entity<M>[], meta: { hasMore: boolean } }) => {
123
+ const onEntitiesUpdate = async (res: { data: Entity<M>[], meta: { hasMore: boolean; total?: number } }) => {
108
124
  const entities = res.data;
109
125
  setDataLoading(false);
110
126
  setDataLoadingError(undefined);
@@ -112,6 +128,7 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
112
128
  ...e
113
129
  })));
114
130
  setNoMoreToLoad(!res.meta.hasMore);
131
+ setTotalCount(res.meta.total);
115
132
  };
116
133
 
117
134
  const onError = (error: Error) => {
@@ -119,6 +136,7 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
119
136
  setDataLoading(false);
120
137
  setData([]);
121
138
  setDataLoadingError(error);
139
+ setTotalCount(undefined);
122
140
  };
123
141
 
124
142
  const accessor = dataClient.collection(path);
@@ -133,6 +151,8 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
133
151
  return accessor.listen({
134
152
  where: whereParams,
135
153
  limit: itemCount,
154
+ offset,
155
+ page,
136
156
  orderBy: orderByParams,
137
157
  searchString,
138
158
  include: includeParams
@@ -141,6 +161,8 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
141
161
  accessor.find({
142
162
  where: whereParams,
143
163
  limit: itemCount,
164
+ offset,
165
+ page,
144
166
  orderBy: orderByParams,
145
167
  searchString,
146
168
  include: includeParams
@@ -150,13 +172,14 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
150
172
  return () => {
151
173
  };
152
174
  }
153
- }, [path, itemCount, currentSort, sortByProperty, filterValues, searchString, dataClient, collection]);
175
+ }, [path, itemCount, offset, page, currentSort, sortByProperty, filterValues, searchString, dataClient, collection]);
154
176
 
155
177
  return useMemo(() => ({
156
178
  data,
157
179
  dataLoading,
158
180
  dataLoadingError,
159
- noMoreToLoad
160
- }), [data, dataLoading, dataLoadingError, noMoreToLoad]);
181
+ noMoreToLoad,
182
+ totalCount
183
+ }), [data, dataLoading, dataLoadingError, noMoreToLoad, totalCount]);
161
184
 
162
185
  }
@@ -142,7 +142,7 @@ export function useUserSelector(
142
142
  }, []);
143
143
 
144
144
  const getUser = useCallback((uid: string): User | null => {
145
- return userManagement?.getUser(uid) ?? null;
145
+ return userManagement?.getUser?.(uid) ?? null;
146
146
  }, [userManagement]);
147
147
 
148
148
  return useMemo(() => ({
@@ -33,7 +33,6 @@ export * from "./useCustomizationController";
33
33
  export * from "./useBuildLocalConfigurationPersistence";
34
34
  export * from "./useBuildModeController";
35
35
 
36
- export * from "./useValidateAuthenticator";
37
36
  export * from "./useRebaseRegistry";
38
37
  export * from "./useBackendStorageSource";
39
38
  export * from "./usePermissions";
@@ -13,7 +13,8 @@ import { isLazyComponentRef } from "@rebasepro/types";
13
13
  * to the `React.lazy()` wrapper it produced. Strings are keyed by a separate
14
14
  * plain Map since they can't be WeakMap keys.
15
15
  */
16
- const lazyCache = new WeakMap<object | ((..._args: any[]) => any), React.ComponentType<any>>();
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ const lazyCache = new WeakMap<object | Function, React.ComponentType<any>>();
17
18
 
18
19
  /**
19
20
  * Resolves a `ComponentRef` into a renderable `React.ComponentType`.
@@ -62,7 +63,7 @@ export function useResolvedComponent<P = unknown>(
62
63
  * same loader always returns the same lazy component identity.
63
64
  */
64
65
  function getOrCreateLazy<P>(
65
- key: object | ((..._args: any[]) => any),
66
+ key: object | Function,
66
67
  loader: () => Promise<{ default: React.ComponentType<P> }>
67
68
  ): React.ComponentType<P> {
68
69
  const cached = lazyCache.get(key);
@@ -108,7 +109,7 @@ export function resolveComponentRef<P = unknown>(
108
109
 
109
110
  // 3. Function — either a React component or a lazy import loader.
110
111
  if (typeof ref === "function") {
111
- const fn = ref as (..._args: any[]) => any;
112
+ const fn = ref as Function;
112
113
 
113
114
  // Class components (React.Component / PureComponent) have this flag
114
115
  if (fn.prototype?.isReactComponent) {
package/src/locales/en.ts CHANGED
@@ -164,6 +164,9 @@ export const en: RebaseTranslations = {
164
164
  navigation_drawer: "Navigation drawer",
165
165
  collapse: "Collapse",
166
166
  expand: "Expand",
167
+ change_language: "Change language",
168
+ toggle_theme: "Toggle theme",
169
+ user_menu: "User menu",
167
170
 
168
171
  // ─── Error states ─────────────────────────────────────────────
169
172
  error: "Error",
@@ -451,7 +454,17 @@ export const en: RebaseTranslations = {
451
454
  select_references: "Select references",
452
455
  account_settings: "Account Settings",
453
456
  profile: "Profile",
457
+ security: "Security",
454
458
  sessions: "Sessions",
459
+ change_password: "Change Password",
460
+ current_password: "Current Password",
461
+ new_password: "New Password",
462
+ confirm_password: "Confirm New Password",
463
+ password_changed: "Password changed successfully. You will be logged out.",
464
+ passwords_dont_match: "Passwords don't match",
465
+ password_too_short: "Password must be at least 8 characters",
466
+ password_change_not_available: "Password change is not available for accounts using external sign-in providers.",
467
+ changing_password: "Changing...",
455
468
  display_name: "Display Name",
456
469
  photo_url: "Photo URL",
457
470
  save_profile: "Save Profile",
package/src/locales/es.ts CHANGED
@@ -652,7 +652,17 @@ no_filter: "No filter",
652
652
  select_references: "Select references",
653
653
  account_settings: "Account Settings",
654
654
  profile: "Profile",
655
- sessions: "Sessions",
655
+ sessions: "Sesiones",
656
+ security: "Seguridad",
657
+ change_password: "Cambiar Contraseña",
658
+ current_password: "Contraseña Actual",
659
+ new_password: "Nueva Contraseña",
660
+ confirm_password: "Confirmar Nueva Contraseña",
661
+ password_changed: "Contraseña cambiada con éxito. Se cerrará tu sesión.",
662
+ passwords_dont_match: "Las contraseñas no coinciden",
663
+ password_too_short: "La contraseña debe tener al menos 8 caracteres",
664
+ password_change_not_available: "El cambio de contraseña no está disponible para cuentas que usan proveedores de inicio de sesión externos.",
665
+ changing_password: "Cambiando...",
656
666
  display_name: "Display Name",
657
667
  photo_url: "Photo URL",
658
668
  save_profile: "Save Profile",
@@ -154,9 +154,7 @@ export function getEntityFromMemoryCache(path: string): object | undefined {
154
154
  return entityCache.get(path);
155
155
  }
156
156
 
157
- export function hasEntityInCache(path: string): boolean {
158
- return entityCache.has(path);
159
- }
157
+
160
158
 
161
159
  /**
162
160
  * Retrieves an entity from the in-memory cache or `sessionStorage`.
@@ -212,31 +210,7 @@ export function removeEntityFromCache(path: string): void {
212
210
  }
213
211
  }
214
212
 
215
- /**
216
- * Clears the entire in-memory cache and removes all related entities from `sessionStorage`.
217
- */
218
- export function clearEntityCache(): void {
219
- // Clear the in-memory cache
220
- entityCache.clear();
221
213
 
222
- // Remove all entities with the specified prefix from sessionStorage
223
- if (isSessionStorageAvailable) {
224
- try {
225
- const keysToRemove: string[] = [];
226
- for (let i = 0; i < sessionStorage.length; i++) {
227
- const fullKey = sessionStorage.key(i);
228
- if (fullKey && fullKey.startsWith(LOCAL_STORAGE_PREFIX)) {
229
- keysToRemove.push(fullKey);
230
- }
231
- }
232
-
233
- // Remove the keys after collecting them to avoid issues while iterating
234
- keysToRemove.forEach((key) => sessionStorage.removeItem(key));
235
- } catch (error) {
236
- console.error("Failed to clear entity cache from sessionStorage:", error);
237
- }
238
- }
239
- }
240
214
 
241
215
  export function flattenKeys(obj: Record<string, unknown> | unknown[], prefix = "", result: string[] = []): string[] {
242
216
 
@@ -1,11 +1,11 @@
1
- import { iconSynonyms } from "./icon_synonyms";
1
+ const iconSynonyms: Record<string, string> = {};
2
2
  import { iconKeys } from "@rebasepro/ui";
3
3
  import Fuse from "fuse.js";
4
4
 
5
5
 
6
6
  const map = iconKeys
7
7
  .map((importName) => {
8
- const iconSynonym = importName in iconSynonyms ? (iconSynonyms as Record<string, string>)[importName] : "";
8
+ const iconSynonym = importName in iconSynonyms ? iconSynonyms[importName] : "";
9
9
  return {
10
10
  key: importName,
11
11
  synonyms: iconSynonym
package/src/util/index.ts CHANGED
@@ -1,12 +1,12 @@
1
1
 
2
2
  export * from "./icon_list";
3
- export * from "./icon_synonyms";
3
+
4
4
  export * from "./icons";
5
5
  export * from "./createFormexStub";
6
6
  export * from "./entity_cache";
7
7
 
8
8
  export * from "./useStorageUploadController";
9
- export * from "./useTraceUpdate";
9
+
10
10
  export * from "./previews";
11
11
  export * from "./enums";
12
12
  export * from "./constants";
@@ -22,6 +22,11 @@ function isRelationProperty(property: Property) {
22
22
  return false;
23
23
  }
24
24
 
25
+ function isHiddenProperty(property: Property | undefined): boolean {
26
+ if (!property) return false;
27
+ return Boolean(property.ui?.hideFromCollection);
28
+ }
29
+
25
30
  export function getEntityPreviewKeys(
26
31
  authController: AuthController,
27
32
  targetCollection: EntityCollection<any>,
@@ -45,7 +50,7 @@ export function getEntityPreviewKeys(
45
50
  })
46
51
  .filter(key => {
47
52
  const property = targetCollection.properties[key];
48
- return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isRelationProperty(property);
53
+ return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isRelationProperty(property) && !isHiddenProperty(property);
49
54
  }).slice(0, limit);
50
55
  }
51
56
  }
@@ -62,6 +67,9 @@ export function getEntityTitlePropertyKey<M extends Record<string, any>>(collect
62
67
  const property = collection.properties[key];
63
68
  if (property && !isPropertyBuilder(property)) {
64
69
  const prop = property as Property;
70
+ if (isHiddenProperty(prop)) {
71
+ continue;
72
+ }
65
73
  if (prop.type === "string" && !prop.ui?.multiline && !prop.ui?.markdown && !prop.storage && !prop.isId) {
66
74
  if (!firstStringCandidate) {
67
75
  firstStringCandidate = key;
@@ -21,7 +21,7 @@ export interface StorageFieldItem {
21
21
  storagePathOrDownloadUrl?: string;
22
22
  file?: File;
23
23
  fileName?: string;
24
- metadata?: any,
24
+ metadata?: Record<string, unknown>,
25
25
  size: StorageFieldSize
26
26
  }
27
27
 
@@ -63,7 +63,7 @@ export function useStorageUploadController<M extends Record<string, unknown>>({
63
63
 
64
64
  const processFile = storage?.processFile;
65
65
 
66
- const metadata: Record<string, any> | undefined = storage?.metadata;
66
+ const metadata: Record<string, unknown> | undefined = storage?.metadata;
67
67
  const size = multipleFilesSupported ? "medium" : "large";
68
68
 
69
69
  const imageResize = storage?.imageResize;
@@ -116,7 +116,7 @@ export function useStorageUploadController<M extends Record<string, unknown>>({
116
116
 
117
117
  const onFileUploadComplete = useCallback(async (uploadedPath: string,
118
118
  entry: StorageFieldItem,
119
- metadata?: any,
119
+ metadata?: Record<string, unknown>,
120
120
  uploadedUrl?: string) => {
121
121
 
122
122
  console.debug("onFileUploadComplete", uploadedPath, entry);
@@ -242,7 +242,7 @@ export function useStorageUploadController<M extends Record<string, unknown>>({
242
242
 
243
243
  function getInternalInitialValue(multipleFilesSupported: boolean,
244
244
  value: string | string[] | null,
245
- metadata: Record<string, any> | undefined,
245
+ metadata: Record<string, unknown> | undefined,
246
246
  size: StorageFieldSize): StorageFieldItem[] {
247
247
  let strings: string[] = [];
248
248
  if (multipleFilesSupported) {
@@ -1,21 +0,0 @@
1
- import { AuthController, Authenticator, RebaseData, StorageSource, User } from "@rebasepro/types";
2
- /**
3
- * This hook is used internally for validating an authenticator.
4
- *
5
- * @param authController
6
- * @param authentication
7
- * @param storageSource
8
- * @param data
9
- */
10
- export declare function useValidateAuthenticator<USER extends User = any>({ disabled, authController, authenticator, storageSource, data }: {
11
- disabled?: boolean;
12
- authController: AuthController<USER>;
13
- authenticator?: boolean | Authenticator<USER>;
14
- data: RebaseData;
15
- storageSource: StorageSource;
16
- }): {
17
- canAccessMainView: boolean;
18
- authLoading: boolean;
19
- notAllowedError: any;
20
- authVerified: boolean;
21
- };
@@ -1 +0,0 @@
1
- export declare const iconSynonyms: Record<string, string>;
@@ -1,2 +0,0 @@
1
- export declare function printChanged(props: any, prev: any, path?: string | undefined, depth?: number | undefined, maxDepth?: number | undefined): void;
2
- export declare function useTraceUpdate(props: any, maxDepth?: number): void;
@@ -1,116 +0,0 @@
1
-
2
- import { useCallback, useEffect, useRef, useState, useMemo } from "react";
3
- import { deepEqual as equal } from "fast-equals";
4
-
5
- import { AuthController, Authenticator, RebaseData, StorageSource, User } from "@rebasepro/types";
6
-
7
- /**
8
- * This hook is used internally for validating an authenticator.
9
- *
10
- * @param authController
11
- * @param authentication
12
- * @param storageSource
13
- * @param data
14
- */
15
- export function useValidateAuthenticator<USER extends User = any>
16
- ({
17
- disabled,
18
- authController,
19
- authenticator,
20
- storageSource,
21
- data
22
- }:
23
- {
24
- disabled?: boolean,
25
- authController: AuthController<USER>,
26
- authenticator?: boolean | Authenticator<USER>,
27
- data: RebaseData;
28
- storageSource: StorageSource;
29
- }): {
30
- canAccessMainView: boolean,
31
- authLoading: boolean,
32
- notAllowedError: any,
33
- authVerified: boolean,
34
- } {
35
-
36
- const authenticationEnabled = Boolean(authenticator);
37
-
38
- const [authLoading, setAuthLoading] = useState<boolean>(authenticationEnabled);
39
- const [notAllowedError, setNotAllowedError] = useState<any>(false);
40
- const [authVerified, setAuthVerified] = useState<boolean>(!authenticationEnabled || Boolean(authController.loginSkipped));
41
-
42
- const canAccessMainView = (authVerified) &&
43
- (!authenticationEnabled || Boolean(authController.user) || Boolean(authController.loginSkipped)) &&
44
- !notAllowedError;
45
-
46
- useEffect(() => {
47
- if (authController.loginSkipped)
48
- setAuthVerified(true);
49
- }, [authController.loginSkipped]);
50
-
51
- /**
52
- * We use this ref to check the authentication only if the user has
53
- * changed.
54
- */
55
- const checkedUserRef = useRef<User | undefined>(undefined);
56
-
57
- const checkAuthentication = useCallback(async () => {
58
-
59
- if (disabled) {
60
- return;
61
- }
62
-
63
- if (authController.initialLoading) {
64
- return;
65
- }
66
-
67
- if (!authController.user && !authController.loginSkipped) {
68
- checkedUserRef.current = undefined;
69
- setAuthLoading(false);
70
- setAuthVerified(false);
71
- return;
72
- }
73
-
74
- const delegateUser = authController.user;
75
-
76
- if (authenticator instanceof Function && delegateUser && !equal(checkedUserRef.current?.uid, delegateUser.uid)) {
77
- setAuthLoading(true);
78
- try {
79
- const allowed = await authenticator({
80
- user: delegateUser,
81
- authController,
82
- data,
83
- storageSource
84
- });
85
- if (!allowed) {
86
- authController.signOut();
87
- setNotAllowedError(true);
88
- }
89
- } catch (e) {
90
- setNotAllowedError(e);
91
- authController.signOut();
92
- }
93
- setAuthLoading(false);
94
- setAuthVerified(true);
95
- checkedUserRef.current = delegateUser;
96
- } else {
97
- setAuthLoading(false);
98
- }
99
-
100
- if (!authController.initialLoading && !delegateUser) {
101
- setAuthVerified(true);
102
- }
103
-
104
- }, [disabled, authController, authenticator, data, storageSource]);
105
-
106
- useEffect(() => {
107
- checkAuthentication();
108
- }, [checkAuthentication]);
109
-
110
- return useMemo(() => ({
111
- canAccessMainView,
112
- authLoading: authenticationEnabled && authLoading,
113
- notAllowedError,
114
- authVerified
115
- }), [canAccessMainView, authenticationEnabled, authLoading, notAllowedError, authVerified]);
116
- }
@@ -1 +0,0 @@
1
- export const iconSynonyms: Record<string, string> = {};
@@ -1,24 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
-
3
- export function printChanged(props: any, prev: any, path: string | undefined = "", depth: number | undefined = 0, maxDepth: number | undefined = 10) {
4
- if (depth > maxDepth) {
5
- return;
6
- }
7
- if (props && prev && typeof props === "object" && typeof prev === "object") {
8
- Object.keys(props).forEach((key) => {
9
- printChanged(props[key], prev[key], path + "." + key, depth + 1, maxDepth);
10
- });
11
- } else if (props !== prev) {
12
- console.log("Changed props:", path);
13
- }
14
-
15
- }
16
-
17
- export function useTraceUpdate(props: any, maxDepth = 3) {
18
- const prev = useRef(props);
19
- useEffect(() => {
20
- console.log("Changed props:");
21
- printChanged(props, prev.current, "", 0, maxDepth);
22
- prev.current = props;
23
- });
24
- }