@haloduck/core 2.0.1 → 2.0.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.
@@ -0,0 +1,881 @@
1
+ import { from, switchMap, of, distinctUntilChanged, map, catchError, delay, withLatestFrom, tap, forkJoin } from 'rxjs';
2
+ import { fetchAuthSession } from 'aws-amplify/auth';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, isDevMode, Pipe, Injectable, InjectionToken, Inject } from '@angular/core';
5
+ import { createFeatureSelector, createSelector, Store, createAction, props, createReducer, on } from '@ngrx/store';
6
+ import { HttpClient } from '@angular/common/http';
7
+ import { map as map$1, catchError as catchError$1, withLatestFrom as withLatestFrom$1, mergeMap, finalize } from 'rxjs/operators';
8
+ import { ComponentStore } from '@ngrx/component-store';
9
+ import { Actions, createEffect, ofType } from '@ngrx/effects';
10
+
11
+ const authGuard = (route, state) => {
12
+ return from(fetchAuthSession()).pipe(switchMap((session) => {
13
+ if (session.tokens?.idToken) {
14
+ return of(true);
15
+ }
16
+ window.location.href = '/authenticate';
17
+ return of(false);
18
+ }));
19
+ };
20
+
21
+ // deprecated
22
+ const dummyMemberIdInterceptor = (req, next) => {
23
+ const dummyMemberId = localStorage.getItem('dummyMemberId');
24
+ if (req.url.startsWith('http://localhost')) {
25
+ if (dummyMemberId) {
26
+ const clonedRequest = req.clone({
27
+ setHeaders: {
28
+ 'X-Dummy-Member-Id': dummyMemberId || '',
29
+ },
30
+ });
31
+ return next(clonedRequest);
32
+ }
33
+ }
34
+ return next(req);
35
+ };
36
+
37
+ var GlobalSelectors;
38
+ (function (GlobalSelectors) {
39
+ GlobalSelectors.selectGlobalState = createFeatureSelector('global');
40
+ GlobalSelectors.isInitiated = createSelector(GlobalSelectors.selectGlobalState, (state) => state.initiated);
41
+ GlobalSelectors.selectIsAuthenticated = createSelector(GlobalSelectors.selectGlobalState, (state) => state.isAuthenticated);
42
+ GlobalSelectors.selectProfile = createSelector(GlobalSelectors.selectGlobalState, (state) => state.profile);
43
+ GlobalSelectors.selectIsLoading = createSelector(GlobalSelectors.selectGlobalState, (state) => state.loadingReference > 0);
44
+ GlobalSelectors.selectAcl = createSelector(GlobalSelectors.selectGlobalState, (state) => state.acl);
45
+ GlobalSelectors.selectListMenuItem = createSelector(GlobalSelectors.selectGlobalState, (state) => state.listMenuItem);
46
+ GlobalSelectors.selectIsSideMenuOpen = createSelector(GlobalSelectors.selectGlobalState, (state) => state.isSideMenuOpen);
47
+ GlobalSelectors.selectLanguage = createSelector(GlobalSelectors.selectGlobalState, (state) => state.language);
48
+ GlobalSelectors.canActivate = (resource, action, shouldStripTag) => createSelector(GlobalSelectors.selectAcl, (acl) => {
49
+ const allowedActions = [];
50
+ switch (action) {
51
+ case 'delete':
52
+ allowedActions.push('delete');
53
+ break;
54
+ case 'create':
55
+ allowedActions.push('delete');
56
+ allowedActions.push('create');
57
+ break;
58
+ case 'update':
59
+ allowedActions.push('delete');
60
+ allowedActions.push('create');
61
+ allowedActions.push('update');
62
+ break;
63
+ case 'read':
64
+ allowedActions.push('delete');
65
+ allowedActions.push('create');
66
+ allowedActions.push('update');
67
+ allowedActions.push('read');
68
+ }
69
+ const result = Object.keys(acl).some((aclKey) => {
70
+ return ['delete', 'create', 'update', 'read'].some((_action) => {
71
+ if (undefined === acl[aclKey][_action]) {
72
+ return false;
73
+ }
74
+ let [_resource, _conditionsRaw] = resource.split(':');
75
+ const _conditions = _conditionsRaw ? _conditionsRaw.split('|') : [];
76
+ _resource =
77
+ shouldStripTag && _resource.includes('/')
78
+ ? _resource.split('/')[0]
79
+ : _resource;
80
+ const _resourceAclArray = acl[aclKey][_action];
81
+ return _resourceAclArray.some((_resourceAclRaw) => {
82
+ const [_resourceAcl, _conditionsAclRaw] = _resourceAclRaw.split(':');
83
+ const _conditionsAcl = _conditionsAclRaw
84
+ ? _conditionsAclRaw.split('|')
85
+ : [];
86
+ if (_resourceAcl === '*') {
87
+ return true;
88
+ }
89
+ if (_resource === _resourceAcl &&
90
+ allowedActions.includes(_action) &&
91
+ (_conditions.length === 0 ||
92
+ _conditionsAcl.some((_condition) => _conditions.includes(_condition)))) {
93
+ return true;
94
+ }
95
+ return false;
96
+ });
97
+ });
98
+ });
99
+ return result;
100
+ });
101
+ GlobalSelectors.selectCurrentGroupId = createSelector(GlobalSelectors.selectGlobalState, (state) => state.currentGroup?.id);
102
+ GlobalSelectors.selectCurrentGroup = createSelector(GlobalSelectors.selectGlobalState, (state) => state.currentGroup);
103
+ })(GlobalSelectors || (GlobalSelectors = {}));
104
+
105
+ // deprecated
106
+ const groupIdInterceptor = (req, next) => {
107
+ const store = inject((Store));
108
+ const groupId$ = store.select(GlobalSelectors.selectCurrentGroupId);
109
+ if (req.url.endsWith('/member/me'))
110
+ return next(req);
111
+ if (req.url.endsWith('/menu'))
112
+ return next(req);
113
+ if (req.url.endsWith('/acl'))
114
+ return next(req);
115
+ if (req.url.startsWith('https://api') ||
116
+ req.url.startsWith('http://localhost')) {
117
+ return groupId$.pipe(switchMap((groupId) => {
118
+ if (groupId) {
119
+ const clonedRequest = req.clone({
120
+ setHeaders: {
121
+ 'X-Group-Id': groupId || '',
122
+ },
123
+ });
124
+ return next(clonedRequest);
125
+ }
126
+ return next(req);
127
+ }));
128
+ }
129
+ return next(req);
130
+ };
131
+
132
+ const idTokenInterceptor = (req, next) => {
133
+ if (req.url.endsWith('/oauth2/token'))
134
+ return next(req);
135
+ if (req.url.startsWith('https://api')) {
136
+ return from(fetchAuthSession()).pipe(switchMap((session) => {
137
+ if (session.tokens?.idToken) {
138
+ const clonedRequest = req.clone({
139
+ setHeaders: {
140
+ Authorization: `Bearer ${session.tokens.idToken}`,
141
+ },
142
+ });
143
+ return next(clonedRequest);
144
+ }
145
+ return next(req);
146
+ }));
147
+ }
148
+ else if (req.url.startsWith('https://auth') || req.url.startsWith('https://eleven-auth')) {
149
+ return from(fetchAuthSession()).pipe(switchMap((session) => {
150
+ if (session.tokens?.accessToken) {
151
+ const clonedRequest = req.clone({
152
+ setHeaders: {
153
+ Authorization: `Bearer ${session.tokens.accessToken}`,
154
+ },
155
+ });
156
+ return next(clonedRequest);
157
+ }
158
+ return next(req);
159
+ }));
160
+ }
161
+ return next(req);
162
+ };
163
+
164
+ var SearchParams;
165
+ (function (SearchParams) {
166
+ SearchParams.SortDirectionAsc = 'asc';
167
+ SearchParams.SortDirectionDesc = 'desc';
168
+ // export interface OrderAndPage{
169
+ // size: number;
170
+ // sort: Order[];
171
+ // searchAfter?: any[];
172
+ // }
173
+ })(SearchParams || (SearchParams = {}));
174
+
175
+ function responseHandler(response) {
176
+ if (!response) {
177
+ errorHandler({
178
+ error: 'empty response',
179
+ message: 'empty response',
180
+ });
181
+ }
182
+ if (response.error != '00') {
183
+ errorHandler({
184
+ error: response.error,
185
+ message: response.message,
186
+ });
187
+ }
188
+ return response;
189
+ }
190
+ function errorHandler(err) {
191
+ isDevMode() && console.error('API Error: ', err);
192
+ throw err;
193
+ }
194
+
195
+ class DisplayNamePipe {
196
+ transform(member) {
197
+ if (!member)
198
+ return '';
199
+ return (member.nickname?.trim() ||
200
+ (member.firstName || '') + ' ' + (member.lastName || ''));
201
+ }
202
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DisplayNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
203
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.4", ngImport: i0, type: DisplayNamePipe, isStandalone: true, name: "displayName" });
204
+ }
205
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: DisplayNamePipe, decorators: [{
206
+ type: Pipe,
207
+ args: [{
208
+ name: 'displayName',
209
+ }]
210
+ }] });
211
+
212
+ var GlobalActions;
213
+ (function (GlobalActions) {
214
+ GlobalActions.markInitiated = createAction('[Global] Mark Initiated', props());
215
+ GlobalActions.clearAuthentication = createAction('[Global] Clear Authentication');
216
+ GlobalActions.setAuthenticated = createAction('[Global] Set Authenticated', props());
217
+ GlobalActions.setProfile = createAction('[Global] Set Profile', props());
218
+ GlobalActions.increaseLoadingReference = createAction('[Global] Increase Loading Reference');
219
+ GlobalActions.decreaseLoadingReference = createAction('[Global] Decrease Loading Reference');
220
+ GlobalActions.setAcl = createAction('[Global] Set Acl', props());
221
+ GlobalActions.setListMenuItem = createAction('[Global] Set List Menu Item', props());
222
+ GlobalActions.toggleSideMenu = createAction('[Global] Toggle Side Menu');
223
+ GlobalActions.closeSideMenu = createAction('[Global] Close Side Menu');
224
+ GlobalActions.setLanguage = createAction('[Global] Set Language', props());
225
+ GlobalActions.setCurrentGroup = createAction('[Global] Set Current Group', props());
226
+ })(GlobalActions || (GlobalActions = {}));
227
+
228
+ class AuthService {
229
+ globalStore = inject((Store));
230
+ canActivate(resource, action, shouldStripTag) {
231
+ return this.globalStore
232
+ .select(GlobalSelectors.canActivate(resource, action, shouldStripTag))
233
+ .pipe(distinctUntilChanged());
234
+ }
235
+ getProfile() {
236
+ return this.globalStore.select(GlobalSelectors.selectProfile);
237
+ }
238
+ setProfile(profile) {
239
+ return this.globalStore.dispatch(GlobalActions.setProfile({ profile }));
240
+ }
241
+ isAuthenticated() {
242
+ return this.globalStore
243
+ .select(GlobalSelectors.selectIsAuthenticated)
244
+ .pipe(distinctUntilChanged());
245
+ }
246
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
247
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AuthService, providedIn: 'root' });
248
+ }
249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AuthService, decorators: [{
250
+ type: Injectable,
251
+ args: [{
252
+ providedIn: 'root',
253
+ }]
254
+ }] });
255
+
256
+ const defaultLanguage = { id: 'en', value: 'English' };
257
+ const supportedLanguages = [
258
+ defaultLanguage,
259
+ { id: 'ko', value: '한국어' },
260
+ ];
261
+ const HALODUCK_CORE_CONFIG = new InjectionToken('HALODUCK_CORE_CONFIG', {
262
+ providedIn: 'root',
263
+ factory: () => ({
264
+ stage: 'local',
265
+ appName: 'please-register-app-name-via-provideHaloduckCoreConfig',
266
+ defaultLanguage: defaultLanguage.id,
267
+ dateFormat: {
268
+ long: 'yyyy-MM-dd',
269
+ short: 'yyMMdd',
270
+ },
271
+ apiUrl: 'https://please-register-via-provideHaloduckCoreConfig.com',
272
+ cdnUrl: 'https://please-register-via-provideHaloduckCoreConfig.com',
273
+ map: {
274
+ mapId: 'please-register-map-id-via-provideHaloduckCoreConfig',
275
+ googleApiKey: 'please-register-google-api-key-via-provideHaloduckCoreConfig',
276
+ defaultLngLat: {
277
+ lat: 37.575971,
278
+ lng: 126.976800,
279
+ },
280
+ },
281
+ }),
282
+ });
283
+ function provideHaloduckCoreConfig(config) {
284
+ return {
285
+ provide: HALODUCK_CORE_CONFIG,
286
+ useValue: config,
287
+ };
288
+ }
289
+ class CoreService {
290
+ config = inject(HALODUCK_CORE_CONFIG);
291
+ constructor() { }
292
+ getStage() {
293
+ return this.config.stage;
294
+ }
295
+ getAppName() {
296
+ return this.config.appName;
297
+ }
298
+ getDefaultLanguage() {
299
+ return this.config.defaultLanguage;
300
+ }
301
+ getApiUrl() {
302
+ return this.config.apiUrl;
303
+ }
304
+ getCdnUrl() {
305
+ return this.config.cdnUrl;
306
+ }
307
+ getDateFormatLong() {
308
+ return this.config.dateFormat.long;
309
+ }
310
+ getDateFormatShort() {
311
+ return this.config.dateFormat.short;
312
+ }
313
+ getGoogleApiKey() {
314
+ return this.config.map.googleApiKey;
315
+ }
316
+ getMapId() {
317
+ return this.config.map.mapId;
318
+ }
319
+ getDefaultLngLat() {
320
+ return this.config.map.defaultLngLat;
321
+ }
322
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CoreService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
323
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CoreService, providedIn: 'root' });
324
+ }
325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CoreService, decorators: [{
326
+ type: Injectable,
327
+ args: [{
328
+ providedIn: 'root',
329
+ }]
330
+ }], ctorParameters: () => [] });
331
+
332
+ class BaseEntityApiService {
333
+ coreService = inject(CoreService);
334
+ http = inject(HttpClient);
335
+ apiUrl = this.coreService.getApiUrl();
336
+ createEntity(entity, parent) {
337
+ return this.http
338
+ .put(`${this.apiUrl}/${parent ? parent.name + '/' + parent.id + '/' : ''}${this.getEntityName()}`, entity)
339
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
340
+ }
341
+ getListEntity(searchParams, parent) {
342
+ const filter = JSON.stringify(searchParams.filter);
343
+ const sort = JSON.stringify(searchParams.sort);
344
+ const page = searchParams.page ? JSON.stringify(searchParams.page) : '';
345
+ return this.http
346
+ .get(`${this.apiUrl}/${parent ? parent.name + '/' + parent.id + '/' : ''}${this.getEntityName()}`, {
347
+ params: { filter, sort, page },
348
+ })
349
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
350
+ }
351
+ getEntityById(id) {
352
+ return this.http
353
+ .get(`${this.apiUrl}/${this.getEntityName()}/${id}`)
354
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
355
+ }
356
+ updateEntityById(id, entity) {
357
+ return this.http
358
+ .patch(`${this.apiUrl}/${this.getEntityName()}/${id}`, entity)
359
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
360
+ }
361
+ deleteEntityById(id) {
362
+ return this.http
363
+ .delete(`${this.apiUrl}/${this.getEntityName()}/${id}`)
364
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
365
+ }
366
+ getEntityName() {
367
+ throw new Error('Method not implemented.');
368
+ }
369
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: BaseEntityApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
370
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: BaseEntityApiService, providedIn: 'root' });
371
+ }
372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: BaseEntityApiService, decorators: [{
373
+ type: Injectable,
374
+ args: [{
375
+ providedIn: 'root',
376
+ }]
377
+ }] });
378
+
379
+ class CdnApiService {
380
+ coreService = inject(CoreService);
381
+ http = inject(HttpClient);
382
+ apiUrl = this.coreService.getApiUrl();
383
+ upload(file, keyPrefix) {
384
+ return this.getPresignedPutUrl(`${keyPrefix}/${file.name}`).pipe(switchMap((response) => {
385
+ const presignedUrl = response.data.url;
386
+ const key = response.data.key;
387
+ return this.uploadFile(presignedUrl, file).pipe(map(() => {
388
+ return key;
389
+ }), catchError((error) => {
390
+ console.error('Upload error:', error);
391
+ return errorHandler(error);
392
+ }));
393
+ }), catchError((error) => {
394
+ console.error('Error getting presigned URL:', error);
395
+ return errorHandler(error);
396
+ }));
397
+ }
398
+ getPresignedPutUrl(key) {
399
+ return this.http
400
+ .get(`${this.apiUrl}/tool/presignedPutUrl`, {
401
+ params: { key },
402
+ })
403
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
404
+ }
405
+ uploadFile(presignedUrl, file) {
406
+ return this.http
407
+ .put(presignedUrl, file, {
408
+ headers: { 'x-amz-tagging': 'expire1D=true' },
409
+ })
410
+ .pipe(catchError((error) => errorHandler(error)));
411
+ }
412
+ getPresignedGetUrl(key) {
413
+ return this.http
414
+ .get(`${this.apiUrl}/tool/presignedGetUrl`, {
415
+ params: { key },
416
+ })
417
+ .pipe(delay(10000), // Simulate a delay of 1 second
418
+ map((response) => responseHandler(response)), catchError((error) => errorHandler(error)), map((response) => response.data.url));
419
+ }
420
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CdnApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
421
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CdnApiService, providedIn: 'root' });
422
+ }
423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: CdnApiService, decorators: [{
424
+ type: Injectable,
425
+ args: [{
426
+ providedIn: 'root',
427
+ }]
428
+ }] });
429
+
430
+ class GlobalApiService {
431
+ coreService = inject(CoreService);
432
+ http = inject(HttpClient);
433
+ apiUrl = this.coreService.getApiUrl();
434
+ getAcl() {
435
+ return this.http.get(`${this.apiUrl}/acl`).pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
436
+ }
437
+ getListMenuItem() {
438
+ return this.http
439
+ .get(`${this.apiUrl}/menu`)
440
+ .pipe(map((response) => responseHandler(response)), catchError((error) => errorHandler(error)));
441
+ }
442
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GlobalApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
443
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GlobalApiService, providedIn: 'root' });
444
+ }
445
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GlobalApiService, decorators: [{
446
+ type: Injectable,
447
+ args: [{
448
+ providedIn: 'root',
449
+ }]
450
+ }] });
451
+
452
+ class GroupApiService extends BaseEntityApiService {
453
+ getEntityName() {
454
+ return 'group';
455
+ }
456
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GroupApiService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
457
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GroupApiService, providedIn: 'root' });
458
+ }
459
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GroupApiService, decorators: [{
460
+ type: Injectable,
461
+ args: [{
462
+ providedIn: 'root',
463
+ }]
464
+ }] });
465
+
466
+ class MemberApiService extends BaseEntityApiService {
467
+ getEntityName() {
468
+ return 'member';
469
+ }
470
+ getProfile() {
471
+ return this.http
472
+ .get(`${this.apiUrl}/${this.getEntityName()}/me`)
473
+ .pipe(map$1((response) => responseHandler(response)), catchError$1((error) => errorHandler(error)));
474
+ }
475
+ checkMemberByEmail(email) {
476
+ return this.http
477
+ .get(`${this.apiUrl}/${this.getEntityName()}/check/email/${email}`)
478
+ .pipe(map$1((response) => responseHandler(response)), catchError$1((error) => errorHandler(error)));
479
+ }
480
+ checkMemberByNickname(nickname) {
481
+ return this.http
482
+ .get(`${this.apiUrl}/${this.getEntityName()}/check/nickname/${nickname}`)
483
+ .pipe(map$1((response) => responseHandler(response)), catchError$1((error) => errorHandler(error)));
484
+ }
485
+ registration(member) {
486
+ return this.http
487
+ .put(`${this.apiUrl}/${this.getEntityName()}/registration`, member)
488
+ .pipe(map$1((response) => responseHandler(response)), catchError$1((error) => errorHandler(error)));
489
+ }
490
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MemberApiService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
491
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MemberApiService, providedIn: 'root' });
492
+ }
493
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MemberApiService, decorators: [{
494
+ type: Injectable,
495
+ args: [{
496
+ providedIn: 'root',
497
+ }]
498
+ }] });
499
+
500
+ const ITableStateStatusCreating = 'creating';
501
+ const ITableStateStatusCreated = 'created';
502
+ const ITableStateStatusFailedToCreate = 'failedToCreate';
503
+ const ITableStateStatusUpdating = 'updating';
504
+ const ITableStateStatusUpdated = 'updated';
505
+ const ITableStateStatusFailedToUpdate = 'failedToUpdate';
506
+ const ITableStateStatusDeleting = 'deleting';
507
+ const ITableStateStatusDeleted = 'deleted';
508
+ const ITableStateStatusFailedToDelete = 'failedToDelete';
509
+ const ITableStateStatusLoading = 'loading';
510
+ const ITableStateStatusLoaded = 'loaded';
511
+ const ITableStateStatusFailedToLoad = 'failedToLoad';
512
+ class TableStore extends ComponentStore {
513
+ initialState;
514
+ apiService;
515
+ // selectors
516
+ status$ = this.select((state) => state.status);
517
+ parent$ = this.select((state) => state.parent);
518
+ filter$ = this.select((state) => state.filter);
519
+ sort$ = this.select((state) => state.sort);
520
+ page$ = this.select((state) => state.page);
521
+ listEntity$ = this.select((state) => state.listEntity);
522
+ isLoading$ = this.select((state) => state.isLoading);
523
+ lastEvaluatedKey$ = this.select((state) => state.lastEvaluatedKey);
524
+ // effects
525
+ loadListEntity = this.effect((trigger$) => trigger$.pipe(withLatestFrom(this.listEntity$, this.filter$, this.sort$, this.page$, this.parent$), switchMap(([, listEntity, filter, sort, page, parent]) => {
526
+ this.updateStatus(ITableStateStatusLoading);
527
+ return this.apiService
528
+ .getListEntity({ filter, sort, page }, parent)
529
+ .pipe(tap((response) => {
530
+ this.patchState({
531
+ listEntity: [
532
+ ...listEntity,
533
+ ...(response.data ? response.data : []),
534
+ ],
535
+ lastEvaluatedKey: response.lastEvaluatedKey,
536
+ });
537
+ this.updateStatus(ITableStateStatusLoaded);
538
+ }), catchError(() => {
539
+ this.updateStatus(ITableStateStatusFailedToLoad);
540
+ return [];
541
+ }));
542
+ })));
543
+ createEntity = this.effect((trigger$) => trigger$.pipe(withLatestFrom(this.listEntity$, this.parent$), switchMap(([data, listEntity, parent]) => {
544
+ this.updateStatus(ITableStateStatusCreating);
545
+ return this.apiService.createEntity(data, parent).pipe(tap((response) => {
546
+ this.patchState({
547
+ listEntity: (() => {
548
+ if (response.data?.parentId) {
549
+ const updatedListEntity = listEntity.map((entity) => {
550
+ if (entity.id === response.data.parentId) {
551
+ return {
552
+ ...entity,
553
+ children: [
554
+ ...(entity.children
555
+ ? [response.data, ...entity.children]
556
+ : [response.data]),
557
+ ],
558
+ };
559
+ }
560
+ return entity;
561
+ });
562
+ const parentExists = updatedListEntity.some((entity) => entity.id === response.data.parentId);
563
+ if (!parentExists) {
564
+ return updatedListEntity.map((entity) => ({
565
+ ...entity,
566
+ children: entity.children?.map((child) => child.id === response.data.parentId
567
+ ? {
568
+ ...child,
569
+ children: [
570
+ ...(child.children
571
+ ? [response.data, ...child.children]
572
+ : [response.data]),
573
+ ],
574
+ }
575
+ : child),
576
+ }));
577
+ }
578
+ return updatedListEntity;
579
+ }
580
+ return [
581
+ ...(response.data ? [response.data] : []),
582
+ ...listEntity,
583
+ ];
584
+ })(),
585
+ });
586
+ this.updateStatus(ITableStateStatusCreated);
587
+ }), catchError(() => {
588
+ this.updateStatus(ITableStateStatusFailedToCreate);
589
+ return [];
590
+ }));
591
+ })));
592
+ updateEntityById = this.effect((trigger$) => trigger$.pipe(withLatestFrom(this.listEntity$, this.parent$), switchMap(([data, listEntity, parent]) => {
593
+ this.updateStatus(ITableStateStatusUpdating);
594
+ return this.apiService.updateEntityById(data.id, data.entity).pipe(tap((response) => {
595
+ this.patchState({
596
+ listEntity: (() => {
597
+ if (response.data?.parentId) {
598
+ const updatedListEntity = listEntity.map((entity) => {
599
+ if (entity.id === response.data.parentId) {
600
+ return {
601
+ ...entity,
602
+ children: entity.children?.map((child) => child.id === response.data.id ? response.data : child),
603
+ };
604
+ }
605
+ return entity;
606
+ });
607
+ const parentExists = updatedListEntity.some((entity) => entity.id === response.data.parentId);
608
+ if (!parentExists) {
609
+ return updatedListEntity.map((entity) => ({
610
+ ...entity,
611
+ children: entity.children?.map((child) => child.id === response.data.parentId
612
+ ? {
613
+ ...child,
614
+ children: child.children?.map((grandChild) => grandChild.id === response.data.id
615
+ ? response.data
616
+ : grandChild),
617
+ }
618
+ : child),
619
+ }));
620
+ }
621
+ return updatedListEntity;
622
+ }
623
+ return listEntity.map((e) => e.id === response.data.id ? response.data : e);
624
+ })(),
625
+ });
626
+ this.updateStatus(ITableStateStatusUpdated);
627
+ }), catchError(() => {
628
+ this.updateStatus(ITableStateStatusFailedToUpdate);
629
+ return [];
630
+ }));
631
+ })));
632
+ deleteEntityById = this.effect((trigger$) => trigger$.pipe(withLatestFrom(this.listEntity$, this.parent$), switchMap(([id, listEntity, parent]) => {
633
+ this.updateStatus(ITableStateStatusDeleting);
634
+ return this.apiService.deleteEntityById(id).pipe(tap(() => {
635
+ this.patchState({
636
+ listEntity: listEntity.filter((e) => e.id !== id),
637
+ });
638
+ this.updateStatus(ITableStateStatusDeleted);
639
+ }), catchError(() => {
640
+ this.updateStatus(ITableStateStatusFailedToDelete);
641
+ return [];
642
+ }));
643
+ })));
644
+ // actions
645
+ updateEntity = this.updater((state, data) => ({
646
+ ...state,
647
+ listEntity: state.listEntity.map((e) => {
648
+ return e.id === data.id ? data : e;
649
+ }),
650
+ }));
651
+ updateStatus = this.updater((state, status) => ({
652
+ ...state,
653
+ status,
654
+ }));
655
+ setParent = this.updater((state, parent) => ({
656
+ ...state,
657
+ parent,
658
+ }));
659
+ updateSortField = this.updater((state, sort) => ({
660
+ ...state,
661
+ sort: [sort],
662
+ }));
663
+ updateFilter = this.updater((state, filter) => ({
664
+ ...state,
665
+ filter,
666
+ }));
667
+ updatePage = this.updater((state, page) => ({
668
+ ...state,
669
+ page,
670
+ }));
671
+ setExpandMode = this.updater((state, { id, mode }) => ({
672
+ ...state,
673
+ listEntity: state.listEntity.map((e) => ({
674
+ ...e,
675
+ expandMode: e.id === id ? mode : e.expandMode,
676
+ })),
677
+ }));
678
+ toggleExpanded = this.updater((state, { id }) => ({
679
+ ...state,
680
+ listEntity: state.listEntity.map((e) => ({
681
+ ...e,
682
+ isExpanded: e.id === id ? !(e.isExpanded || false) : e.isExpanded,
683
+ })),
684
+ }));
685
+ showExpanded = this.updater((state, { id }) => ({
686
+ ...state,
687
+ listEntity: state.listEntity.map((e) => ({
688
+ ...e,
689
+ isExpanded: e.id === id ? true : e.isExpanded,
690
+ })),
691
+ }));
692
+ hideExpanded = this.updater((state, { id }) => ({
693
+ ...state,
694
+ listEntity: state.listEntity.map((e) => ({
695
+ ...e,
696
+ isExpanded: e.id === id ? false : e.isExpanded,
697
+ })),
698
+ }));
699
+ toggleSelected = this.updater((state, { id }) => ({
700
+ ...state,
701
+ listEntity: state.listEntity.map((e) => ({
702
+ ...e,
703
+ isSelected: e.id === id ? !(e.isSelected || false) : e.isSelected,
704
+ })),
705
+ }));
706
+ constructor(initialState, apiService) {
707
+ super(initialState);
708
+ this.initialState = initialState;
709
+ this.apiService = apiService;
710
+ // this.loadListEntity();
711
+ }
712
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableStore, deps: [{ token: 'initialState' }, { token: 'apiService' }], target: i0.ɵɵFactoryTarget.Injectable });
713
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableStore });
714
+ }
715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableStore, decorators: [{
716
+ type: Injectable
717
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
718
+ type: Inject,
719
+ args: ['initialState']
720
+ }] }, { type: undefined, decorators: [{
721
+ type: Inject,
722
+ args: ['apiService']
723
+ }] }] });
724
+
725
+ class GroupStore extends TableStore {
726
+ constructor() {
727
+ super({
728
+ isLoading: false,
729
+ filter: {
730
+ dateRange: undefined,
731
+ organizationId: [],
732
+ id: [],
733
+ type: [],
734
+ active: null,
735
+ approved: null,
736
+ keyword: '',
737
+ },
738
+ sort: [
739
+ {
740
+ field: 'created_timestamp',
741
+ direction: SearchParams.SortDirectionDesc,
742
+ },
743
+ ],
744
+ page: {
745
+ limit: 10,
746
+ },
747
+ listEntity: [],
748
+ }, inject(GroupApiService));
749
+ }
750
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GroupStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
751
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GroupStore });
752
+ }
753
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GroupStore, decorators: [{
754
+ type: Injectable
755
+ }], ctorParameters: () => [] });
756
+
757
+ class MemberStore extends TableStore {
758
+ constructor() {
759
+ super({
760
+ isLoading: false,
761
+ filter: {
762
+ dateRange: undefined,
763
+ organizationId: [],
764
+ groupId: [],
765
+ type: [],
766
+ active: null,
767
+ keyword: '',
768
+ },
769
+ sort: [
770
+ {
771
+ field: 'created_timestamp',
772
+ direction: SearchParams.SortDirectionDesc,
773
+ },
774
+ ],
775
+ page: {
776
+ limit: 10,
777
+ },
778
+ listEntity: [],
779
+ }, inject(MemberApiService));
780
+ }
781
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MemberStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
782
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MemberStore });
783
+ }
784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: MemberStore, decorators: [{
785
+ type: Injectable
786
+ }], ctorParameters: () => [] });
787
+
788
+ class GlobalEffects {
789
+ actions$ = inject(Actions);
790
+ memberApiService = inject(MemberApiService);
791
+ globalApiService = inject(GlobalApiService);
792
+ groupApiService = inject(GroupApiService);
793
+ store = inject((Store));
794
+ setAuthenticated$ = createEffect(() => this.actions$.pipe(ofType(GlobalActions.setAuthenticated), withLatestFrom$1(this.store.select(GlobalSelectors.selectIsAuthenticated)), mergeMap(([action, isAuthenticated]) => {
795
+ if (isAuthenticated) {
796
+ this.store.dispatch(GlobalActions.increaseLoadingReference());
797
+ return forkJoin({
798
+ profile: this.memberApiService.getProfile(),
799
+ acl: this.globalApiService.getAcl(),
800
+ listMenuItem: this.globalApiService.getListMenuItem(),
801
+ }).pipe(mergeMap(({ profile, acl, listMenuItem }) => {
802
+ const groupId = profile.data.groupId;
803
+ return this.groupApiService.getEntityById(groupId).pipe(mergeMap((group) => [
804
+ GlobalActions.setProfile({ profile: profile.data }),
805
+ GlobalActions.setAcl({ acl: acl.data }),
806
+ GlobalActions.setListMenuItem({
807
+ listMenuItem: listMenuItem.data,
808
+ }),
809
+ GlobalActions.setCurrentGroup({ group: group.data }),
810
+ GlobalActions.markInitiated({ initiated: true }),
811
+ ]));
812
+ }), catchError$1(() => of(GlobalActions.clearAuthentication())), finalize(() => {
813
+ this.store.dispatch(GlobalActions.decreaseLoadingReference());
814
+ }));
815
+ }
816
+ return of(GlobalActions.clearAuthentication());
817
+ })));
818
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GlobalEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
819
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GlobalEffects });
820
+ }
821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GlobalEffects, decorators: [{
822
+ type: Injectable
823
+ }] });
824
+
825
+ const initialState = {
826
+ initiated: false,
827
+ isAuthenticated: false,
828
+ loadingReference: 0,
829
+ acl: {},
830
+ listMenuItem: [],
831
+ isSideMenuOpen: false,
832
+ language: 'en', // TODO: Use a proper language management system
833
+ profile: undefined,
834
+ currentGroup: undefined,
835
+ };
836
+
837
+ const globalReducer = createReducer(initialState, on(GlobalActions.markInitiated, (state) => ({
838
+ ...state,
839
+ initiated: true,
840
+ })), on(GlobalActions.setAuthenticated, (state, { isAuthenticated }) => ({
841
+ ...state,
842
+ isAuthenticated,
843
+ })), on(GlobalActions.setProfile, (state, { profile }) => ({
844
+ ...state,
845
+ profile,
846
+ })), on(GlobalActions.increaseLoadingReference, (state) => ({
847
+ ...state,
848
+ loadingReference: state.loadingReference + 1,
849
+ })), on(GlobalActions.decreaseLoadingReference, (state) => ({
850
+ ...state,
851
+ loadingReference: Math.max(state.loadingReference - 1, 0),
852
+ })), on(GlobalActions.setAcl, (state, { acl }) => ({
853
+ ...state,
854
+ acl,
855
+ })), on(GlobalActions.setListMenuItem, (state, { listMenuItem }) => ({
856
+ ...state,
857
+ listMenuItem,
858
+ })), on(GlobalActions.toggleSideMenu, (state) => ({
859
+ ...state,
860
+ isSideMenuOpen: !state.isSideMenuOpen,
861
+ })), on(GlobalActions.closeSideMenu, (state) => ({
862
+ ...state,
863
+ isSideMenuOpen: false,
864
+ })), on(GlobalActions.setLanguage, (state, { language }) => ({
865
+ ...state,
866
+ language,
867
+ })), on(GlobalActions.setCurrentGroup, (state, { group }) => ({
868
+ ...state,
869
+ currentGroup: group,
870
+ })));
871
+
872
+ /*
873
+ * Public API Surface of core
874
+ */
875
+
876
+ /**
877
+ * Generated bundle index. Do not edit.
878
+ */
879
+
880
+ export { AuthService, BaseEntityApiService, CdnApiService, CoreService, DisplayNamePipe, GlobalActions, GlobalApiService, GlobalEffects, GlobalSelectors, GroupApiService, GroupStore, HALODUCK_CORE_CONFIG, ITableStateStatusCreated, ITableStateStatusCreating, ITableStateStatusDeleted, ITableStateStatusDeleting, ITableStateStatusFailedToCreate, ITableStateStatusFailedToDelete, ITableStateStatusFailedToLoad, ITableStateStatusFailedToUpdate, ITableStateStatusLoaded, ITableStateStatusLoading, ITableStateStatusUpdated, ITableStateStatusUpdating, MemberApiService, MemberStore, SearchParams, TableStore, authGuard, defaultLanguage, dummyMemberIdInterceptor, errorHandler, globalReducer, groupIdInterceptor, idTokenInterceptor, initialState, provideHaloduckCoreConfig, responseHandler, supportedLanguages };
881
+ //# sourceMappingURL=haloduck-core.mjs.map