@barcidev/ngx-autogen 0.1.3 → 0.1.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.
- package/LICENSE +20 -20
- package/README.es.md +352 -366
- package/README.md +352 -366
- package/package.json +62 -61
- package/src/collection.json +14 -14
- package/src/ng-add/index.js +43 -15
- package/src/ng-add/schema.d.ts +4 -4
- package/src/ng-add/schema.json +19 -19
- package/src/ngrx/store/files/entity/entity.model.ts.template +12 -22
- package/src/ngrx/store/files/entity/with-entity-pagination.ts.template +89 -0
- package/src/ngrx/store/files/entity/with-entity-status.ts.template +92 -0
- package/src/ngrx/store/files/{store → state/models}/__name@dasherize__.model.ts.template +13 -13
- package/src/ngrx/store/files/{store → state/services}/__name@dasherize__.service.ts.template +28 -28
- package/src/ngrx/store/files/state/store/__name@dasherize__.store.ts.template +200 -0
- package/src/ngrx/store/index.js +64 -30
- package/src/ngrx/store/schema.d.ts +7 -6
- package/src/ngrx/store/schema.json +33 -29
- package/src/ngrx/store/files/store/__name@dasherize__.store.ts.template +0 -212
package/README.es.md
CHANGED
|
@@ -1,366 +1,352 @@
|
|
|
1
|
-
# ngx-autogen
|
|
2
|
-
|
|
3
|
-
[](README.md)
|
|
4
|
-
[](README.es.md)
|
|
5
|
-
|
|
6
|
-
**ngx-autogen** es un conjunto de schematics diseñados para optimizar y estandarizar el flujo de trabajo en proyectos Angular. Esta librería proporciona herramientas de generación de código que siguen las mejores prácticas, permitiendo a los desarrolladores ahorrar tiempo en tareas repetitivas y configuración de arquitectura.
|
|
7
|
-
|
|
8
|
-
## 🚀 Características
|
|
9
|
-
|
|
10
|
-
El proyecto se lanza inicialmente con un enfoque en la gestión de estado, pero está diseñado para crecer:
|
|
11
|
-
|
|
12
|
-
- **Store Schematic**: Nuestro primer schematic disponible. Permite generar automáticamente toda la estructura necesaria para un store basado en signals (NGRX-Signals), facilitando la integración rápida y escalable de la gestión de estado en tus aplicaciones.
|
|
13
|
-
|
|
14
|
-
## 📅 Próximamente
|
|
15
|
-
|
|
16
|
-
**ngx-autogen** es un proyecto en evolución continua. Se irán agregando progresivamente nuevas herramientas y schematics para cubrir más aspectos del desarrollo en Angular, como:
|
|
17
|
-
|
|
18
|
-
- Generación de servicios y utilidades.
|
|
19
|
-
- Scaffolding para componentes avanzados.
|
|
20
|
-
|
|
21
|
-
## 📦 Instalación
|
|
22
|
-
|
|
23
|
-
Puedes instalar el paquete en tu proyecto Angular mediante angular cli para que se configure automáticamente el proyecto con las dependencias necesarias:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
ng add
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 🛠️ Uso
|
|
30
|
-
|
|
31
|
-
### Generar un Store
|
|
32
|
-
|
|
33
|
-
#### Propiedades
|
|
34
|
-
|
|
35
|
-
- `name`(obligatorio): nombre del store.
|
|
36
|
-
- `pk`(opcional): nombre de la primary key, si no se especifica se usara la especificada en el proceso de instalacion del schematic, de lo contrario se usara `id`.
|
|
37
|
-
- `path`(opcional): ruta del store, si no se especifica se usara la especificada en el proceso de instalacion del schematic, de lo contrario se usara `src/app/core`.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
├──
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
export
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
export
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
import {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
import {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
} from '
|
|
160
|
-
|
|
161
|
-
import {
|
|
162
|
-
|
|
163
|
-
import {
|
|
164
|
-
import {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
UpdateUser
|
|
168
|
-
} from './user.model';
|
|
169
|
-
import { UserService } from './user.service';
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}),
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
354
|
-
),
|
|
355
|
-
})),
|
|
356
|
-
withHooks({
|
|
357
|
-
onInit: (store) => {
|
|
358
|
-
store.loadUsers();
|
|
359
|
-
},
|
|
360
|
-
})
|
|
361
|
-
);
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## 📄 Licencia
|
|
365
|
-
|
|
366
|
-
Este proyecto está bajo la licencia [MIT](LICENSE).
|
|
1
|
+
# ngx-autogen
|
|
2
|
+
|
|
3
|
+
[](README.md)
|
|
4
|
+
[](README.es.md)
|
|
5
|
+
|
|
6
|
+
**ngx-autogen** es un conjunto de schematics diseñados para optimizar y estandarizar el flujo de trabajo en proyectos Angular. Esta librería proporciona herramientas de generación de código que siguen las mejores prácticas, permitiendo a los desarrolladores ahorrar tiempo en tareas repetitivas y configuración de arquitectura.
|
|
7
|
+
|
|
8
|
+
## 🚀 Características
|
|
9
|
+
|
|
10
|
+
El proyecto se lanza inicialmente con un enfoque en la gestión de estado, pero está diseñado para crecer:
|
|
11
|
+
|
|
12
|
+
- **Store Schematic**: Nuestro primer schematic disponible. Permite generar automáticamente toda la estructura necesaria para un store basado en signals (NGRX-Signals), facilitando la integración rápida y escalable de la gestión de estado en tus aplicaciones.
|
|
13
|
+
|
|
14
|
+
## 📅 Próximamente
|
|
15
|
+
|
|
16
|
+
**ngx-autogen** es un proyecto en evolución continua. Se irán agregando progresivamente nuevas herramientas y schematics para cubrir más aspectos del desarrollo en Angular, como:
|
|
17
|
+
|
|
18
|
+
- Generación de servicios y utilidades.
|
|
19
|
+
- Scaffolding para componentes avanzados.
|
|
20
|
+
|
|
21
|
+
## 📦 Instalación
|
|
22
|
+
|
|
23
|
+
Puedes instalar el paquete en tu proyecto Angular mediante angular cli para que se configure automáticamente el proyecto con las dependencias necesarias:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
ng add ngx-autogen
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 🛠️ Uso
|
|
30
|
+
|
|
31
|
+
### Generar un Store
|
|
32
|
+
|
|
33
|
+
#### Propiedades
|
|
34
|
+
|
|
35
|
+
- `name`(obligatorio): nombre del store.
|
|
36
|
+
- `pk`(opcional): nombre de la primary key, si no se especifica se usara la especificada en el proceso de instalacion del schematic, de lo contrario se usara `id`.
|
|
37
|
+
- `path`(opcional): ruta del store, si no se especifica se usara la especificada en el proceso de instalacion del schematic, de lo contrario se usara `src/app/core`. La carpeta `state` se agregará automáticamente a la ruta.
|
|
38
|
+
- `grouped` (opcional): si es verdadero, los archivos se agruparán en subcarpetas `models`, `services` y `store`.
|
|
39
|
+
|
|
40
|
+
#### Ejemplo
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
ng g app-store --name="user" --pk="cod"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Esto creará los archivos `user.model.ts`, `user.service.ts`, `user.store.ts` dentro de la carpeta `src/app/core/state/user`, y los archivos `entity.model.ts`, `with-entity-pagination.ts`, y `with-entity-status.ts` si no existen dentro de la carpeta `src/app/shared/state`.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
src/
|
|
50
|
+
└── app/
|
|
51
|
+
└── shared/
|
|
52
|
+
└── state/
|
|
53
|
+
├── entity.model.ts
|
|
54
|
+
├── with-entity-pagination.ts
|
|
55
|
+
└── with-entity-status.ts
|
|
56
|
+
└── state/
|
|
57
|
+
└── index.ts
|
|
58
|
+
└── user/
|
|
59
|
+
├── user.service.ts
|
|
60
|
+
├── user.model.ts
|
|
61
|
+
└── user.store.ts
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
El archivo `index.ts` exportará todo lo necesario para que el store pueda ser importado y utilizado en cualquier parte de la aplicación.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
/* USER */
|
|
68
|
+
export * from './user/user.model';
|
|
69
|
+
export * from './user/user.service';
|
|
70
|
+
export * from './user/user.store';
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
La carpeta `src/app/shared/state` contiene los archivos compartidos para el manejo del estado.
|
|
74
|
+
|
|
75
|
+
`entity.model.ts`:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { HttpErrorResponse } from '@angular/common/http';
|
|
79
|
+
import { FormControl } from '@angular/forms';
|
|
80
|
+
|
|
81
|
+
export type FormGroupType<T> = {
|
|
82
|
+
[K in keyof T]: FormControl<T[K]>;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export interface RequestConfig<T, U = unknown> {
|
|
86
|
+
onError?: (error?: HttpErrorResponse) => void;
|
|
87
|
+
onSuccess?: (response?: U) => void;
|
|
88
|
+
payload: T;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
El archivo `user.model.ts` contiene la interface del modelo de datos.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { FormGroupType } from 'src/app/shared/state/entity.model';
|
|
96
|
+
|
|
97
|
+
export interface AddUser {
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export type AddUserForm = FormGroupType<AddUser>;
|
|
101
|
+
|
|
102
|
+
export interface UserDto {
|
|
103
|
+
cod: number;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type UpdateUser = Partial<UserDto> & Pick<UserDto, 'cod'>;
|
|
107
|
+
|
|
108
|
+
export interface UserRequest{}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
El archivo `user.service.ts` contiene el servicio que se encarga de la lógica de negocio.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { Injectable } from '@angular/core';
|
|
115
|
+
import { Observable, of } from 'rxjs';
|
|
116
|
+
import {
|
|
117
|
+
AddUser,
|
|
118
|
+
UserDto,
|
|
119
|
+
UpdateUser
|
|
120
|
+
} from './user.model';
|
|
121
|
+
|
|
122
|
+
@Injectable({
|
|
123
|
+
providedIn: 'root'
|
|
124
|
+
})
|
|
125
|
+
export class UserService {
|
|
126
|
+
|
|
127
|
+
addUser$(entity: AddUser): Observable<number> {
|
|
128
|
+
return of(0);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
removeUser$(cod: number): Observable<boolean> {
|
|
132
|
+
return of(true);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
getUsers$(): Observable<UserDto[]> {
|
|
136
|
+
return of([]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
updateUser$(entity: UpdateUser): Observable<boolean> {
|
|
140
|
+
return of(true);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
El archivo `user.store.ts` contiene el store que se encarga de la gestión de estado.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { computed, inject } from '@angular/core';
|
|
149
|
+
import { patchState, signalStore, type, withComputed, withHooks, withMethods, withState } from '@ngrx/signals';
|
|
150
|
+
import {
|
|
151
|
+
addEntity,
|
|
152
|
+
entityConfig,
|
|
153
|
+
removeEntity,
|
|
154
|
+
setAllEntities,
|
|
155
|
+
updateEntity,
|
|
156
|
+
withEntities
|
|
157
|
+
} from '@ngrx/signals/entities';
|
|
158
|
+
import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
159
|
+
import { catchError, of, pipe, switchMap, tap } from 'rxjs';
|
|
160
|
+
|
|
161
|
+
import { RequestConfig } from 'src/app/shared/state/entity.model';
|
|
162
|
+
import { withPagination } from 'src/app/shared/state/with-entity-pagination';
|
|
163
|
+
import { withEntityStatus } from 'src/app/shared/state/with-entity-status';
|
|
164
|
+
import {
|
|
165
|
+
AddUser,
|
|
166
|
+
UserDto,
|
|
167
|
+
UpdateUser
|
|
168
|
+
} from './user.model';
|
|
169
|
+
import { UserService } from './user.service';
|
|
170
|
+
|
|
171
|
+
const config = entityConfig({
|
|
172
|
+
entity: type<UserDto>(),
|
|
173
|
+
selectId: (entity) => entity.cod,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
export const UserStore = signalStore(
|
|
177
|
+
withEntities(config),
|
|
178
|
+
withEntityStatus(),
|
|
179
|
+
withPagination(),
|
|
180
|
+
withComputed(({ entities, entityMap, status: { idSelected } }) => ({
|
|
181
|
+
users: computed(() => entities()),
|
|
182
|
+
userSeleccionado: computed(() => {
|
|
183
|
+
const cod = idSelected();
|
|
184
|
+
return cod ? entityMap()[cod] : null;
|
|
185
|
+
})
|
|
186
|
+
})),
|
|
187
|
+
withMethods((store, userService = inject(UserService)) => ({
|
|
188
|
+
addUser: rxMethod<RequestConfig<AddUser, UserDto>>(
|
|
189
|
+
pipe(
|
|
190
|
+
tap(() => {
|
|
191
|
+
patchState(store, (state) => ({ status: { ...state.status, addLoading: true } }));
|
|
192
|
+
}),
|
|
193
|
+
switchMap(({ onError, onSuccess, payload: { request } }) => {
|
|
194
|
+
return userService.addUser$(request).pipe(
|
|
195
|
+
tap((cod) => {
|
|
196
|
+
const newUser: UserDto = { ...request, cod};
|
|
197
|
+
patchState(store, addEntity(newUser, config), (state) => ({
|
|
198
|
+
...state,
|
|
199
|
+
status: { ...state.status, addError: null, addLoading: false }
|
|
200
|
+
}));
|
|
201
|
+
if (onSuccess) {
|
|
202
|
+
onSuccess(newUser);
|
|
203
|
+
}
|
|
204
|
+
}),
|
|
205
|
+
catchError(() => {
|
|
206
|
+
const error = new Error('');
|
|
207
|
+
patchState(store, (state) => ({
|
|
208
|
+
status: { ...state.status, addError: error, addLoading: false }
|
|
209
|
+
}));
|
|
210
|
+
if (onError) {
|
|
211
|
+
onError();
|
|
212
|
+
}
|
|
213
|
+
return EMPTY;
|
|
214
|
+
})
|
|
215
|
+
);
|
|
216
|
+
})
|
|
217
|
+
)
|
|
218
|
+
),
|
|
219
|
+
loadUsers: rxMethod<void>(
|
|
220
|
+
pipe(
|
|
221
|
+
tap(() => {
|
|
222
|
+
patchState(store, (state) => ({ status: { ...state.status, loading: true } }));
|
|
223
|
+
}),
|
|
224
|
+
switchMap(() => {
|
|
225
|
+
return userService.getUsers$().pipe(
|
|
226
|
+
tap((response) => {
|
|
227
|
+
patchState(store, setAllEntities(response, config), (state) => ({
|
|
228
|
+
status: { ...state.status, error: null, loaded: true, loading: false }
|
|
229
|
+
}));
|
|
230
|
+
}),
|
|
231
|
+
catchError(() => {
|
|
232
|
+
patchState(store, (state) => ({
|
|
233
|
+
status: { ...state.status, error: new Error('Error al cargar users'), loading: false }
|
|
234
|
+
}));
|
|
235
|
+
return EMPTY;
|
|
236
|
+
})
|
|
237
|
+
);
|
|
238
|
+
})
|
|
239
|
+
)
|
|
240
|
+
),
|
|
241
|
+
removeUser: rxMethod<RequestConfig<number, boolean>>(
|
|
242
|
+
pipe(
|
|
243
|
+
tap(({ payload }) => {
|
|
244
|
+
patchState(store, (state) => ({
|
|
245
|
+
status: {
|
|
246
|
+
...state.status,
|
|
247
|
+
_removeLoading: true,
|
|
248
|
+
idsRemoving: [...(state.status.idsRemoving || []), payload]
|
|
249
|
+
}
|
|
250
|
+
}));
|
|
251
|
+
}),
|
|
252
|
+
switchMap(({ onError, onSuccess, payload }) => {
|
|
253
|
+
return userService.removeUser$(payload).pipe(
|
|
254
|
+
tap((response) => {
|
|
255
|
+
if (response) {
|
|
256
|
+
const idsRemoving = store.status.idsRemoving() || [];
|
|
257
|
+
patchState(store, removeEntity(payload), (state) => ({
|
|
258
|
+
status: {
|
|
259
|
+
...state.status,
|
|
260
|
+
_removeLoading: false,
|
|
261
|
+
error: null,
|
|
262
|
+
idsRemoving: idsRemoving.filter((idRemoving) => idRemoving !== payload)
|
|
263
|
+
}
|
|
264
|
+
}));
|
|
265
|
+
if (onSuccess) {
|
|
266
|
+
onSuccess(response);
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
throw new Error();
|
|
270
|
+
}
|
|
271
|
+
}),
|
|
272
|
+
catchError(() => {
|
|
273
|
+
const idsRemoving = store.status.idsRemoving() || [];
|
|
274
|
+
patchState(store, (state) => ({
|
|
275
|
+
status: {
|
|
276
|
+
...state.status,
|
|
277
|
+
_removeLoading: false,
|
|
278
|
+
error: new Error(),
|
|
279
|
+
idsRemoving: idsRemoving.filter((idRemoving) => idRemoving !== payload)
|
|
280
|
+
}
|
|
281
|
+
}));
|
|
282
|
+
if (onError) {
|
|
283
|
+
onError();
|
|
284
|
+
}
|
|
285
|
+
return EMPTY;
|
|
286
|
+
})
|
|
287
|
+
);
|
|
288
|
+
})
|
|
289
|
+
)
|
|
290
|
+
),
|
|
291
|
+
updateUser: rxMethod<RequestConfig<UpdateUser, boolean>>(
|
|
292
|
+
pipe(
|
|
293
|
+
tap(({ payload }) => {
|
|
294
|
+
patchState(store, (state) => ({
|
|
295
|
+
status: {
|
|
296
|
+
...state.status,
|
|
297
|
+
_updateLoading: true,
|
|
298
|
+
idsUpdating: [...(state.status.idsUpdating || []), payload.cod]
|
|
299
|
+
}
|
|
300
|
+
}));
|
|
301
|
+
}),
|
|
302
|
+
switchMap(({ onError, onSuccess, payload }) => {
|
|
303
|
+
return userService.updateUser$(entity).pipe(
|
|
304
|
+
tap((response) => {
|
|
305
|
+
if (response) {
|
|
306
|
+
const idsUpdating = store.status.idsUpdating() || [];
|
|
307
|
+
patchState(store, updateEntity({ changes: payload, id: payload.cod }, config), (state) => ({
|
|
308
|
+
status: {
|
|
309
|
+
...state.status,
|
|
310
|
+
_updateLoading: false,
|
|
311
|
+
error: null,
|
|
312
|
+
idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.cod)
|
|
313
|
+
}
|
|
314
|
+
}));
|
|
315
|
+
if (onSuccess) {
|
|
316
|
+
onSuccess(response);
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
throw new Error('');
|
|
320
|
+
}
|
|
321
|
+
}),
|
|
322
|
+
catchError(() => {
|
|
323
|
+
const idsUpdating = store.status.idsUpdating() || [];
|
|
324
|
+
patchState(store, (state) => ({
|
|
325
|
+
status: {
|
|
326
|
+
...state.status,
|
|
327
|
+
_updateLoading: false,
|
|
328
|
+
error: new Error('Error al actualizar user'),
|
|
329
|
+
idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.cod)
|
|
330
|
+
}
|
|
331
|
+
}));
|
|
332
|
+
if (onError) {
|
|
333
|
+
onError();
|
|
334
|
+
}
|
|
335
|
+
return EMPTY;
|
|
336
|
+
})
|
|
337
|
+
);
|
|
338
|
+
})
|
|
339
|
+
)
|
|
340
|
+
),
|
|
341
|
+
})),
|
|
342
|
+
withHooks({
|
|
343
|
+
onInit: (store) => {
|
|
344
|
+
store.loadUsers();
|
|
345
|
+
},
|
|
346
|
+
})
|
|
347
|
+
);
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## 📄 Licencia
|
|
351
|
+
|
|
352
|
+
Este proyecto está bajo la licencia [MIT](LICENSE).
|