@nocios/crudify-ui 1.0.40 → 1.0.43

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.d.mts CHANGED
@@ -5,7 +5,7 @@ import React from 'react';
5
5
  type BoxScreenType = "login" | "signUp" | "forgotPassword" | "resetPassword" | "checkCode";
6
6
  interface CrudifyLoginConfig {
7
7
  publicApiKey?: string;
8
- env?: "dev" | "stg" | "prod";
8
+ env?: "dev" | "stg" | "api" | "prod";
9
9
  appName?: string;
10
10
  logo?: string;
11
11
  colors?: {
@@ -23,7 +23,6 @@ interface CrudifyLoginProps {
23
23
  initialScreen?: BoxScreenType;
24
24
  redirectUrl?: string;
25
25
  autoReadFromCookies?: boolean;
26
- onSubdomainLoginSuccess?: (token: string, config: CrudifyLoginConfig) => void;
27
26
  }
28
27
 
29
28
  declare const CrudifyLogin: React.FC<CrudifyLoginProps>;
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import React from 'react';
5
5
  type BoxScreenType = "login" | "signUp" | "forgotPassword" | "resetPassword" | "checkCode";
6
6
  interface CrudifyLoginConfig {
7
7
  publicApiKey?: string;
8
- env?: "dev" | "stg" | "prod";
8
+ env?: "dev" | "stg" | "api" | "prod";
9
9
  appName?: string;
10
10
  logo?: string;
11
11
  colors?: {
@@ -23,7 +23,6 @@ interface CrudifyLoginProps {
23
23
  initialScreen?: BoxScreenType;
24
24
  redirectUrl?: string;
25
25
  autoReadFromCookies?: boolean;
26
- onSubdomainLoginSuccess?: (token: string, config: CrudifyLoginConfig) => void;
27
26
  }
28
27
 
29
28
  declare const CrudifyLogin: React.FC<CrudifyLoginProps>;
package/dist/index.js CHANGED
@@ -32,13 +32,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
34
  CrudifyLogin: () => CrudifyLogin_default,
35
- crudify: () => import_crudify_browser3.default,
35
+ crudify: () => import_crudify_browser2.default,
36
36
  getCookie: () => getCookie,
37
37
  secureLocalStorage: () => secureLocalStorage,
38
38
  secureSessionStorage: () => secureSessionStorage
39
39
  });
40
40
  module.exports = __toCommonJS(index_exports);
41
- var import_crudify_browser3 = __toESM(require("@nocios/crudify-browser"));
41
+ var import_crudify_browser2 = __toESM(require("@nocios/crudify-browser"));
42
42
  __reExport(index_exports, require("@nocios/crudify-browser"), module.exports);
43
43
 
44
44
  // src/components/CrudifyLogin/index.tsx
@@ -177,27 +177,16 @@ var secureSessionStorage = new SecureStorage("sessionStorage");
177
177
  var secureLocalStorage = new SecureStorage("localStorage");
178
178
 
179
179
  // src/components/CrudifyLogin/Forms/LoginForm.tsx
180
- var import_crudify_browser2 = __toESM(require("@nocios/crudify-browser"));
181
180
  var import_jsx_runtime = require("react/jsx-runtime");
182
- var LoginForm = ({
183
- config,
184
- onNavigate,
185
- onLoginSuccess,
186
- onError,
187
- redirectUrl = "/",
188
- onSubdomainLoginSuccess
189
- }) => {
181
+ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/" }) => {
190
182
  const [username, setUsername] = (0, import_react2.useState)("");
191
183
  const [password, setPassword] = (0, import_react2.useState)("");
192
- const [subdomain, setSubdomain] = (0, import_react2.useState)("");
193
184
  const [loading, setLoading] = (0, import_react2.useState)(false);
194
185
  const [errors, setErrors] = (0, import_react2.useState)([]);
195
186
  const [helperTextEmail, setHelperTextEmail] = (0, import_react2.useState)(null);
196
187
  const [helperTextPassword, setHelperTextPassword] = (0, import_react2.useState)(null);
197
- const [helperTextSubdomain, setHelperTextSubdomain] = (0, import_react2.useState)(null);
198
188
  const { t } = (0, import_react_i18next.useTranslation)();
199
189
  const usernameInputRef = (0, import_react2.useRef)(null);
200
- const hasPublicApiKey = Boolean(config.publicApiKey);
201
190
  const { crudify: crudifyFromHook } = useCrudifyLogin(config, {
202
191
  showErrorNotifications: false,
203
192
  showSuccessNotifications: false
@@ -234,41 +223,19 @@ var LoginForm = ({
234
223
  setHelperTextPassword(t("login.passwordRequired"));
235
224
  return;
236
225
  }
237
- if (!hasPublicApiKey && !subdomain.trim()) {
238
- setHelperTextSubdomain(t("login.subdomainRequired", "Subdomain is required"));
239
- return;
240
- }
241
226
  setErrors([]);
242
227
  setHelperTextEmail(null);
243
228
  setHelperTextPassword(null);
244
- setHelperTextSubdomain(null);
245
229
  setLoading(true);
246
230
  try {
247
- let response;
248
- if (hasPublicApiKey && crudifyFromHook) {
249
- response = await crudifyFromHook.login(username, password);
250
- } else {
251
- try {
252
- import_crudify_browser2.default.config(config.env || "prod");
253
- response = await import_crudify_browser2.default.loginWithSubdomain(username, password, subdomain);
254
- } catch (subdomainError) {
255
- console.error("Error during subdomain login:", subdomainError);
256
- throw subdomainError;
257
- }
231
+ if (!crudifyFromHook) {
232
+ throw new Error("Crudify not initialized");
258
233
  }
234
+ const response = await crudifyFromHook.login(username, password);
259
235
  setLoading(false);
260
236
  if (response.success) {
261
237
  secureSessionStorage.setToken(response.data.token);
262
- if (!hasPublicApiKey && onSubdomainLoginSuccess) {
263
- const newConfig = {
264
- ...config,
265
- publicApiKey: response.data.publicApiKey || config.publicApiKey,
266
- appName: response.data.appName || config.appName,
267
- logo: response.data.logo || config.logo,
268
- colors: response.data.colors || config.colors
269
- };
270
- onSubdomainLoginSuccess(response.data.token, newConfig);
271
- } else if (onLoginSuccess) {
238
+ if (onLoginSuccess) {
272
239
  onLoginSuccess(response.data.token, redirectUrl);
273
240
  }
274
241
  } else {
@@ -289,15 +256,12 @@ var LoginForm = ({
289
256
  if (fieldsWarning) {
290
257
  if (fieldsWarning.username) setHelperTextEmail(fieldsWarning.username[0]);
291
258
  if (fieldsWarning.password) setHelperTextPassword(fieldsWarning.password[0]);
292
- if (fieldsWarning.subdomain) setHelperTextSubdomain(fieldsWarning.subdomain[0]);
293
259
  } else if (status === "INVALID_CREDENTIALS") {
294
260
  const translatedError = getSafeErrorTranslation(status);
295
261
  setErrors([translatedError]);
296
262
  } else if (status === "TOO_MANY_REQUESTS") {
297
263
  const translatedError = getSafeErrorTranslation(status);
298
264
  setErrors([translatedError]);
299
- } else if (status === "SUBDOMAIN_NOT_FOUND") {
300
- setHelperTextSubdomain(t("login.subdomainNotFound", "Subdomain not found"));
301
265
  } else if (status) {
302
266
  setErrors([getSafeErrorTranslation(status)]);
303
267
  } else {
@@ -310,11 +274,9 @@ var LoginForm = ({
310
274
  } else if (typeof errors2 === "object") {
311
275
  const hasUsernameError = errors2.username && errors2.username.length > 0;
312
276
  const hasPasswordError = errors2.password && errors2.password.length > 0;
313
- const hasSubdomainError = errors2.subdomain && errors2.subdomain.length > 0;
314
- if (hasUsernameError || hasPasswordError || hasSubdomainError) {
277
+ if (hasUsernameError || hasPasswordError) {
315
278
  if (hasUsernameError) setHelperTextEmail(errors2.username[0]);
316
279
  if (hasPasswordError) setHelperTextPassword(errors2.password[0]);
317
- if (hasSubdomainError) setHelperTextSubdomain(errors2.subdomain[0]);
318
280
  } else if (errors2._error && errors2._error.length > 0) {
319
281
  const errorMessage = errors2._error[0];
320
282
  if (typeof errorMessage === "string" && errorMessage.match(/^[A-Z_]+$/)) {
@@ -351,34 +313,6 @@ var LoginForm = ({
351
313
  onKeyDown: handleKeyDown,
352
314
  sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 },
353
315
  children: [
354
- !hasPublicApiKey && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_material.Box, { sx: { mb: 1 }, children: [
355
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
356
- import_material.Typography,
357
- {
358
- variant: "body2",
359
- component: "label",
360
- htmlFor: "subdomain",
361
- sx: { display: "block", fontWeight: 500, color: "grey.700", mb: 0.5 },
362
- children: t("login.subdomainLabel", "Subdomain")
363
- }
364
- ),
365
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
366
- import_material.TextField,
367
- {
368
- fullWidth: true,
369
- id: "subdomain",
370
- name: "subdomain",
371
- type: "text",
372
- value: subdomain,
373
- disabled: loading,
374
- onChange: (e) => setSubdomain(e.target.value),
375
- error: !!helperTextSubdomain,
376
- helperText: helperTextSubdomain,
377
- placeholder: t("login.subdomainPlaceholder", "Enter your subdomain"),
378
- required: true
379
- }
380
- )
381
- ] }),
382
316
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_material.Box, { sx: { mb: 1 }, children: [
383
317
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
384
318
  import_material.Typography,
@@ -466,13 +400,13 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
466
400
  const [emailSent, setEmailSent] = (0, import_react3.useState)(false);
467
401
  const [codeAlreadyExists, setCodeAlreadyExists] = (0, import_react3.useState)(false);
468
402
  const { t } = (0, import_react_i18next2.useTranslation)();
469
- const { crudify: crudify3 } = useCrudifyLogin(config);
403
+ const { crudify: crudify2 } = useCrudifyLogin(config);
470
404
  const validateEmail = (email2) => {
471
405
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
472
406
  return emailRegex.test(email2);
473
407
  };
474
408
  const handleSubmit = async () => {
475
- if (loading || !crudify3) return;
409
+ if (loading || !crudify2) return;
476
410
  setErrors([]);
477
411
  setHelperTextEmail(null);
478
412
  if (!email) {
@@ -486,7 +420,7 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
486
420
  setLoading(true);
487
421
  try {
488
422
  const data = [{ operation: "requestPasswordReset", data: { email } }];
489
- const response = await crudify3.transaction(data);
423
+ const response = await crudify2.transaction(data);
490
424
  if (response.success) {
491
425
  if (response.data && response.data.existingCodeValid) {
492
426
  setCodeAlreadyExists(true);
@@ -594,10 +528,10 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
594
528
  const [codeValidated, setCodeValidated] = (0, import_react4.useState)(false);
595
529
  const [resetSuccess, setResetSuccess] = (0, import_react4.useState)(false);
596
530
  const { t } = (0, import_react_i18next3.useTranslation)();
597
- const { crudify: crudify3 } = useCrudifyLogin(config);
531
+ const { crudify: crudify2 } = useCrudifyLogin(config);
598
532
  (0, import_react4.useEffect)(() => {
599
533
  const validateCode = async (emailToValidate, codeToValidate) => {
600
- if (!crudify3) return;
534
+ if (!crudify2) return;
601
535
  try {
602
536
  const data = [
603
537
  {
@@ -605,7 +539,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
605
539
  data: { email: emailToValidate, codePassword: codeToValidate }
606
540
  }
607
541
  ];
608
- const response = await crudify3.transaction(data);
542
+ const response = await crudify2.transaction(data);
609
543
  if (response.success) {
610
544
  setCodeValidated(true);
611
545
  } else {
@@ -633,7 +567,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
633
567
  setValidatingCode(false);
634
568
  setErrors([t("resetPassword.missingParameters")]);
635
569
  }
636
- }, [searchParams, crudify3, t]);
570
+ }, [searchParams, crudify2, t]);
637
571
  const validatePasswords = () => {
638
572
  setHelperTextNewPassword(null);
639
573
  setHelperTextConfirmPassword(null);
@@ -656,7 +590,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
656
590
  return true;
657
591
  };
658
592
  const handleSubmit = async () => {
659
- if (loading || !crudify3) return;
593
+ if (loading || !crudify2) return;
660
594
  setErrors([]);
661
595
  if (!validatePasswords()) return;
662
596
  setLoading(true);
@@ -667,7 +601,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
667
601
  data: { email, codePassword: code, newPassword }
668
602
  }
669
603
  ];
670
- const response = await crudify3.transaction(data);
604
+ const response = await crudify2.transaction(data);
671
605
  if (response.success) {
672
606
  setResetSuccess(true);
673
607
  } else {
@@ -811,7 +745,7 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
811
745
  const [helperTextEmail, setHelperTextEmail] = (0, import_react5.useState)(null);
812
746
  const [helperTextCode, setHelperTextCode] = (0, import_react5.useState)(null);
813
747
  const { t } = (0, import_react_i18next4.useTranslation)();
814
- const { crudify: crudify3 } = useCrudifyLogin(config);
748
+ const { crudify: crudify2 } = useCrudifyLogin(config);
815
749
  (0, import_react5.useEffect)(() => {
816
750
  const timer = setTimeout(() => {
817
751
  const emailInput = document.getElementById("email");
@@ -824,7 +758,7 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
824
758
  return emailRegex.test(email2);
825
759
  };
826
760
  const handleSubmit = async () => {
827
- if (loading || !crudify3) return;
761
+ if (loading || !crudify2) return;
828
762
  setErrors([]);
829
763
  setHelperTextEmail(null);
830
764
  setHelperTextCode(null);
@@ -848,7 +782,7 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
848
782
  data: { email, codePassword: code }
849
783
  }
850
784
  ];
851
- const response = await crudify3.transaction(data);
785
+ const response = await crudify2.transaction(data);
852
786
  if (response.success) {
853
787
  const params = new URLSearchParams({ email, code }).toString();
854
788
  onNavigate?.(`/login/resetPassword?${params}`);
@@ -970,7 +904,6 @@ var CrudifyLogin = ({
970
904
  onNavigate,
971
905
  onLoginSuccess,
972
906
  onError,
973
- onSubdomainLoginSuccess,
974
907
  initialScreen = "login",
975
908
  redirectUrl = "/",
976
909
  autoReadFromCookies = true
@@ -1061,7 +994,7 @@ var CrudifyLogin = ({
1061
994
  case "resetPassword":
1062
995
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ResetPasswordForm_default, { ...commonProps, searchParams });
1063
996
  default:
1064
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LoginForm_default, { ...commonProps, onLoginSuccess, onSubdomainLoginSuccess });
997
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LoginForm_default, { ...commonProps, onLoginSuccess });
1065
998
  }
1066
999
  };
1067
1000
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
package/dist/index.mjs CHANGED
@@ -138,27 +138,16 @@ var secureSessionStorage = new SecureStorage("sessionStorage");
138
138
  var secureLocalStorage = new SecureStorage("localStorage");
139
139
 
140
140
  // src/components/CrudifyLogin/Forms/LoginForm.tsx
141
- import crudify2 from "@nocios/crudify-browser";
142
141
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
143
- var LoginForm = ({
144
- config,
145
- onNavigate,
146
- onLoginSuccess,
147
- onError,
148
- redirectUrl = "/",
149
- onSubdomainLoginSuccess
150
- }) => {
142
+ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/" }) => {
151
143
  const [username, setUsername] = useState("");
152
144
  const [password, setPassword] = useState("");
153
- const [subdomain, setSubdomain] = useState("");
154
145
  const [loading, setLoading] = useState(false);
155
146
  const [errors, setErrors] = useState([]);
156
147
  const [helperTextEmail, setHelperTextEmail] = useState(null);
157
148
  const [helperTextPassword, setHelperTextPassword] = useState(null);
158
- const [helperTextSubdomain, setHelperTextSubdomain] = useState(null);
159
149
  const { t } = useTranslation();
160
150
  const usernameInputRef = useRef(null);
161
- const hasPublicApiKey = Boolean(config.publicApiKey);
162
151
  const { crudify: crudifyFromHook } = useCrudifyLogin(config, {
163
152
  showErrorNotifications: false,
164
153
  showSuccessNotifications: false
@@ -195,41 +184,19 @@ var LoginForm = ({
195
184
  setHelperTextPassword(t("login.passwordRequired"));
196
185
  return;
197
186
  }
198
- if (!hasPublicApiKey && !subdomain.trim()) {
199
- setHelperTextSubdomain(t("login.subdomainRequired", "Subdomain is required"));
200
- return;
201
- }
202
187
  setErrors([]);
203
188
  setHelperTextEmail(null);
204
189
  setHelperTextPassword(null);
205
- setHelperTextSubdomain(null);
206
190
  setLoading(true);
207
191
  try {
208
- let response;
209
- if (hasPublicApiKey && crudifyFromHook) {
210
- response = await crudifyFromHook.login(username, password);
211
- } else {
212
- try {
213
- crudify2.config(config.env || "prod");
214
- response = await crudify2.loginWithSubdomain(username, password, subdomain);
215
- } catch (subdomainError) {
216
- console.error("Error during subdomain login:", subdomainError);
217
- throw subdomainError;
218
- }
192
+ if (!crudifyFromHook) {
193
+ throw new Error("Crudify not initialized");
219
194
  }
195
+ const response = await crudifyFromHook.login(username, password);
220
196
  setLoading(false);
221
197
  if (response.success) {
222
198
  secureSessionStorage.setToken(response.data.token);
223
- if (!hasPublicApiKey && onSubdomainLoginSuccess) {
224
- const newConfig = {
225
- ...config,
226
- publicApiKey: response.data.publicApiKey || config.publicApiKey,
227
- appName: response.data.appName || config.appName,
228
- logo: response.data.logo || config.logo,
229
- colors: response.data.colors || config.colors
230
- };
231
- onSubdomainLoginSuccess(response.data.token, newConfig);
232
- } else if (onLoginSuccess) {
199
+ if (onLoginSuccess) {
233
200
  onLoginSuccess(response.data.token, redirectUrl);
234
201
  }
235
202
  } else {
@@ -250,15 +217,12 @@ var LoginForm = ({
250
217
  if (fieldsWarning) {
251
218
  if (fieldsWarning.username) setHelperTextEmail(fieldsWarning.username[0]);
252
219
  if (fieldsWarning.password) setHelperTextPassword(fieldsWarning.password[0]);
253
- if (fieldsWarning.subdomain) setHelperTextSubdomain(fieldsWarning.subdomain[0]);
254
220
  } else if (status === "INVALID_CREDENTIALS") {
255
221
  const translatedError = getSafeErrorTranslation(status);
256
222
  setErrors([translatedError]);
257
223
  } else if (status === "TOO_MANY_REQUESTS") {
258
224
  const translatedError = getSafeErrorTranslation(status);
259
225
  setErrors([translatedError]);
260
- } else if (status === "SUBDOMAIN_NOT_FOUND") {
261
- setHelperTextSubdomain(t("login.subdomainNotFound", "Subdomain not found"));
262
226
  } else if (status) {
263
227
  setErrors([getSafeErrorTranslation(status)]);
264
228
  } else {
@@ -271,11 +235,9 @@ var LoginForm = ({
271
235
  } else if (typeof errors2 === "object") {
272
236
  const hasUsernameError = errors2.username && errors2.username.length > 0;
273
237
  const hasPasswordError = errors2.password && errors2.password.length > 0;
274
- const hasSubdomainError = errors2.subdomain && errors2.subdomain.length > 0;
275
- if (hasUsernameError || hasPasswordError || hasSubdomainError) {
238
+ if (hasUsernameError || hasPasswordError) {
276
239
  if (hasUsernameError) setHelperTextEmail(errors2.username[0]);
277
240
  if (hasPasswordError) setHelperTextPassword(errors2.password[0]);
278
- if (hasSubdomainError) setHelperTextSubdomain(errors2.subdomain[0]);
279
241
  } else if (errors2._error && errors2._error.length > 0) {
280
242
  const errorMessage = errors2._error[0];
281
243
  if (typeof errorMessage === "string" && errorMessage.match(/^[A-Z_]+$/)) {
@@ -312,34 +274,6 @@ var LoginForm = ({
312
274
  onKeyDown: handleKeyDown,
313
275
  sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 },
314
276
  children: [
315
- !hasPublicApiKey && /* @__PURE__ */ jsxs(Box, { sx: { mb: 1 }, children: [
316
- /* @__PURE__ */ jsx(
317
- Typography,
318
- {
319
- variant: "body2",
320
- component: "label",
321
- htmlFor: "subdomain",
322
- sx: { display: "block", fontWeight: 500, color: "grey.700", mb: 0.5 },
323
- children: t("login.subdomainLabel", "Subdomain")
324
- }
325
- ),
326
- /* @__PURE__ */ jsx(
327
- TextField,
328
- {
329
- fullWidth: true,
330
- id: "subdomain",
331
- name: "subdomain",
332
- type: "text",
333
- value: subdomain,
334
- disabled: loading,
335
- onChange: (e) => setSubdomain(e.target.value),
336
- error: !!helperTextSubdomain,
337
- helperText: helperTextSubdomain,
338
- placeholder: t("login.subdomainPlaceholder", "Enter your subdomain"),
339
- required: true
340
- }
341
- )
342
- ] }),
343
277
  /* @__PURE__ */ jsxs(Box, { sx: { mb: 1 }, children: [
344
278
  /* @__PURE__ */ jsx(
345
279
  Typography,
@@ -427,13 +361,13 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
427
361
  const [emailSent, setEmailSent] = useState2(false);
428
362
  const [codeAlreadyExists, setCodeAlreadyExists] = useState2(false);
429
363
  const { t } = useTranslation2();
430
- const { crudify: crudify3 } = useCrudifyLogin(config);
364
+ const { crudify: crudify2 } = useCrudifyLogin(config);
431
365
  const validateEmail = (email2) => {
432
366
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
433
367
  return emailRegex.test(email2);
434
368
  };
435
369
  const handleSubmit = async () => {
436
- if (loading || !crudify3) return;
370
+ if (loading || !crudify2) return;
437
371
  setErrors([]);
438
372
  setHelperTextEmail(null);
439
373
  if (!email) {
@@ -447,7 +381,7 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
447
381
  setLoading(true);
448
382
  try {
449
383
  const data = [{ operation: "requestPasswordReset", data: { email } }];
450
- const response = await crudify3.transaction(data);
384
+ const response = await crudify2.transaction(data);
451
385
  if (response.success) {
452
386
  if (response.data && response.data.existingCodeValid) {
453
387
  setCodeAlreadyExists(true);
@@ -555,10 +489,10 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
555
489
  const [codeValidated, setCodeValidated] = useState3(false);
556
490
  const [resetSuccess, setResetSuccess] = useState3(false);
557
491
  const { t } = useTranslation3();
558
- const { crudify: crudify3 } = useCrudifyLogin(config);
492
+ const { crudify: crudify2 } = useCrudifyLogin(config);
559
493
  useEffect2(() => {
560
494
  const validateCode = async (emailToValidate, codeToValidate) => {
561
- if (!crudify3) return;
495
+ if (!crudify2) return;
562
496
  try {
563
497
  const data = [
564
498
  {
@@ -566,7 +500,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
566
500
  data: { email: emailToValidate, codePassword: codeToValidate }
567
501
  }
568
502
  ];
569
- const response = await crudify3.transaction(data);
503
+ const response = await crudify2.transaction(data);
570
504
  if (response.success) {
571
505
  setCodeValidated(true);
572
506
  } else {
@@ -594,7 +528,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
594
528
  setValidatingCode(false);
595
529
  setErrors([t("resetPassword.missingParameters")]);
596
530
  }
597
- }, [searchParams, crudify3, t]);
531
+ }, [searchParams, crudify2, t]);
598
532
  const validatePasswords = () => {
599
533
  setHelperTextNewPassword(null);
600
534
  setHelperTextConfirmPassword(null);
@@ -617,7 +551,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
617
551
  return true;
618
552
  };
619
553
  const handleSubmit = async () => {
620
- if (loading || !crudify3) return;
554
+ if (loading || !crudify2) return;
621
555
  setErrors([]);
622
556
  if (!validatePasswords()) return;
623
557
  setLoading(true);
@@ -628,7 +562,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
628
562
  data: { email, codePassword: code, newPassword }
629
563
  }
630
564
  ];
631
- const response = await crudify3.transaction(data);
565
+ const response = await crudify2.transaction(data);
632
566
  if (response.success) {
633
567
  setResetSuccess(true);
634
568
  } else {
@@ -772,7 +706,7 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
772
706
  const [helperTextEmail, setHelperTextEmail] = useState4(null);
773
707
  const [helperTextCode, setHelperTextCode] = useState4(null);
774
708
  const { t } = useTranslation4();
775
- const { crudify: crudify3 } = useCrudifyLogin(config);
709
+ const { crudify: crudify2 } = useCrudifyLogin(config);
776
710
  useEffect3(() => {
777
711
  const timer = setTimeout(() => {
778
712
  const emailInput = document.getElementById("email");
@@ -785,7 +719,7 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
785
719
  return emailRegex.test(email2);
786
720
  };
787
721
  const handleSubmit = async () => {
788
- if (loading || !crudify3) return;
722
+ if (loading || !crudify2) return;
789
723
  setErrors([]);
790
724
  setHelperTextEmail(null);
791
725
  setHelperTextCode(null);
@@ -809,7 +743,7 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
809
743
  data: { email, codePassword: code }
810
744
  }
811
745
  ];
812
- const response = await crudify3.transaction(data);
746
+ const response = await crudify2.transaction(data);
813
747
  if (response.success) {
814
748
  const params = new URLSearchParams({ email, code }).toString();
815
749
  onNavigate?.(`/login/resetPassword?${params}`);
@@ -931,7 +865,6 @@ var CrudifyLogin = ({
931
865
  onNavigate,
932
866
  onLoginSuccess,
933
867
  onError,
934
- onSubdomainLoginSuccess,
935
868
  initialScreen = "login",
936
869
  redirectUrl = "/",
937
870
  autoReadFromCookies = true
@@ -1022,7 +955,7 @@ var CrudifyLogin = ({
1022
955
  case "resetPassword":
1023
956
  return /* @__PURE__ */ jsx5(ResetPasswordForm_default, { ...commonProps, searchParams });
1024
957
  default:
1025
- return /* @__PURE__ */ jsx5(LoginForm_default, { ...commonProps, onLoginSuccess, onSubdomainLoginSuccess });
958
+ return /* @__PURE__ */ jsx5(LoginForm_default, { ...commonProps, onLoginSuccess });
1026
959
  }
1027
960
  };
1028
961
  return /* @__PURE__ */ jsx5(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocios/crudify-ui",
3
- "version": "1.0.40",
3
+ "version": "1.0.43",
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": "^1.0.83",
28
+ "@nocios/crudify-browser": "^1.0.84",
29
29
  "crypto-js": "^4.2.0",
30
30
  "i18next-browser-languagedetector": "^8.1.0",
31
31
  "i18next-http-backend": "^3.0.2",
package/tsup.config.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { defineConfig } from 'tsup'
1
+ import { defineConfig } from "tsup";
2
2
 
3
3
  export default defineConfig({
4
- entry: ['src/index.ts'],
5
- format: ['cjs', 'esm'],
4
+ entry: ["src/index.ts"],
5
+ format: ["cjs", "esm"],
6
6
  dts: true,
7
7
  clean: true,
8
- external: ['react', 'react-dom', '@mui/material', '@mui/icons-material']
9
- })
8
+ external: ["react", "react-dom", "@mui/material", "@mui/icons-material"],
9
+ });
@@ -1,281 +0,0 @@
1
- # Análisis: Implementaciones Posibles para Manejo de Usuario Logueado
2
-
3
- ## Contexto Actual
4
-
5
- Actualmente en `crudia-ui`:
6
- - **DataProvider**: Maneja token, usuario (del JWT), inicialización de crudify, interceptores de expiración
7
- - **Token**: Se guarda en secureSessionStorage y se extrae info básica del JWT (email, exp, etc.)
8
- - **Datos completos del usuario**: Se obtienen con `findUserByEmail()` usando `readItems("users", {filter: {email}})`
9
- - **Redirección automática**: Al expirar token, redirige a `/login`
10
-
11
- ## Opciones de Implementación
12
-
13
- ### ✅ **OPCIÓN 1: Provider Completo en la Librería (Recomendada)**
14
-
15
- **Descripción:**
16
- Crear un `CrudifyAuthProvider` en npm-crudify-ui que maneje completamente la autenticación y datos del usuario.
17
-
18
- ```tsx
19
- // En npm-crudify-ui
20
- export const CrudifyAuthProvider = ({
21
- children,
22
- onTokenExpired,
23
- onError,
24
- config
25
- }) => {
26
- // Maneja: token, usuario completo, crudify init, interceptores
27
- }
28
-
29
- // En crudia-ui
30
- <CrudifyAuthProvider
31
- onTokenExpired={() => navigate("/login")}
32
- config={appConfig}
33
- >
34
- <App />
35
- </CrudifyAuthProvider>
36
- ```
37
-
38
- **✅ PROS:**
39
- - **Reutilización máxima**: Todas las apps usan la misma lógica de auth
40
- - **Mantenimiento centralizado**: Un solo lugar para bugs de auth
41
- - **Consistencia**: Mismo comportamiento en todas las apps
42
- - **Simplicidad**: Apps solo necesitan proveer callbacks
43
- - **Testing**: Más fácil testear lógica de auth de forma aislada
44
- - **Menos código**: Apps no duplican lógica de autenticación
45
-
46
- **❌ CONTRAS:**
47
- - **Migración inicial**: Hay que actualizar DataProvider existente
48
- - **Flexibilidad**: Menos control granular en cada app
49
- - **Dependencias**: Apps dependen más de la librería
50
-
51
- **📋 IMPLEMENTACIÓN:**
52
- ```
53
- npm-crudify-ui/
54
- ├── src/
55
- │ ├── components/
56
- │ │ ├── CrudifyLogin/
57
- │ │ └── CrudifyAuthProvider/ # NUEVO
58
- │ │ ├── index.tsx
59
- │ │ ├── types.ts
60
- │ │ ├── hooks/
61
- │ │ │ ├── useAuth.ts
62
- │ │ │ ├── useUserProfile.ts
63
- │ │ │ └── useCrudifyInit.ts
64
- │ │ └── utils/
65
- │ │ ├── jwtUtils.ts
66
- │ │ └── tokenInterceptors.ts
67
- ```
68
-
69
- ---
70
-
71
- ### 🔄 **OPCIÓN 2: Hook Compartido**
72
-
73
- **Descripción:**
74
- Crear hooks reutilizables pero mantener el Provider en cada app.
75
-
76
- ```tsx
77
- // En npm-crudify-ui
78
- export const useAuthToken = (config) => { /* lógica token */ }
79
- export const useUserProfile = (userEmail) => { /* lógica usuario */ }
80
- export const useCrudifyInit = (config, token) => { /* lógica init */ }
81
-
82
- // En crudia-ui (DataProvider se mantiene)
83
- const DataProvider = ({ children }) => {
84
- const { token, setToken } = useAuthToken(config)
85
- const { user } = useUserProfile(userEmail)
86
- const { isInitialized } = useCrudifyInit(config, token)
87
- // ...
88
- }
89
- ```
90
-
91
- **✅ PROS:**
92
- - **Flexibilidad**: Cada app controla su Provider
93
- - **Migración gradual**: Se puede migrar por partes
94
- - **Personalización**: Apps pueden customizar comportamiento
95
- - **Compatibilidad**: Fácil mantener el DataProvider actual
96
-
97
- **❌ CONTRAS:**
98
- - **Duplicación de código**: Cada app necesita su Provider
99
- - **Inconsistencias**: Apps pueden implementar diferente
100
- - **Mantenimiento**: Hay que actualizar múltiples lugares
101
- - **Complejidad**: Apps necesitan conocer la implementación
102
-
103
- ---
104
-
105
- ### 🚫 **OPCIÓN 3: Solo Utilidades (No recomendada)**
106
-
107
- **Descripción:**
108
- Mover solo funciones utilitarias a la librería.
109
-
110
- ```tsx
111
- // En npm-crudify-ui
112
- export const parseJWT = (token) => { /* ... */ }
113
- export const setupTokenInterceptor = (onExpired) => { /* ... */ }
114
- export const findUserByEmail = (email) => { /* ... */ }
115
- ```
116
-
117
- **✅ PROS:**
118
- - **Migración mínima**: Casi no cambia el código existente
119
- - **Control total**: Apps mantienen control completo
120
-
121
- **❌ CONTRAS:**
122
- - **Poca reutilización**: No se simplifica realmente
123
- - **Duplicación**: Lógica principal sigue duplicada
124
- - **Mantenimiento**: Sigue siendo complejo mantener
125
- - **Valor limitado**: No justifica el esfuerzo
126
-
127
- ---
128
-
129
- ### ⚖️ **OPCIÓN 4: Híbrida (Provider + Hooks)**
130
-
131
- **Descripción:**
132
- Provider principal + hooks especializados para casos específicos.
133
-
134
- ```tsx
135
- // Provider principal
136
- <CrudifyAuthProvider>
137
- <App />
138
- </CrudifyAuthProvider>
139
-
140
- // Hooks adicionales para casos específicos
141
- const { refreshUserProfile } = useUserProfile()
142
- const { extendToken } = useTokenManager()
143
- ```
144
-
145
- **✅ PROS:**
146
- - **Lo mejor de ambos**: Provider simple + hooks flexibles
147
- - **Escalabilidad**: Fácil agregar funcionalidades
148
- - **Gradual**: Se puede implementar por etapas
149
-
150
- **❌ CONTRAS:**
151
- - **Complejidad inicial**: Más código para implementar
152
- - **Decisiones de diseño**: Qué va en Provider vs hooks
153
-
154
- ---
155
-
156
- ## 🎯 **RECOMENDACIÓN: OPCIÓN 1**
157
-
158
- ### **Por qué la Opción 1 es la mejor:**
159
-
160
- 1. **Alineada con el objetivo**: Librería reutilizable y fácil mantenimiento
161
- 2. **Soluciona el problema real**: Evita duplicar DataProvider en cada app
162
- 3. **Escalable**: Nuevas apps solo importan el provider
163
- 4. **Mantenible**: Un solo lugar para arreglar bugs de auth
164
- 5. **React best practices**: Providers son el patrón estándar para estado global
165
-
166
- ### **Plan de Migración:**
167
-
168
- #### **Fase 1: Crear CrudifyAuthProvider en la librería**
169
- ```tsx
170
- // npm-crudify-ui/src/components/CrudifyAuthProvider/
171
- export interface CrudifyAuthConfig {
172
- publicApiKey?: string
173
- env?: 'dev' | 'stg' | 'prod'
174
- onTokenExpired?: () => void
175
- onAuthError?: (error: string) => void
176
- autoLoginWithSubdomain?: boolean
177
- }
178
-
179
- export const CrudifyAuthProvider: React.FC<{
180
- children: React.ReactNode
181
- config: CrudifyAuthConfig
182
- }>
183
- ```
184
-
185
- #### **Fase 2: Migrar crudia-ui**
186
- ```tsx
187
- // Reemplazar DataProvider con:
188
- <CrudifyAuthProvider
189
- config={{
190
- onTokenExpired: () => navigate("/login"),
191
- onAuthError: (error) => showNotification(error, "error")
192
- }}
193
- >
194
- {children}
195
- </CrudifyAuthProvider>
196
- ```
197
-
198
- #### **Fase 3: Otras apps usan el mismo provider**
199
- ```tsx
200
- // En nuevas apps:
201
- <CrudifyAuthProvider config={appSpecificConfig}>
202
- <MyApp />
203
- </CrudifyAuthProvider>
204
- ```
205
-
206
- ### **Beneficios a Largo Plazo:**
207
-
208
- - 🚀 **Nuevas apps**: Se implementan en minutos, no horas
209
- - 🔧 **Bugs de auth**: Se arreglan una vez, se aplican a todas las apps
210
- - 📚 **Consistencia**: Misma UX de autenticación en todo el ecosistema
211
- - 🧪 **Testing**: Lógica de auth se puede testear de forma aislada
212
- - 📖 **Documentación**: Un solo provider para documentar
213
-
214
- ---
215
-
216
- ## 🚀 **Implementación Sugerida**
217
-
218
- ### **Estructura del CrudifyAuthProvider:**
219
-
220
- ```tsx
221
- interface CrudifyAuthContextValue {
222
- // Estado básico
223
- token: string | null
224
- user: any | null
225
- userProfile: any | null
226
- isAuthenticated: boolean
227
- isInitialized: boolean
228
-
229
- // Métodos
230
- login: (username: string, password: string) => Promise<LoginResponse>
231
- loginWithSubdomain: (username: string, password: string, subdomain: string) => Promise<LoginResponse>
232
- logout: () => void
233
- refreshUserProfile: () => Promise<void>
234
-
235
- // Estados de carga
236
- loginLoading: boolean
237
- profileLoading: boolean
238
- initLoading: boolean
239
-
240
- // Errores
241
- authError: string | null
242
- profileError: string | null
243
- }
244
- ```
245
-
246
- ### **Uso en las apps:**
247
-
248
- ```tsx
249
- // crudia-ui/src/App.tsx
250
- <CrudifyAuthProvider
251
- config={{
252
- publicApiKey: appConfig.publicApiKey,
253
- env: appConfig.env,
254
- onTokenExpired: () => navigate("/login"),
255
- onAuthError: (error) => showNotification(error, "error"),
256
- autoReadFromCookies: true
257
- }}
258
- >
259
- <Router>
260
- <Routes>
261
- <Route path="/login" element={<CrudifyLogin />} />
262
- <Route path="/*" element={<ProtectedRoutes />} />
263
- </Routes>
264
- </Router>
265
- </CrudifyAuthProvider>
266
- ```
267
-
268
- ### **Hook de uso:**
269
-
270
- ```tsx
271
- // En cualquier componente
272
- const { user, userProfile, logout, refreshUserProfile } = useAuth()
273
-
274
- // Usuario básico (del JWT)
275
- console.log(user.email, user.exp)
276
-
277
- // Usuario completo (de la DB)
278
- console.log(userProfile.firstName, userProfile.preferences)
279
- ```
280
-
281
- ¿Te parece bien esta propuesta? ¿Quieres que proceda con la implementación de la Opción 1?