@rebasepro/core 0.2.3 → 0.2.4
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/LoginView/LoginView.d.ts +17 -1
- package/dist/components/common/types.d.ts +10 -7
- package/dist/components/common/useDebouncedData.d.ts +1 -1
- package/dist/core/RebaseProps.d.ts +13 -2
- package/dist/core/RebaseRouter.d.ts +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.es.js +499 -418
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +499 -418
- package/dist/index.umd.js.map +1 -1
- package/dist/util/entity_cache.d.ts +0 -5
- package/dist/util/index.d.ts +0 -2
- package/dist/util/useStorageUploadController.d.ts +2 -2
- package/package.json +6 -6
- package/src/components/BootstrapAdminBanner.tsx +12 -3
- package/src/components/LoginView/LoginView.tsx +151 -6
- package/src/components/UserSettingsView.tsx +95 -2
- package/src/components/common/types.tsx +7 -7
- package/src/components/common/useDebouncedData.ts +2 -2
- package/src/core/Rebase.tsx +3 -2
- package/src/core/RebaseProps.tsx +15 -2
- package/src/core/RebaseRouter.tsx +1 -1
- package/src/hooks/index.tsx +0 -1
- package/src/hooks/useResolvedComponent.tsx +4 -3
- package/src/locales/en.ts +13 -0
- package/src/locales/es.ts +11 -1
- package/src/util/entity_cache.ts +1 -27
- package/src/util/icon_list.ts +2 -2
- package/src/util/index.ts +2 -2
- package/src/util/useStorageUploadController.tsx +4 -4
- package/dist/hooks/useValidateAuthenticator.d.ts +0 -21
- package/dist/util/icon_synonyms.d.ts +0 -1
- package/dist/util/useTraceUpdate.d.ts +0 -2
- package/src/hooks/useValidateAuthenticator.tsx +0 -116
- package/src/util/icon_synonyms.ts +0 -1
- package/src/util/useTraceUpdate.tsx +0 -24
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: "
|
|
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",
|
package/src/util/entity_cache.ts
CHANGED
|
@@ -154,9 +154,7 @@ export function getEntityFromMemoryCache(path: string): object | undefined {
|
|
|
154
154
|
return entityCache.get(path);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
|
|
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
|
|
package/src/util/icon_list.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
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 ?
|
|
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
|
-
|
|
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
|
-
|
|
9
|
+
|
|
10
10
|
export * from "./previews";
|
|
11
11
|
export * from "./enums";
|
|
12
12
|
export * from "./constants";
|
|
@@ -21,7 +21,7 @@ export interface StorageFieldItem {
|
|
|
21
21
|
storagePathOrDownloadUrl?: string;
|
|
22
22
|
file?: File;
|
|
23
23
|
fileName?: string;
|
|
24
|
-
metadata?:
|
|
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,
|
|
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?:
|
|
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,
|
|
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,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
|
-
}
|