@nocios/crudify-ui 3.0.30 → 3.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +57 -12
- package/dist/index.mjs +57 -12
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -84,16 +84,30 @@ var import_react2 = require("react");
|
|
|
84
84
|
// src/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts
|
|
85
85
|
var import_react = require("react");
|
|
86
86
|
var useTranslationsFromUrl = (url, providedTranslations) => {
|
|
87
|
-
const [translations, setTranslations] = (0, import_react.useState)(
|
|
88
|
-
const [loading, setLoading] = (0, import_react.useState)(
|
|
87
|
+
const [translations, setTranslations] = (0, import_react.useState)({});
|
|
88
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
89
89
|
const [error, setError] = (0, import_react.useState)(null);
|
|
90
90
|
(0, import_react.useEffect)(() => {
|
|
91
|
+
console.log("\u{1F527} [I18nProvider] Hybrid translation loading:", {
|
|
92
|
+
hasProvidedTranslations: !!providedTranslations && Object.keys(providedTranslations).length > 0,
|
|
93
|
+
hasUrl: !!url,
|
|
94
|
+
providedKeys: providedTranslations ? Object.keys(providedTranslations).length : 0
|
|
95
|
+
});
|
|
96
|
+
if (providedTranslations && Object.keys(providedTranslations).length > 0) {
|
|
97
|
+
console.log("\u2705 [I18nProvider] Using provided translations (highest priority)");
|
|
98
|
+
setTranslations(providedTranslations);
|
|
99
|
+
setLoading(false);
|
|
100
|
+
setError(null);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
91
103
|
if (!url) {
|
|
92
|
-
|
|
104
|
+
console.log("\u26A0\uFE0F [I18nProvider] No translations provided, using empty object (keys will show as-is)");
|
|
105
|
+
setTranslations({});
|
|
93
106
|
setLoading(false);
|
|
94
107
|
setError(null);
|
|
95
108
|
return;
|
|
96
109
|
}
|
|
110
|
+
console.log("\u{1F310} [I18nProvider] Loading translations from URL:", url);
|
|
97
111
|
let isCancelled = false;
|
|
98
112
|
setLoading(true);
|
|
99
113
|
setError(null);
|
|
@@ -104,14 +118,19 @@ var useTranslationsFromUrl = (url, providedTranslations) => {
|
|
|
104
118
|
return response.json();
|
|
105
119
|
}).then((data) => {
|
|
106
120
|
if (!isCancelled) {
|
|
121
|
+
console.log("\u2705 [I18nProvider] Translations loaded successfully from URL:", {
|
|
122
|
+
url,
|
|
123
|
+
keysLoaded: Object.keys(data).length
|
|
124
|
+
});
|
|
107
125
|
setTranslations(data);
|
|
108
126
|
setLoading(false);
|
|
109
127
|
}
|
|
110
128
|
}).catch((err) => {
|
|
111
129
|
if (!isCancelled) {
|
|
112
|
-
console.error("
|
|
130
|
+
console.error("\u274C [I18nProvider] Failed to load translations from URL:", url, err);
|
|
113
131
|
setError(err.message);
|
|
114
|
-
|
|
132
|
+
console.log("\u{1F504} [I18nProvider] Falling back to empty translations (keys will show as-is)");
|
|
133
|
+
setTranslations({});
|
|
115
134
|
setLoading(false);
|
|
116
135
|
}
|
|
117
136
|
});
|
|
@@ -139,7 +158,11 @@ var I18nProvider = ({ children, translations, translationsUrl, language = "en" }
|
|
|
139
158
|
const { translations: loadedTranslations, loading } = useTranslationsFromUrl(translationsUrl, translations);
|
|
140
159
|
const t = (0, import_react2.useMemo)(() => {
|
|
141
160
|
return (key, variables) => {
|
|
142
|
-
let value = getNestedValue(loadedTranslations, key)
|
|
161
|
+
let value = getNestedValue(loadedTranslations, key);
|
|
162
|
+
if (value === void 0 || value === null) {
|
|
163
|
+
console.log(`\u{1F50D} [I18nProvider] Translation not found for key: "${key}" - showing key as-is`);
|
|
164
|
+
value = key;
|
|
165
|
+
}
|
|
143
166
|
if (variables && typeof value === "string") {
|
|
144
167
|
Object.entries(variables).forEach(([varKey, varValue]) => {
|
|
145
168
|
value = value.replace(new RegExp(`{{${varKey}}}`, "g"), varValue);
|
|
@@ -819,6 +842,9 @@ var SessionManager = class _SessionManager {
|
|
|
819
842
|
*/
|
|
820
843
|
setupResponseInterceptor() {
|
|
821
844
|
import_crudify_browser2.default.setResponseInterceptor(async (response) => {
|
|
845
|
+
if (response.errors) {
|
|
846
|
+
this.log("Response interceptor - received response with errors:", response);
|
|
847
|
+
}
|
|
822
848
|
if (response.errors) {
|
|
823
849
|
let hasAuthError = false;
|
|
824
850
|
if (Array.isArray(response.errors)) {
|
|
@@ -828,16 +854,35 @@ var SessionManager = class _SessionManager {
|
|
|
828
854
|
} else if (typeof response.errors === "object") {
|
|
829
855
|
const errorMessages = Object.values(response.errors).flat();
|
|
830
856
|
hasAuthError = errorMessages.some(
|
|
831
|
-
(message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
|
|
857
|
+
(message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("TOKEN_REFRESH_FAILED") || message.includes("PLEASE_LOGIN") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
|
|
832
858
|
);
|
|
833
859
|
}
|
|
834
|
-
if (hasAuthError &&
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
860
|
+
if (!hasAuthError && response.errorCode) {
|
|
861
|
+
const errorCode = response.errorCode;
|
|
862
|
+
hasAuthError = errorCode === "UNAUTHORIZED" || errorCode === "UNAUTHENTICATED" || errorCode === "TOKEN_EXPIRED";
|
|
863
|
+
}
|
|
864
|
+
if (hasAuthError) {
|
|
865
|
+
this.log("Auth error detected in response interceptor");
|
|
866
|
+
const isRefreshTokenFailed = response.errors && typeof response.errors === "object" && Object.values(response.errors).flat().some(
|
|
867
|
+
(message) => typeof message === "string" && message.includes("TOKEN_REFRESH_FAILED")
|
|
868
|
+
);
|
|
869
|
+
if (isRefreshTokenFailed) {
|
|
870
|
+
this.log("Refresh token failed, clearing tokens and triggering session expired");
|
|
871
|
+
TokenStorage.clearTokens();
|
|
872
|
+
this.config.onSessionExpired?.();
|
|
873
|
+
} else if (TokenStorage.hasValidTokens()) {
|
|
874
|
+
this.log("Auth error detected, attempting token refresh...");
|
|
875
|
+
const refreshSuccess = await this.refreshTokens();
|
|
876
|
+
if (!refreshSuccess) {
|
|
877
|
+
this.log("Session expired, triggering callback");
|
|
878
|
+
this.config.onSessionExpired?.();
|
|
879
|
+
}
|
|
880
|
+
} else {
|
|
881
|
+
this.log("Auth error but no valid tokens, triggering session expired");
|
|
839
882
|
this.config.onSessionExpired?.();
|
|
840
883
|
}
|
|
884
|
+
} else {
|
|
885
|
+
this.log("No auth error detected in response");
|
|
841
886
|
}
|
|
842
887
|
}
|
|
843
888
|
return response;
|
package/dist/index.mjs
CHANGED
|
@@ -11,16 +11,30 @@ import { createContext, useContext, useMemo } from "react";
|
|
|
11
11
|
// src/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts
|
|
12
12
|
import { useState, useEffect } from "react";
|
|
13
13
|
var useTranslationsFromUrl = (url, providedTranslations) => {
|
|
14
|
-
const [translations, setTranslations] = useState(
|
|
15
|
-
const [loading, setLoading] = useState(
|
|
14
|
+
const [translations, setTranslations] = useState({});
|
|
15
|
+
const [loading, setLoading] = useState(false);
|
|
16
16
|
const [error, setError] = useState(null);
|
|
17
17
|
useEffect(() => {
|
|
18
|
+
console.log("\u{1F527} [I18nProvider] Hybrid translation loading:", {
|
|
19
|
+
hasProvidedTranslations: !!providedTranslations && Object.keys(providedTranslations).length > 0,
|
|
20
|
+
hasUrl: !!url,
|
|
21
|
+
providedKeys: providedTranslations ? Object.keys(providedTranslations).length : 0
|
|
22
|
+
});
|
|
23
|
+
if (providedTranslations && Object.keys(providedTranslations).length > 0) {
|
|
24
|
+
console.log("\u2705 [I18nProvider] Using provided translations (highest priority)");
|
|
25
|
+
setTranslations(providedTranslations);
|
|
26
|
+
setLoading(false);
|
|
27
|
+
setError(null);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
18
30
|
if (!url) {
|
|
19
|
-
|
|
31
|
+
console.log("\u26A0\uFE0F [I18nProvider] No translations provided, using empty object (keys will show as-is)");
|
|
32
|
+
setTranslations({});
|
|
20
33
|
setLoading(false);
|
|
21
34
|
setError(null);
|
|
22
35
|
return;
|
|
23
36
|
}
|
|
37
|
+
console.log("\u{1F310} [I18nProvider] Loading translations from URL:", url);
|
|
24
38
|
let isCancelled = false;
|
|
25
39
|
setLoading(true);
|
|
26
40
|
setError(null);
|
|
@@ -31,14 +45,19 @@ var useTranslationsFromUrl = (url, providedTranslations) => {
|
|
|
31
45
|
return response.json();
|
|
32
46
|
}).then((data) => {
|
|
33
47
|
if (!isCancelled) {
|
|
48
|
+
console.log("\u2705 [I18nProvider] Translations loaded successfully from URL:", {
|
|
49
|
+
url,
|
|
50
|
+
keysLoaded: Object.keys(data).length
|
|
51
|
+
});
|
|
34
52
|
setTranslations(data);
|
|
35
53
|
setLoading(false);
|
|
36
54
|
}
|
|
37
55
|
}).catch((err) => {
|
|
38
56
|
if (!isCancelled) {
|
|
39
|
-
console.error("
|
|
57
|
+
console.error("\u274C [I18nProvider] Failed to load translations from URL:", url, err);
|
|
40
58
|
setError(err.message);
|
|
41
|
-
|
|
59
|
+
console.log("\u{1F504} [I18nProvider] Falling back to empty translations (keys will show as-is)");
|
|
60
|
+
setTranslations({});
|
|
42
61
|
setLoading(false);
|
|
43
62
|
}
|
|
44
63
|
});
|
|
@@ -66,7 +85,11 @@ var I18nProvider = ({ children, translations, translationsUrl, language = "en" }
|
|
|
66
85
|
const { translations: loadedTranslations, loading } = useTranslationsFromUrl(translationsUrl, translations);
|
|
67
86
|
const t = useMemo(() => {
|
|
68
87
|
return (key, variables) => {
|
|
69
|
-
let value = getNestedValue(loadedTranslations, key)
|
|
88
|
+
let value = getNestedValue(loadedTranslations, key);
|
|
89
|
+
if (value === void 0 || value === null) {
|
|
90
|
+
console.log(`\u{1F50D} [I18nProvider] Translation not found for key: "${key}" - showing key as-is`);
|
|
91
|
+
value = key;
|
|
92
|
+
}
|
|
70
93
|
if (variables && typeof value === "string") {
|
|
71
94
|
Object.entries(variables).forEach(([varKey, varValue]) => {
|
|
72
95
|
value = value.replace(new RegExp(`{{${varKey}}}`, "g"), varValue);
|
|
@@ -746,6 +769,9 @@ var SessionManager = class _SessionManager {
|
|
|
746
769
|
*/
|
|
747
770
|
setupResponseInterceptor() {
|
|
748
771
|
crudify2.setResponseInterceptor(async (response) => {
|
|
772
|
+
if (response.errors) {
|
|
773
|
+
this.log("Response interceptor - received response with errors:", response);
|
|
774
|
+
}
|
|
749
775
|
if (response.errors) {
|
|
750
776
|
let hasAuthError = false;
|
|
751
777
|
if (Array.isArray(response.errors)) {
|
|
@@ -755,16 +781,35 @@ var SessionManager = class _SessionManager {
|
|
|
755
781
|
} else if (typeof response.errors === "object") {
|
|
756
782
|
const errorMessages = Object.values(response.errors).flat();
|
|
757
783
|
hasAuthError = errorMessages.some(
|
|
758
|
-
(message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
|
|
784
|
+
(message) => typeof message === "string" && (message.includes("NOT_AUTHORIZED") || message.includes("TOKEN_REFRESH_FAILED") || message.includes("PLEASE_LOGIN") || message.includes("Unauthorized") || message.includes("UNAUTHENTICATED") || message.includes("Token"))
|
|
759
785
|
);
|
|
760
786
|
}
|
|
761
|
-
if (hasAuthError &&
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
787
|
+
if (!hasAuthError && response.errorCode) {
|
|
788
|
+
const errorCode = response.errorCode;
|
|
789
|
+
hasAuthError = errorCode === "UNAUTHORIZED" || errorCode === "UNAUTHENTICATED" || errorCode === "TOKEN_EXPIRED";
|
|
790
|
+
}
|
|
791
|
+
if (hasAuthError) {
|
|
792
|
+
this.log("Auth error detected in response interceptor");
|
|
793
|
+
const isRefreshTokenFailed = response.errors && typeof response.errors === "object" && Object.values(response.errors).flat().some(
|
|
794
|
+
(message) => typeof message === "string" && message.includes("TOKEN_REFRESH_FAILED")
|
|
795
|
+
);
|
|
796
|
+
if (isRefreshTokenFailed) {
|
|
797
|
+
this.log("Refresh token failed, clearing tokens and triggering session expired");
|
|
798
|
+
TokenStorage.clearTokens();
|
|
799
|
+
this.config.onSessionExpired?.();
|
|
800
|
+
} else if (TokenStorage.hasValidTokens()) {
|
|
801
|
+
this.log("Auth error detected, attempting token refresh...");
|
|
802
|
+
const refreshSuccess = await this.refreshTokens();
|
|
803
|
+
if (!refreshSuccess) {
|
|
804
|
+
this.log("Session expired, triggering callback");
|
|
805
|
+
this.config.onSessionExpired?.();
|
|
806
|
+
}
|
|
807
|
+
} else {
|
|
808
|
+
this.log("Auth error but no valid tokens, triggering session expired");
|
|
766
809
|
this.config.onSessionExpired?.();
|
|
767
810
|
}
|
|
811
|
+
} else {
|
|
812
|
+
this.log("No auth error detected in response");
|
|
768
813
|
}
|
|
769
814
|
}
|
|
770
815
|
return response;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocios/crudify-ui",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.42",
|
|
4
4
|
"description": "Biblioteca de componentes UI para Crudify",
|
|
5
5
|
"author": "Nocios",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@mui/icons-material": "^7.1.0",
|
|
26
26
|
"@mui/material": "^7.1.0",
|
|
27
27
|
"@mui/x-data-grid": "^8.5.1",
|
|
28
|
-
"@nocios/crudify-browser": "^2.0.
|
|
28
|
+
"@nocios/crudify-browser": "^2.0.2",
|
|
29
29
|
"@types/uuid": "^10.0.0",
|
|
30
30
|
"crypto-js": "^4.2.0",
|
|
31
31
|
"i18next-browser-languagedetector": "^8.1.0",
|