@nocios/crudify-ui 1.3.0 → 1.3.2
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/README.md +155 -1108
- package/README_DEPTH.md +1046 -0
- package/dist/index.d.mts +181 -1
- package/dist/index.d.ts +181 -1
- package/dist/index.js +393 -20
- package/dist/index.mjs +388 -19
- package/package.json +1 -1
- package/MIGRATION-GUIDE.md +0 -312
- package/MIGRATION.md +0 -201
- package/MIGRATION_EXAMPLE.md +0 -538
- package/TECHNICAL_SPECIFICATION.md +0 -344
- package/example-app.tsx +0 -197
- package/mejoras_npm_lib.md +0 -790
- package/tsup.config.ts +0 -9
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
# ESPECIFICACIÓN TÉCNICA: CrudifyDataProvider
|
|
2
|
-
|
|
3
|
-
## 🎯 OBJETIVO
|
|
4
|
-
|
|
5
|
-
Crear un provider unificado que encapsule toda la funcionalidad de autenticación, gestión de tokens y operaciones CRUD, eliminando la duplicación de código entre crudia-ui y crudify-ui, mientras mantiene **100% de compatibilidad** con el sistema de producción.
|
|
6
|
-
|
|
7
|
-
## 🔍 ANÁLISIS DEL SISTEMA ACTUAL
|
|
8
|
-
|
|
9
|
-
### CRUDIA-UI (Sistema de Producción que FUNCIONA)
|
|
10
|
-
|
|
11
|
-
**Arquitectura de Providers:**
|
|
12
|
-
```
|
|
13
|
-
GlobalNotificationProvider
|
|
14
|
-
├── AppProvider (configuración desde ENV/cookies)
|
|
15
|
-
├── DataProvider (inicialización de crudify + JWT)
|
|
16
|
-
├── UIProvider
|
|
17
|
-
├── DashboardProvider
|
|
18
|
-
└── Components
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Flujo de Inicialización Crítico:**
|
|
22
|
-
1. `AppProvider` lee configuración de ENV vars + cookies
|
|
23
|
-
2. `DataProvider` inicializa crudify globalmente con `publicApiKey` y `env`
|
|
24
|
-
3. `DataProvider` maneja JWT tokens con `secureSessionStorage`
|
|
25
|
-
4. `DataProvider` configura interceptores para manejo de errores
|
|
26
|
-
5. Componentes usan `crudify` directamente o via `useCrudifyWithNotifications`
|
|
27
|
-
|
|
28
|
-
**Puntos de Integración Críticos:**
|
|
29
|
-
- `secureSessionStorage` con key `"authToken"`
|
|
30
|
-
- `crudify.config(env)` + `crudify.init(publicApiKey, "none")`
|
|
31
|
-
- `crudify.setToken(token)` sincronizado con storage
|
|
32
|
-
- Interceptores para manejo de tokens expirados
|
|
33
|
-
- Sistema de notificaciones integrado
|
|
34
|
-
|
|
35
|
-
### CRUDIFY-UI (Sistema que Falla)
|
|
36
|
-
|
|
37
|
-
**Problemas Identificados:**
|
|
38
|
-
1. **Doble Inicialización**: `DataProvider` + `CrudifyProvider`
|
|
39
|
-
2. **Storage Incompatible**: No usa `secureSessionStorage`
|
|
40
|
-
3. **Falta Provider Global**: Solo `JWTSessionProvider` local
|
|
41
|
-
4. **Error**: "Crudify: Not initialized" por conflictos
|
|
42
|
-
|
|
43
|
-
## 🏗️ DISEÑO DEL NUEVO SISTEMA
|
|
44
|
-
|
|
45
|
-
### PRINCIPIOS DE DISEÑO
|
|
46
|
-
|
|
47
|
-
1. **Compatibilidad Total**: No romper crudia-ui (producción)
|
|
48
|
-
2. **Encapsulación**: Todo en npm-crudify-ui, sin duplicación
|
|
49
|
-
3. **Configuración Flexible**: ENV vars, cookies, o parámetros
|
|
50
|
-
4. **Error Handling Robusto**: Fallas graduales, no cascada
|
|
51
|
-
5. **API Simple**: Hooks fáciles de usar
|
|
52
|
-
|
|
53
|
-
### ARQUITECTURA PROPUESTA
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
CrudifyDataProvider (NUEVO)
|
|
57
|
-
├── ConfigurationManager (lee ENV + cookies)
|
|
58
|
-
├── CrudifyInitializer (inicializa crudify UNA SOLA VEZ)
|
|
59
|
-
├── TokenManager (JWT + secureSessionStorage)
|
|
60
|
-
├── ErrorInterceptor (manejo de errores automático)
|
|
61
|
-
├── NotificationSystem (opcional)
|
|
62
|
-
└── Hooks Exportados:
|
|
63
|
-
├── useCrudifyAuth (estado de autenticación)
|
|
64
|
-
├── useCrudifyUser (datos del usuario + perfil)
|
|
65
|
-
├── useCrudifyData (operaciones CRUD)
|
|
66
|
-
└── useCrudifyConfig (configuración actual)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## 📋 ESPECIFICACIÓN DETALLADA
|
|
70
|
-
|
|
71
|
-
### 1. CONFIGURACIÓN
|
|
72
|
-
|
|
73
|
-
**Prioridad de Configuración:**
|
|
74
|
-
```typescript
|
|
75
|
-
interface CrudifyConfig {
|
|
76
|
-
env?: "dev" | "stg" | "prod"
|
|
77
|
-
publicApiKey?: string
|
|
78
|
-
loginActions?: string[]
|
|
79
|
-
appName?: string
|
|
80
|
-
logo?: string
|
|
81
|
-
colors?: Record<string, string>
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Orden de prioridad:
|
|
85
|
-
// 1. Props explícitas al Provider
|
|
86
|
-
// 2. Variables de entorno (VITE_TEST_*)
|
|
87
|
-
// 3. Cookies (para multi-tenant)
|
|
88
|
-
// 4. Error si falta publicApiKey
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Variables de Entorno Soportadas:**
|
|
92
|
-
- `VITE_TEST_ENV`
|
|
93
|
-
- `VITE_TEST_PUBLIC_API_KEY`
|
|
94
|
-
- `VITE_TEST_LOGIN_ACTIONS`
|
|
95
|
-
|
|
96
|
-
**Cookies Multi-tenant:**
|
|
97
|
-
- `publicApiKey`
|
|
98
|
-
- `environment`
|
|
99
|
-
- `appName`
|
|
100
|
-
- `loginActions`
|
|
101
|
-
- `logo`
|
|
102
|
-
- `colors`
|
|
103
|
-
|
|
104
|
-
### 2. GESTIÓN DE TOKENS
|
|
105
|
-
|
|
106
|
-
**Storage Strategy:**
|
|
107
|
-
```typescript
|
|
108
|
-
// COMPATIBILIDAD TOTAL con crudia-ui
|
|
109
|
-
class SecureSessionStorage {
|
|
110
|
-
private readonly TOKEN_KEY = "authToken"
|
|
111
|
-
|
|
112
|
-
setToken(token: string): void
|
|
113
|
-
getToken(): string | null
|
|
114
|
-
removeItem(key: string): void
|
|
115
|
-
migrateFromLocalStorage(key: string): void
|
|
116
|
-
clear(): void
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
**JWT Management:**
|
|
121
|
-
```typescript
|
|
122
|
-
interface TokenManager {
|
|
123
|
-
// Sincronización automática: storage <-> crudify
|
|
124
|
-
setToken(token: string | null): void
|
|
125
|
-
getToken(): string | null
|
|
126
|
-
parseToken(): JWTPayload | null
|
|
127
|
-
isTokenValid(): boolean
|
|
128
|
-
getTokenExpiration(): Date | null
|
|
129
|
-
|
|
130
|
-
// Auto-cleanup en caso de expiración
|
|
131
|
-
setupExpirationCheck(): void
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### 3. INICIALIZACIÓN DE CRUDIFY
|
|
136
|
-
|
|
137
|
-
**Inicialización Única y Robusta:**
|
|
138
|
-
```typescript
|
|
139
|
-
class CrudifyInitializer {
|
|
140
|
-
private static isInitialized = false
|
|
141
|
-
private static initializationPromise: Promise<void> | null = null
|
|
142
|
-
|
|
143
|
-
static async initialize(config: CrudifyConfig): Promise<void> {
|
|
144
|
-
// Prevenir doble inicialización
|
|
145
|
-
if (this.isInitialized) return
|
|
146
|
-
if (this.initializationPromise) return this.initializationPromise
|
|
147
|
-
|
|
148
|
-
this.initializationPromise = this.performInitialization(config)
|
|
149
|
-
await this.initializationPromise
|
|
150
|
-
this.isInitialized = true
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
private static async performInitialization(config: CrudifyConfig): Promise<void> {
|
|
154
|
-
await crudify.config(config.env || 'prod')
|
|
155
|
-
await crudify.init(config.publicApiKey!, 'none')
|
|
156
|
-
|
|
157
|
-
// Verificar que los métodos estén disponibles
|
|
158
|
-
if (typeof crudify.readItems !== 'function') {
|
|
159
|
-
throw new Error('Crudify not properly initialized')
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### 4. HOOKS PÚBLICOS
|
|
166
|
-
|
|
167
|
-
**useCrudifyAuth - Estado de Autenticación:**
|
|
168
|
-
```typescript
|
|
169
|
-
interface UseCrudifyAuthReturn {
|
|
170
|
-
// Estado básico
|
|
171
|
-
isAuthenticated: boolean
|
|
172
|
-
loading: boolean
|
|
173
|
-
error: string | null
|
|
174
|
-
|
|
175
|
-
// Datos del token
|
|
176
|
-
token: string | null
|
|
177
|
-
user: JWTPayload | null // Datos del JWT
|
|
178
|
-
tokenExpiration: Date | null
|
|
179
|
-
|
|
180
|
-
// Acciones
|
|
181
|
-
setToken: (token: string | null) => void
|
|
182
|
-
logout: () => void
|
|
183
|
-
refreshToken?: () => Promise<void> // Futuro
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**useCrudifyUser - Datos del Usuario:**
|
|
188
|
-
```typescript
|
|
189
|
-
interface UseCrudifyUserReturn {
|
|
190
|
-
// Datos básicos del JWT
|
|
191
|
-
userEmail: string | null
|
|
192
|
-
userId: string | null
|
|
193
|
-
userIdentifier: string | null
|
|
194
|
-
|
|
195
|
-
// Perfil completo desde BD
|
|
196
|
-
userProfile: UserProfile | null
|
|
197
|
-
profileLoading: boolean
|
|
198
|
-
profileError: string | null
|
|
199
|
-
|
|
200
|
-
// Datos extendidos formateados
|
|
201
|
-
extendedData: {
|
|
202
|
-
fullProfile: UserProfile | null
|
|
203
|
-
totalFields: number
|
|
204
|
-
displayData: Record<string, any>
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Acciones
|
|
208
|
-
refreshProfile: () => Promise<void>
|
|
209
|
-
clearProfile: () => void
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**useCrudifyData - Operaciones CRUD:**
|
|
214
|
-
```typescript
|
|
215
|
-
interface UseCrudifyDataReturn {
|
|
216
|
-
// Operaciones básicas
|
|
217
|
-
readItems: (moduleKey: string, filter?: object, options?: any) => Promise<CrudifyResponse>
|
|
218
|
-
readItem: (moduleKey: string, filter: object, options?: any) => Promise<CrudifyResponse>
|
|
219
|
-
createItem: (moduleKey: string, data: object, options?: any) => Promise<CrudifyResponse>
|
|
220
|
-
updateItem: (moduleKey: string, data: object, options?: any) => Promise<CrudifyResponse>
|
|
221
|
-
deleteItem: (moduleKey: string, id: string, options?: any) => Promise<CrudifyResponse>
|
|
222
|
-
|
|
223
|
-
// Operaciones avanzadas
|
|
224
|
-
transaction: (operations: any[], options?: any) => Promise<CrudifyResponse>
|
|
225
|
-
login: (email: string, password: string) => Promise<CrudifyResponse>
|
|
226
|
-
|
|
227
|
-
// Estado
|
|
228
|
-
isInitialized: boolean
|
|
229
|
-
initializationError: string | null
|
|
230
|
-
}
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**useCrudifyConfig - Configuración:**
|
|
234
|
-
```typescript
|
|
235
|
-
interface UseCrudifyConfigReturn {
|
|
236
|
-
config: CrudifyConfig
|
|
237
|
-
isConfigured: boolean
|
|
238
|
-
configError: string | null
|
|
239
|
-
|
|
240
|
-
// Para debugging
|
|
241
|
-
configSource: 'props' | 'env' | 'cookies'
|
|
242
|
-
rawConfig: Record<string, any>
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## 🔄 ESTRATEGIA DE MIGRACIÓN
|
|
247
|
-
|
|
248
|
-
### FASE 1: Implementación (No Rompe Nada)
|
|
249
|
-
|
|
250
|
-
1. **Crear CrudifyDataProvider** manteniendo APIs existentes
|
|
251
|
-
2. **Mantener CrudifyProvider** para compatibilidad
|
|
252
|
-
3. **Agregar hooks nuevos** sin afectar los existentes
|
|
253
|
-
4. **Testing exhaustivo** en ambos sistemas
|
|
254
|
-
|
|
255
|
-
### FASE 2: Migración Gradual
|
|
256
|
-
|
|
257
|
-
1. **Actualizar crudify-ui** para usar CrudifyDataProvider
|
|
258
|
-
2. **Mantener crudia-ui** sin cambios (producción)
|
|
259
|
-
3. **Documentar migración** opcional para crudia-ui
|
|
260
|
-
|
|
261
|
-
### FASE 3: Consolidación (Futuro)
|
|
262
|
-
|
|
263
|
-
1. **Deprecar APIs antiguas** con warnings
|
|
264
|
-
2. **Migrar crudia-ui** opcionalmente
|
|
265
|
-
3. **Limpiar código** redundante
|
|
266
|
-
|
|
267
|
-
## 🛡️ GARANTÍAS DE COMPATIBILIDAD
|
|
268
|
-
|
|
269
|
-
### CRUDIA-UI (Producción)
|
|
270
|
-
- ✅ **API actual intacta**: Todos los imports/exports existentes
|
|
271
|
-
- ✅ **DataProvider compatible**: Mismo comportamiento exacto
|
|
272
|
-
- ✅ **Storage compatible**: Misma key `"authToken"`
|
|
273
|
-
- ✅ **Interceptores**: Mismo manejo de errores
|
|
274
|
-
- ✅ **Notificaciones**: Sistema existente sin cambios
|
|
275
|
-
|
|
276
|
-
### CRUDIFY-UI (Desarrollo)
|
|
277
|
-
- ✅ **Migración simple**: Un solo Provider reemplaza todo
|
|
278
|
-
- ✅ **Hooks simples**: APIs más fáciles de usar
|
|
279
|
-
- ✅ **Configuración flexible**: ENV + cookies + props
|
|
280
|
-
- ✅ **Error handling**: Más robusto que el actual
|
|
281
|
-
|
|
282
|
-
## 🧪 PLAN DE TESTING
|
|
283
|
-
|
|
284
|
-
### Tests de Compatibilidad
|
|
285
|
-
1. **crudia-ui**: Login, operaciones CRUD, manejo de errores
|
|
286
|
-
2. **npm-crudify-ui**: APIs existentes sin cambios
|
|
287
|
-
3. **crudify-ui**: Nueva implementación funcional
|
|
288
|
-
|
|
289
|
-
### Tests de Integración
|
|
290
|
-
1. **Doble inicialización**: Sin conflictos
|
|
291
|
-
2. **Storage**: Compatibilidad entre sistemas
|
|
292
|
-
3. **Tokens**: Manejo correcto de JWT
|
|
293
|
-
4. **Errores**: Graceful degradation
|
|
294
|
-
|
|
295
|
-
### Tests de Regresión
|
|
296
|
-
1. **Multi-tenant**: Cookies funcionando
|
|
297
|
-
2. **ENV vars**: Configuración correcta
|
|
298
|
-
3. **Login flow**: End-to-end completo
|
|
299
|
-
4. **User profile**: Datos cargados correctamente
|
|
300
|
-
|
|
301
|
-
## 📚 DOCUMENTACIÓN
|
|
302
|
-
|
|
303
|
-
### Para Desarrolladores
|
|
304
|
-
1. **Guía de migración** desde sistema actual
|
|
305
|
-
2. **API reference** completa
|
|
306
|
-
3. **Ejemplos de uso** para cada hook
|
|
307
|
-
4. **Troubleshooting** común
|
|
308
|
-
|
|
309
|
-
### Para Producción
|
|
310
|
-
1. **No-breaking changes** garantizados
|
|
311
|
-
2. **Rollback plan** si es necesario
|
|
312
|
-
3. **Monitoring** de errores
|
|
313
|
-
4. **Performance** sin degradación
|
|
314
|
-
|
|
315
|
-
## 🚀 CRONOGRAMA
|
|
316
|
-
|
|
317
|
-
### Semana 1: Implementación Core
|
|
318
|
-
- [ ] ConfigurationManager
|
|
319
|
-
- [ ] CrudifyInitializer
|
|
320
|
-
- [ ] TokenManager
|
|
321
|
-
- [ ] Tests unitarios
|
|
322
|
-
|
|
323
|
-
### Semana 2: Hooks y Provider
|
|
324
|
-
- [ ] CrudifyDataProvider
|
|
325
|
-
- [ ] useCrudifyAuth
|
|
326
|
-
- [ ] useCrudifyUser
|
|
327
|
-
- [ ] useCrudifyData
|
|
328
|
-
|
|
329
|
-
### Semana 3: Integración y Testing
|
|
330
|
-
- [ ] Migración crudify-ui
|
|
331
|
-
- [ ] Tests de compatibilidad crudia-ui
|
|
332
|
-
- [ ] Tests end-to-end
|
|
333
|
-
- [ ] Documentación
|
|
334
|
-
|
|
335
|
-
### Semana 4: Validación y Deploy
|
|
336
|
-
- [ ] Testing exhaustivo
|
|
337
|
-
- [ ] Code review
|
|
338
|
-
- [ ] Deploy y monitoring
|
|
339
|
-
- [ ] Documentación final
|
|
340
|
-
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
**RIESGO: MÍNIMO** - El diseño mantiene 100% compatibilidad hacia atrás
|
|
344
|
-
**BENEFICIO: MÁXIMO** - Elimina duplicación y simplifica enormemente el desarrollo futuro
|
package/example-app.tsx
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
// =============================
|
|
2
|
-
// EXAMPLE APP - REFRESH TOKEN PATTERN
|
|
3
|
-
// =============================
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Ejemplo completo de aplicación usando el Refresh Token Pattern
|
|
7
|
-
* Demuestra todas las características nuevas de crudify-ui v1.2+
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import React from 'react';
|
|
11
|
-
import ReactDOM from 'react-dom/client';
|
|
12
|
-
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
|
13
|
-
import { CssBaseline, Container, AppBar, Toolbar, Typography, Box } from '@mui/material';
|
|
14
|
-
import {
|
|
15
|
-
SessionProvider,
|
|
16
|
-
LoginComponent,
|
|
17
|
-
SessionStatus,
|
|
18
|
-
SessionDebugInfo,
|
|
19
|
-
useSessionContext,
|
|
20
|
-
ProtectedRoute
|
|
21
|
-
} from '@nocios/crudify-ui';
|
|
22
|
-
|
|
23
|
-
const theme = createTheme();
|
|
24
|
-
|
|
25
|
-
// Componente de aplicación principal
|
|
26
|
-
function App() {
|
|
27
|
-
return (
|
|
28
|
-
<ThemeProvider theme={theme}>
|
|
29
|
-
<CssBaseline />
|
|
30
|
-
|
|
31
|
-
{/* Envolver toda la app con SessionProvider */}
|
|
32
|
-
<SessionProvider
|
|
33
|
-
options={{
|
|
34
|
-
autoRestore: true, // Restaurar sesión automáticamente
|
|
35
|
-
enableLogging: true, // Logs para debug
|
|
36
|
-
onSessionExpired: () => { // Callback cuando expira la sesión
|
|
37
|
-
console.log('Session expired - redirecting to login');
|
|
38
|
-
// Aquí podrías hacer redirect, mostrar modal, etc.
|
|
39
|
-
},
|
|
40
|
-
onSessionRestored: (tokens) => {
|
|
41
|
-
console.log('Session restored successfully:', tokens);
|
|
42
|
-
}
|
|
43
|
-
}}
|
|
44
|
-
>
|
|
45
|
-
<AppContent />
|
|
46
|
-
</SessionProvider>
|
|
47
|
-
</ThemeProvider>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Contenido principal de la aplicación
|
|
52
|
-
function AppContent() {
|
|
53
|
-
return (
|
|
54
|
-
<>
|
|
55
|
-
{/* App Bar */}
|
|
56
|
-
<AppBar position="static">
|
|
57
|
-
<Toolbar>
|
|
58
|
-
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
|
|
59
|
-
Crudify Refresh Token Demo
|
|
60
|
-
</Typography>
|
|
61
|
-
<SessionStatus />
|
|
62
|
-
</Toolbar>
|
|
63
|
-
</AppBar>
|
|
64
|
-
|
|
65
|
-
{/* Contenido principal */}
|
|
66
|
-
<Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
|
|
67
|
-
<LoginComponent />
|
|
68
|
-
|
|
69
|
-
{/* Área protegida - solo visible si está autenticado */}
|
|
70
|
-
<ProtectedRoute fallback={null}>
|
|
71
|
-
<ProtectedArea />
|
|
72
|
-
</ProtectedRoute>
|
|
73
|
-
|
|
74
|
-
{/* Debug info (solo en desarrollo) */}
|
|
75
|
-
{process.env.NODE_ENV === 'development' && (
|
|
76
|
-
<SessionDebugInfo />
|
|
77
|
-
)}
|
|
78
|
-
</Container>
|
|
79
|
-
</>
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Área protegida de la aplicación
|
|
84
|
-
function ProtectedArea() {
|
|
85
|
-
const { refreshTokens, isExpiringSoon } = useSessionContext();
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<Box sx={{ mt: 4, p: 3, bgcolor: 'background.paper', borderRadius: 1 }}>
|
|
89
|
-
<Typography variant="h5" gutterBottom>
|
|
90
|
-
Protected Area 🔒
|
|
91
|
-
</Typography>
|
|
92
|
-
|
|
93
|
-
<Typography variant="body1" paragraph>
|
|
94
|
-
This content is only visible to authenticated users. The session is managed
|
|
95
|
-
automatically with the Refresh Token Pattern.
|
|
96
|
-
</Typography>
|
|
97
|
-
|
|
98
|
-
{isExpiringSoon && (
|
|
99
|
-
<Box sx={{ mb: 2, p: 2, bgcolor: 'warning.light', borderRadius: 1 }}>
|
|
100
|
-
<Typography variant="body2">
|
|
101
|
-
⚠️ Your token is expiring soon, but don't worry - it will be refreshed automatically!
|
|
102
|
-
</Typography>
|
|
103
|
-
</Box>
|
|
104
|
-
)}
|
|
105
|
-
|
|
106
|
-
{/* Ejemplo de uso de CRUD operations */}
|
|
107
|
-
<CrudOperationsExample />
|
|
108
|
-
</Box>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Ejemplo de operaciones CRUD con auto-refresh
|
|
113
|
-
function CrudOperationsExample() {
|
|
114
|
-
const [data, setData] = React.useState(null);
|
|
115
|
-
const [loading, setLoading] = React.useState(false);
|
|
116
|
-
const [error, setError] = React.useState(null);
|
|
117
|
-
|
|
118
|
-
// Importar crudify
|
|
119
|
-
const crudify = React.useMemo(() => {
|
|
120
|
-
// En una app real, ya estaría inicializado
|
|
121
|
-
import('@nocios/crudify-browser').then(module => module.default);
|
|
122
|
-
}, []);
|
|
123
|
-
|
|
124
|
-
const fetchData = async () => {
|
|
125
|
-
setLoading(true);
|
|
126
|
-
setError(null);
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
// Esta operación usará automáticamente el auto-refresh si es necesario
|
|
130
|
-
const result = await crudify.getPermissions();
|
|
131
|
-
|
|
132
|
-
if (result.success) {
|
|
133
|
-
setData(result.data);
|
|
134
|
-
} else {
|
|
135
|
-
setError('Failed to fetch data: ' + JSON.stringify(result.errors));
|
|
136
|
-
}
|
|
137
|
-
} catch (err) {
|
|
138
|
-
setError('Network error: ' + err.message);
|
|
139
|
-
} finally {
|
|
140
|
-
setLoading(false);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<Box sx={{ mt: 3 }}>
|
|
146
|
-
<Typography variant="h6" gutterBottom>
|
|
147
|
-
CRUD Operations with Auto-Refresh
|
|
148
|
-
</Typography>
|
|
149
|
-
|
|
150
|
-
<button onClick={fetchData} disabled={loading}>
|
|
151
|
-
{loading ? 'Loading...' : 'Fetch Permissions (Test Auto-Refresh)'}
|
|
152
|
-
</button>
|
|
153
|
-
|
|
154
|
-
{error && (
|
|
155
|
-
<Box sx={{ mt: 2, p: 2, bgcolor: 'error.light', borderRadius: 1 }}>
|
|
156
|
-
<Typography variant="body2" color="error">
|
|
157
|
-
{error}
|
|
158
|
-
</Typography>
|
|
159
|
-
</Box>
|
|
160
|
-
)}
|
|
161
|
-
|
|
162
|
-
{data && (
|
|
163
|
-
<Box sx={{ mt: 2, p: 2, bgcolor: 'success.light', borderRadius: 1 }}>
|
|
164
|
-
<Typography variant="body2">
|
|
165
|
-
✅ Data fetched successfully! Auto-refresh is working.
|
|
166
|
-
</Typography>
|
|
167
|
-
<pre style={{ fontSize: '12px', marginTop: '8px' }}>
|
|
168
|
-
{JSON.stringify(data, null, 2)}
|
|
169
|
-
</pre>
|
|
170
|
-
</Box>
|
|
171
|
-
)}
|
|
172
|
-
</Box>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// =============================
|
|
177
|
-
// BOOTSTRAP DE LA APLICACIÓN
|
|
178
|
-
// =============================
|
|
179
|
-
|
|
180
|
-
// Para usar este ejemplo:
|
|
181
|
-
// 1. npm install @nocios/crudify-ui@^1.2.0
|
|
182
|
-
// 2. Configurar crudify con tu API key antes de renderizar
|
|
183
|
-
// 3. Renderizar la aplicación
|
|
184
|
-
|
|
185
|
-
export default App;
|
|
186
|
-
|
|
187
|
-
// Ejemplo de inicialización
|
|
188
|
-
/*
|
|
189
|
-
import { crudify } from '@nocios/crudify-ui';
|
|
190
|
-
|
|
191
|
-
// Configurar crudify antes de renderizar la app
|
|
192
|
-
await crudify.init('your-api-key', 'debug');
|
|
193
|
-
|
|
194
|
-
// Renderizar la aplicación
|
|
195
|
-
const root = ReactDOM.createRoot(document.getElementById('root')!);
|
|
196
|
-
root.render(<App />);
|
|
197
|
-
*/
|