@masterteam/lookups 0.0.1

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,971 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, Injectable, computed, signal, Component, viewChild, linkedSignal, input } from '@angular/core';
4
+ import { ActivatedRoute, Router, NavigationEnd, RouterOutlet } from '@angular/router';
5
+ import { Breadcrumb } from '@masterteam/components/breadcrumb';
6
+ import { Action, Selector, State, Store, select } from '@ngxs/store';
7
+ import { HttpClient } from '@angular/common/http';
8
+ import { CrudStateBase, handleApiRequest, ValidatorConfig, ColorPickerFieldConfig } from '@masterteam/components';
9
+ import { TranslocoService, TranslocoDirective } from '@jsverse/transloco';
10
+ import { Page } from '@masterteam/components/page';
11
+ import { filter, finalize } from 'rxjs';
12
+ import { ModalRef, DialogService } from '@masterteam/components/dialog';
13
+ import { Table } from '@masterteam/components/table';
14
+ import * as i2 from 'primeng/skeleton';
15
+ import { SkeletonModule } from 'primeng/skeleton';
16
+ import * as i1 from '@angular/forms';
17
+ import { FormControl, ReactiveFormsModule, FormBuilder, FormsModule } from '@angular/forms';
18
+ import { Button } from '@masterteam/components/button';
19
+ import { DynamicForm } from '@masterteam/forms/dynamic-form';
20
+ import { ModalService } from '@masterteam/components/modal';
21
+ import { Avatar } from '@masterteam/components/avatar';
22
+ import { Card } from '@masterteam/components/card';
23
+ import { TextField } from '@masterteam/components/text-field';
24
+
25
+ class GetLookups {
26
+ params;
27
+ static type = '[Lookups] Get All';
28
+ constructor(params) {
29
+ this.params = params;
30
+ }
31
+ }
32
+ class GetLookup {
33
+ id;
34
+ mode;
35
+ static type = '[Lookups] Get One';
36
+ constructor(id, mode = 'edit') {
37
+ this.id = id;
38
+ this.mode = mode;
39
+ }
40
+ }
41
+ class CreateLookup {
42
+ payload;
43
+ static type = '[Lookups] Create';
44
+ constructor(payload) {
45
+ this.payload = payload;
46
+ }
47
+ }
48
+ class UpdateLookup {
49
+ payload;
50
+ static type = '[Lookups] Update';
51
+ constructor(payload) {
52
+ this.payload = payload;
53
+ }
54
+ }
55
+ class DeleteLookup {
56
+ id;
57
+ static type = '[Lookups] Delete';
58
+ constructor(id) {
59
+ this.id = id;
60
+ }
61
+ }
62
+ class CreateLookupItem {
63
+ lookupId;
64
+ payload;
65
+ static type = '[Lookups] Create Item';
66
+ constructor(lookupId, payload) {
67
+ this.lookupId = lookupId;
68
+ this.payload = payload;
69
+ }
70
+ }
71
+ class UpdateLookupItem {
72
+ lookupId;
73
+ lookupItemId;
74
+ payload;
75
+ static type = '[Lookups] Update Item';
76
+ constructor(lookupId, lookupItemId, payload) {
77
+ this.lookupId = lookupId;
78
+ this.lookupItemId = lookupItemId;
79
+ this.payload = payload;
80
+ }
81
+ }
82
+ class DeleteLookupItem {
83
+ lookupId;
84
+ itemId;
85
+ static type = '[Lookups] Delete Item';
86
+ constructor(lookupId, itemId) {
87
+ this.lookupId = lookupId;
88
+ this.itemId = itemId;
89
+ }
90
+ }
91
+
92
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
93
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
94
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
95
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
96
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
97
+ };
98
+ const DEFAULT_STATE = {
99
+ lookups: [],
100
+ selectedLookup: null,
101
+ loadingActive: [],
102
+ errors: {},
103
+ };
104
+ let LookupsState = class LookupsState extends CrudStateBase {
105
+ http = inject(HttpClient);
106
+ baseUrl = 'Lookups';
107
+ // Data selectors
108
+ static getLookups(state) {
109
+ return state.lookups;
110
+ }
111
+ static getSelectedLookup(state) {
112
+ return state.selectedLookup;
113
+ }
114
+ static getPredefinedLookups(state) {
115
+ return state.lookups.filter((lookup) => !lookup.allowManage);
116
+ }
117
+ static getCustomLookups(state) {
118
+ return state.lookups.filter((lookup) => lookup.allowManage);
119
+ }
120
+ // Loading/Error slice selectors
121
+ static getLoadingActive(state) {
122
+ return state.loadingActive;
123
+ }
124
+ static getErrors(state) {
125
+ return state.errors;
126
+ }
127
+ getAll(ctx, action) {
128
+ const params = Object.entries(action.params ?? {}).reduce((acc, [key, value]) => {
129
+ if (value === undefined || value === null) {
130
+ return acc;
131
+ }
132
+ if (Array.isArray(value)) {
133
+ acc[key] = value.map((item) => String(item));
134
+ return acc;
135
+ }
136
+ acc[key] = String(value);
137
+ return acc;
138
+ }, {});
139
+ const req$ = this.http.get(this.baseUrl, { params });
140
+ return handleApiRequest({
141
+ ctx,
142
+ key: 'getLookups',
143
+ request$: req$,
144
+ onSuccess: (response) => ({
145
+ lookups: Array.isArray(response?.data) ? response.data : [],
146
+ }),
147
+ errorMessage: 'Failed to load lookups',
148
+ });
149
+ }
150
+ getOne(ctx, action) {
151
+ const params = { mode: action.mode ?? 'edit' };
152
+ const req$ = this.http.get(`${this.baseUrl}/${encodeURIComponent(String(action.id))}`, { params });
153
+ return handleApiRequest({
154
+ ctx,
155
+ key: 'getLookupById',
156
+ request$: req$,
157
+ onSuccess: (response) => ({
158
+ selectedLookup: response?.data ?? null,
159
+ }),
160
+ errorMessage: 'Failed to load lookup',
161
+ });
162
+ }
163
+ createLookup(ctx, action) {
164
+ const req$ = this.http.post(this.baseUrl, action.payload);
165
+ return handleApiRequest({
166
+ ctx,
167
+ key: 'addLookup',
168
+ request$: req$,
169
+ onSuccess: (response, state) => {
170
+ if (!response?.data)
171
+ return {};
172
+ return {
173
+ lookups: this.adapter.addOne(state.lookups, response.data),
174
+ selectedLookup: response.data,
175
+ };
176
+ },
177
+ errorMessage: 'Failed to create lookup',
178
+ });
179
+ }
180
+ updateLookup(ctx, action) {
181
+ const req$ = this.http.put(`${this.baseUrl}/${encodeURIComponent(String(action.payload.id))}`, action.payload);
182
+ return handleApiRequest({
183
+ ctx,
184
+ key: 'updateLookup',
185
+ request$: req$,
186
+ onSuccess: (response, state) => {
187
+ if (!response?.data)
188
+ return {};
189
+ const updated = response.data;
190
+ return {
191
+ lookups: this.adapter.upsertOne(state.lookups, updated, 'id'),
192
+ selectedLookup: state.selectedLookup?.id === updated.id
193
+ ? { ...state.selectedLookup, ...updated }
194
+ : state.selectedLookup,
195
+ };
196
+ },
197
+ errorMessage: 'Failed to update lookup',
198
+ });
199
+ }
200
+ deleteLookup(ctx, action) {
201
+ const req$ = this.http.delete(`${this.baseUrl}/${encodeURIComponent(String(action.id))}`);
202
+ return handleApiRequest({
203
+ ctx,
204
+ key: 'deleteLookup',
205
+ request$: req$,
206
+ onSuccess: (_, state) => {
207
+ const lookups = this.adapter.removeOne(state.lookups, action.id, 'id');
208
+ const nextSelected = state.selectedLookup && state.selectedLookup.id === Number(action.id)
209
+ ? null
210
+ : state.selectedLookup;
211
+ return {
212
+ lookups,
213
+ selectedLookup: nextSelected,
214
+ };
215
+ },
216
+ errorMessage: 'Failed to delete lookup',
217
+ });
218
+ }
219
+ createItem(ctx, action) {
220
+ const req$ = this.http.post(`${this.baseUrl}/LookupItem`, action.payload);
221
+ return handleApiRequest({
222
+ ctx,
223
+ key: 'addLookupItem',
224
+ request$: req$,
225
+ onSuccess: (response, state) => {
226
+ if (!response?.data)
227
+ return {};
228
+ const newItem = response.data;
229
+ const { selectedLookup } = state;
230
+ if (selectedLookup?.id !== Number(action.lookupId)) {
231
+ return {};
232
+ }
233
+ return {
234
+ selectedLookup: {
235
+ ...selectedLookup,
236
+ items: [...selectedLookup.items, newItem],
237
+ },
238
+ };
239
+ },
240
+ errorMessage: 'Failed to add lookup item',
241
+ });
242
+ }
243
+ updateItem(ctx, action) {
244
+ const req$ = this.http.put(`${this.baseUrl}/LookupItem/${encodeURIComponent(String(action.lookupItemId))}`, action.payload);
245
+ return handleApiRequest({
246
+ ctx,
247
+ key: 'updateLookupItem',
248
+ request$: req$,
249
+ onSuccess: (response, state) => {
250
+ if (!response?.data)
251
+ return {};
252
+ const updatedItem = response.data;
253
+ const { selectedLookup } = state;
254
+ if (selectedLookup?.id !== Number(action.lookupId)) {
255
+ return {};
256
+ }
257
+ return {
258
+ selectedLookup: {
259
+ ...selectedLookup,
260
+ items: selectedLookup.items.map((item) => item.id === Number(action.lookupItemId) ? updatedItem : item),
261
+ },
262
+ };
263
+ },
264
+ errorMessage: 'Failed to update lookup item',
265
+ });
266
+ }
267
+ deleteItem(ctx, action) {
268
+ const req$ = this.http.delete(`${this.baseUrl}/LookupItem/${encodeURIComponent(String(action.itemId))}`);
269
+ return handleApiRequest({
270
+ ctx,
271
+ key: 'deleteLookupItem',
272
+ request$: req$,
273
+ onSuccess: (response, state) => {
274
+ if (response?.data !== true)
275
+ return {};
276
+ const { lookups, selectedLookup } = state;
277
+ const updatedLookups = lookups.map((lookup) => {
278
+ if (lookup.id === Number(action.lookupId)) {
279
+ return {
280
+ ...lookup,
281
+ items: lookup.items.filter((item) => item.id !== Number(action.itemId)),
282
+ };
283
+ }
284
+ return lookup;
285
+ });
286
+ const updatedSelectedLookup = selectedLookup?.id === Number(action.lookupId)
287
+ ? {
288
+ ...selectedLookup,
289
+ items: selectedLookup.items.filter((item) => item.id !== Number(action.itemId)),
290
+ }
291
+ : selectedLookup;
292
+ return {
293
+ lookups: updatedLookups,
294
+ selectedLookup: updatedSelectedLookup,
295
+ };
296
+ },
297
+ errorMessage: 'Failed to delete lookup item',
298
+ });
299
+ }
300
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsState, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
301
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsState });
302
+ };
303
+ __decorate([
304
+ Action(GetLookups)
305
+ ], LookupsState.prototype, "getAll", null);
306
+ __decorate([
307
+ Action(GetLookup)
308
+ ], LookupsState.prototype, "getOne", null);
309
+ __decorate([
310
+ Action(CreateLookup)
311
+ ], LookupsState.prototype, "createLookup", null);
312
+ __decorate([
313
+ Action(UpdateLookup)
314
+ ], LookupsState.prototype, "updateLookup", null);
315
+ __decorate([
316
+ Action(DeleteLookup)
317
+ ], LookupsState.prototype, "deleteLookup", null);
318
+ __decorate([
319
+ Action(CreateLookupItem)
320
+ ], LookupsState.prototype, "createItem", null);
321
+ __decorate([
322
+ Action(UpdateLookupItem)
323
+ ], LookupsState.prototype, "updateItem", null);
324
+ __decorate([
325
+ Action(DeleteLookupItem)
326
+ ], LookupsState.prototype, "deleteItem", null);
327
+ __decorate([
328
+ Selector()
329
+ ], LookupsState, "getLookups", null);
330
+ __decorate([
331
+ Selector()
332
+ ], LookupsState, "getSelectedLookup", null);
333
+ __decorate([
334
+ Selector()
335
+ ], LookupsState, "getPredefinedLookups", null);
336
+ __decorate([
337
+ Selector()
338
+ ], LookupsState, "getCustomLookups", null);
339
+ __decorate([
340
+ Selector()
341
+ ], LookupsState, "getLoadingActive", null);
342
+ __decorate([
343
+ Selector()
344
+ ], LookupsState, "getErrors", null);
345
+ LookupsState = __decorate([
346
+ State({
347
+ name: 'lookups',
348
+ defaults: DEFAULT_STATE,
349
+ })
350
+ ], LookupsState);
351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsState, decorators: [{
352
+ type: Injectable
353
+ }], propDecorators: { getAll: [], getOne: [], createLookup: [], updateLookup: [], deleteLookup: [], createItem: [], updateItem: [], deleteItem: [] } });
354
+
355
+ class LookupsFacade {
356
+ store = inject(Store);
357
+ // ============================================================================
358
+ // Data Selectors - Memoized by NGXS (fine-grained reactivity)
359
+ // ============================================================================
360
+ lookups = select(LookupsState.getLookups);
361
+ selectedLookup = select(LookupsState.getSelectedLookup);
362
+ predefinedLookups = select(LookupsState.getPredefinedLookups);
363
+ customLookups = select(LookupsState.getCustomLookups);
364
+ // ============================================================================
365
+ // Loading/Error Slices - Memoized by NGXS
366
+ // ============================================================================
367
+ loadingActive = select(LookupsState.getLoadingActive);
368
+ errors = select(LookupsState.getErrors);
369
+ // ============================================================================
370
+ // Loading Signals - Computed from slice (minimal reactivity)
371
+ // ============================================================================
372
+ isLoadingLookups = computed(() => this.loadingActive().includes('getLookups'), ...(ngDevMode ? [{ debugName: "isLoadingLookups" }] : []));
373
+ isLoadingLookupById = computed(() => this.loadingActive().includes('getLookupById'), ...(ngDevMode ? [{ debugName: "isLoadingLookupById" }] : []));
374
+ isAddingLookup = computed(() => this.loadingActive().includes('addLookup'), ...(ngDevMode ? [{ debugName: "isAddingLookup" }] : []));
375
+ isUpdatingLookup = computed(() => this.loadingActive().includes('updateLookup'), ...(ngDevMode ? [{ debugName: "isUpdatingLookup" }] : []));
376
+ isDeletingLookup = computed(() => this.loadingActive().includes('deleteLookup'), ...(ngDevMode ? [{ debugName: "isDeletingLookup" }] : []));
377
+ isAddingLookupItem = computed(() => this.loadingActive().includes('addLookupItem'), ...(ngDevMode ? [{ debugName: "isAddingLookupItem" }] : []));
378
+ isUpdatingLookupItem = computed(() => this.loadingActive().includes('updateLookupItem'), ...(ngDevMode ? [{ debugName: "isUpdatingLookupItem" }] : []));
379
+ isDeletingLookupItem = computed(() => this.loadingActive().includes('deleteLookupItem'), ...(ngDevMode ? [{ debugName: "isDeletingLookupItem" }] : []));
380
+ // ============================================================================
381
+ // Error Signals - Computed from slice (minimal reactivity)
382
+ // ============================================================================
383
+ lookupsError = computed(() => this.errors()['getLookups'] ?? null, ...(ngDevMode ? [{ debugName: "lookupsError" }] : []));
384
+ lookupByIdError = computed(() => this.errors()['getLookupById'] ?? null, ...(ngDevMode ? [{ debugName: "lookupByIdError" }] : []));
385
+ addLookupError = computed(() => this.errors()['addLookup'] ?? null, ...(ngDevMode ? [{ debugName: "addLookupError" }] : []));
386
+ updateLookupError = computed(() => this.errors()['updateLookup'] ?? null, ...(ngDevMode ? [{ debugName: "updateLookupError" }] : []));
387
+ deleteLookupError = computed(() => this.errors()['deleteLookup'] ?? null, ...(ngDevMode ? [{ debugName: "deleteLookupError" }] : []));
388
+ addLookupItemError = computed(() => this.errors()['addLookupItem'] ?? null, ...(ngDevMode ? [{ debugName: "addLookupItemError" }] : []));
389
+ updateLookupItemError = computed(() => this.errors()['updateLookupItem'] ?? null, ...(ngDevMode ? [{ debugName: "updateLookupItemError" }] : []));
390
+ deleteLookupItemError = computed(() => this.errors()['deleteLookupItem'] ?? null, ...(ngDevMode ? [{ debugName: "deleteLookupItemError" }] : []));
391
+ // ============================================================================
392
+ // Action Dispatchers
393
+ // ============================================================================
394
+ loadAll(params) {
395
+ return this.store.dispatch(new GetLookups(params));
396
+ }
397
+ loadOne(id, mode = 'edit') {
398
+ return this.store.dispatch(new GetLookup(id, mode));
399
+ }
400
+ create(payload) {
401
+ return this.store.dispatch(new CreateLookup(payload));
402
+ }
403
+ update(payload) {
404
+ return this.store.dispatch(new UpdateLookup(payload));
405
+ }
406
+ delete(id) {
407
+ return this.store.dispatch(new DeleteLookup(id));
408
+ }
409
+ createItem(lookupId, payload) {
410
+ return this.store.dispatch(new CreateLookupItem(lookupId, payload));
411
+ }
412
+ updateItem(lookupId, lookupItemId, payload) {
413
+ return this.store.dispatch(new UpdateLookupItem(lookupId, lookupItemId, payload));
414
+ }
415
+ deleteItem(lookupId, itemId) {
416
+ return this.store.dispatch(new DeleteLookupItem(lookupId, itemId));
417
+ }
418
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
419
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsFacade, providedIn: 'root' });
420
+ }
421
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsFacade, decorators: [{
422
+ type: Injectable,
423
+ args: [{
424
+ providedIn: 'root',
425
+ }]
426
+ }] });
427
+
428
+ class Lookups {
429
+ route = inject(ActivatedRoute);
430
+ router = inject(Router);
431
+ facade = inject(LookupsFacade);
432
+ transloco = inject(TranslocoService);
433
+ isDetailPage = signal(false, ...(ngDevMode ? [{ debugName: "isDetailPage" }] : []));
434
+ breadcrumbItems = [
435
+ {
436
+ label: '',
437
+ icon: 'general.home-line',
438
+ routerLink: '/control-panel/product-settings/custom',
439
+ },
440
+ {
441
+ label: this.transloco.translate('lookups.Product_Settings'),
442
+ routerLink: '/control-panel/product-settings',
443
+ },
444
+ { label: this.transloco.translate('lookups.Lookups') },
445
+ ];
446
+ ngOnInit() {
447
+ this.facade.loadAll();
448
+ this.checkRoute();
449
+ this.router.events
450
+ .pipe(filter((event) => event instanceof NavigationEnd))
451
+ .subscribe(() => {
452
+ this.checkRoute();
453
+ });
454
+ }
455
+ goBack() {
456
+ this.router.navigate(['control-panel/product-settings']);
457
+ }
458
+ checkRoute() {
459
+ const firstChild = this.route.snapshot.firstChild;
460
+ this.isDetailPage.set(!!firstChild?.paramMap.get('id'));
461
+ }
462
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Lookups, deps: [], target: i0.ɵɵFactoryTarget.Component });
463
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: Lookups, isStandalone: true, selector: "mt-lookups", ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n @if (!isDetailPage()) {\r\n <mt-page\r\n [title]=\"t('lookups.Product_Lookups')\"\r\n [avatarIcon]=\"'file.file-plus-02'\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-yellow-100)',\r\n '--p-avatar-color': 'var(--p-yellow-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n >\r\n <h3 class=\"font-bold text-xl\">{{ t(\"lookups.All_Lookups\") }}</h3>\r\n <mt-breadcrumb\r\n [items]=\"breadcrumbItems\"\r\n [styleClass]=\"'flex justify-start mx-1'\"\r\n ></mt-breadcrumb>\r\n <router-outlet />\r\n </mt-page>\r\n } @else {\r\n <router-outlet />\r\n }\r\n</ng-container>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: Breadcrumb, selector: "mt-breadcrumb", inputs: ["items", "styleClass"], outputs: ["onItemClick"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
464
+ }
465
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Lookups, decorators: [{
466
+ type: Component,
467
+ args: [{ selector: 'mt-lookups', imports: [CommonModule, Page, Breadcrumb, RouterOutlet, TranslocoDirective], template: "<ng-container *transloco=\"let t\">\r\n @if (!isDetailPage()) {\r\n <mt-page\r\n [title]=\"t('lookups.Product_Lookups')\"\r\n [avatarIcon]=\"'file.file-plus-02'\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-yellow-100)',\r\n '--p-avatar-color': 'var(--p-yellow-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n >\r\n <h3 class=\"font-bold text-xl\">{{ t(\"lookups.All_Lookups\") }}</h3>\r\n <mt-breadcrumb\r\n [items]=\"breadcrumbItems\"\r\n [styleClass]=\"'flex justify-start mx-1'\"\r\n ></mt-breadcrumb>\r\n <router-outlet />\r\n </mt-page>\r\n } @else {\r\n <router-outlet />\r\n }\r\n</ng-container>\r\n" }]
468
+ }] });
469
+
470
+ class LookupForm {
471
+ modal = inject(ModalService);
472
+ ref = inject(ModalRef);
473
+ facade = inject(LookupsFacade);
474
+ router = inject(Router);
475
+ transloco = inject(TranslocoService);
476
+ selectedLookup = this.facade.selectedLookup;
477
+ lookupFormConfig = signal({
478
+ sections: [
479
+ {
480
+ key: 'lookupFormConfig',
481
+ type: 'header',
482
+ order: 1,
483
+ fields: [
484
+ {
485
+ key: 'nameEn',
486
+ label: this.transloco.translate('lookups.EnglishName'),
487
+ placeholder: this.transloco.translate('lookups.EnglishName'),
488
+ validators: [ValidatorConfig.required()],
489
+ order: 2,
490
+ },
491
+ {
492
+ key: 'nameAr',
493
+ label: this.transloco.translate('lookups.ArabicName'),
494
+ placeholder: this.transloco.translate('lookups.ArabicName'),
495
+ validators: [ValidatorConfig.required()],
496
+ order: 3,
497
+ },
498
+ ],
499
+ },
500
+ ],
501
+ }, ...(ngDevMode ? [{ debugName: "lookupFormConfig" }] : []));
502
+ lookupFormControl = new FormControl();
503
+ onSubmit() {
504
+ if (this.lookupFormControl.valid && !this.facade.isAddingLookup()) {
505
+ const body = {
506
+ name: {
507
+ en: this.lookupFormControl.value.nameEn,
508
+ ar: this.lookupFormControl.value.nameAr,
509
+ },
510
+ };
511
+ this.facade.create(body).subscribe({
512
+ next: () => {
513
+ this.ref.close(this.lookupFormControl.value);
514
+ if (this.selectedLookup()?.id) {
515
+ this.router.navigate([
516
+ '/control-panel/product-settings/lookups',
517
+ this.selectedLookup()?.id,
518
+ ]);
519
+ }
520
+ },
521
+ error: () => { },
522
+ });
523
+ }
524
+ }
525
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
526
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LookupForm, isStandalone: true, selector: "mt-lookup-form", ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div [class]=\"'flex flex-col gap-1 p-4 my-4' + modal.contentClass\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"lookupFormConfig()\"\r\n [formControl]=\"lookupFormControl\"\r\n />\r\n </form>\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\" class=\"mt-7\">\r\n <mt-button\r\n label=\"{{ t('lookups.Create') }}\"\r\n (click)=\"onSubmit()\"\r\n [loading]=\"facade.isAddingLookup()\"\r\n [disabled]=\"!this.lookupFormControl.valid || facade.isAddingLookup()\"\r\n />\r\n </div>\r\n</ng-container>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
527
+ }
528
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupForm, decorators: [{
529
+ type: Component,
530
+ args: [{ selector: 'mt-lookup-form', imports: [
531
+ CommonModule,
532
+ Button,
533
+ DynamicForm,
534
+ ReactiveFormsModule,
535
+ TranslocoDirective,
536
+ ], template: "<ng-container *transloco=\"let t\">\r\n <div [class]=\"'flex flex-col gap-1 p-4 my-4' + modal.contentClass\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"lookupFormConfig()\"\r\n [formControl]=\"lookupFormControl\"\r\n />\r\n </form>\r\n </div>\r\n\r\n <div [class]=\"modal.footerClass\" class=\"mt-7\">\r\n <mt-button\r\n label=\"{{ t('lookups.Create') }}\"\r\n (click)=\"onSubmit()\"\r\n [loading]=\"facade.isAddingLookup()\"\r\n [disabled]=\"!this.lookupFormControl.valid || facade.isAddingLookup()\"\r\n />\r\n </div>\r\n</ng-container>\r\n" }]
537
+ }] });
538
+
539
+ class LookupsList {
540
+ typeCol = viewChild.required('typeCol');
541
+ itemsCol = viewChild.required('itemsCol');
542
+ userCol = viewChild.required('userCol');
543
+ facade = inject(LookupsFacade);
544
+ modal = inject(ModalService);
545
+ router = inject(Router);
546
+ route = inject(ActivatedRoute);
547
+ transloco = inject(TranslocoService);
548
+ // Tabs for filtering lookups
549
+ tabs = signal([
550
+ { label: this.transloco.translate('lookups.all'), value: 'all' },
551
+ { label: this.transloco.translate('lookups.system'), value: 'system' },
552
+ { label: this.transloco.translate('lookups.custom'), value: 'custom' },
553
+ ], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
554
+ allLookups = this.facade.lookups;
555
+ loading = this.facade.isLoadingLookups;
556
+ lookups = computed(() => {
557
+ const tab = this.activeTab();
558
+ const all = this.allLookups();
559
+ switch (tab) {
560
+ case 'system':
561
+ return all.filter((lookup) => !lookup.allowDelete);
562
+ case 'custom':
563
+ return all.filter((lookup) => lookup.allowDelete);
564
+ case 'all':
565
+ default:
566
+ return all;
567
+ }
568
+ }, ...(ngDevMode ? [{ debugName: "lookups" }] : []));
569
+ activeTab = signal('all', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
570
+ tableColumns = linkedSignal(() => [
571
+ {
572
+ key: 'name',
573
+ label: this.transloco.translate('lookups.title'),
574
+ filterConfig: {
575
+ type: 'text',
576
+ label: this.transloco.translate('lookups.title'),
577
+ },
578
+ },
579
+ {
580
+ key: 'allowDelete',
581
+ label: this.transloco.translate('lookups.type'),
582
+ type: 'custom',
583
+ customCellTpl: this.typeCol(),
584
+ },
585
+ {
586
+ key: 'createdBy',
587
+ label: this.transloco.translate('lookups.createdBy'),
588
+ type: 'custom',
589
+ customCellTpl: this.userCol(),
590
+ },
591
+ {
592
+ key: 'items',
593
+ label: this.transloco.translate('lookups.items'),
594
+ type: 'custom',
595
+ customCellTpl: this.itemsCol(),
596
+ },
597
+ ], ...(ngDevMode ? [{ debugName: "tableColumns" }] : []));
598
+ tableActions = signal([
599
+ {
600
+ icon: 'general.plus',
601
+ label: this.transloco.translate('lookups.Create_New_Lookup'),
602
+ color: 'primary',
603
+ action: () => {
604
+ this.addLookupsDialog();
605
+ },
606
+ },
607
+ ], ...(ngDevMode ? [{ debugName: "tableActions" }] : []));
608
+ deletingRowIds = signal([], ...(ngDevMode ? [{ debugName: "deletingRowIds" }] : []));
609
+ rowActions = signal([
610
+ {
611
+ icon: 'custom.pencil',
612
+ tooltip: this.transloco.translate('lookups.Edit'),
613
+ color: 'primary',
614
+ action: (row) => {
615
+ this.editLookup(row);
616
+ },
617
+ },
618
+ {
619
+ icon: 'general.trash-01',
620
+ tooltip: this.transloco.translate('lookups.Delete'),
621
+ color: 'danger',
622
+ variant: 'outlined',
623
+ action: (row) => {
624
+ this.deletingRowIds.update((ids) => [...ids, row.id]);
625
+ this.facade
626
+ .delete(row.id)
627
+ .pipe(finalize(() => {
628
+ this.deletingRowIds.update((ids) => ids.filter((id) => id !== row.id));
629
+ }))
630
+ .subscribe({
631
+ error: () => { },
632
+ });
633
+ },
634
+ hidden: (row) => !row.allowDelete,
635
+ confirmation: {
636
+ type: 'popup',
637
+ confirmationType: 'delete',
638
+ },
639
+ loading: (row) => this.deletingRowIds().includes(row.id),
640
+ },
641
+ ], ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
642
+ ngOnInit() {
643
+ this.facade.loadAll();
644
+ }
645
+ addLookupsDialog(lookup = null) {
646
+ this.modal.openModal(LookupForm, 'dialog', {
647
+ header: this.transloco.translate('lookups.Create_New_Lookup'),
648
+ styleClass: '!w-[30vw]',
649
+ height: 'auto',
650
+ appendTo: 'body',
651
+ dismissableMask: true,
652
+ inputValues: {
653
+ lookup: lookup,
654
+ },
655
+ });
656
+ }
657
+ editLookup(lookup) {
658
+ this.router.navigate([lookup.id], { relativeTo: this.route.parent });
659
+ }
660
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsList, deps: [], target: i0.ɵɵFactoryTarget.Component });
661
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.3", type: LookupsList, isStandalone: true, selector: "mt-lookups-list", providers: [DialogService], viewQueries: [{ propertyName: "typeCol", first: true, predicate: ["typeCol"], descendants: true, isSignal: true }, { propertyName: "itemsCol", first: true, predicate: ["itemsCol"], descendants: true, isSignal: true }, { propertyName: "userCol", first: true, predicate: ["userCol"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <div class=\"mt-5\">\r\n <ng-template #typeCol let-row>\r\n <div>{{ row.allowDelete ? \"Custom\" : \"System\" }}</div>\r\n </ng-template>\r\n\r\n <ng-template #itemsCol let-row>\r\n <div>{{ row?.items?.length + \" Items\" }}</div>\r\n </ng-template>\r\n <ng-template #userCol let-row>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-avatar [icon]=\"'custom.user-pp'\"> </mt-avatar>\r\n {{ row?.createdBy?.displayName || \"-\" }}\r\n </div>\r\n </ng-template>\r\n <mt-table\r\n [tabs]=\"tabs()\"\r\n [(activeTab)]=\"activeTab\"\r\n [data]=\"lookups()\"\r\n [columns]=\"tableColumns()\"\r\n [actions]=\"tableActions()\"\r\n [rowActions]=\"rowActions()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [loading]=\"loading()\"\r\n >\r\n </mt-table>\r\n </div>\r\n</ng-container>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }] });
662
+ }
663
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsList, decorators: [{
664
+ type: Component,
665
+ args: [{ selector: 'mt-lookups-list', imports: [CommonModule, SkeletonModule, Table, TranslocoDirective, Avatar], providers: [DialogService], template: "<ng-container *transloco=\"let t\">\r\n <div class=\"mt-5\">\r\n <ng-template #typeCol let-row>\r\n <div>{{ row.allowDelete ? \"Custom\" : \"System\" }}</div>\r\n </ng-template>\r\n\r\n <ng-template #itemsCol let-row>\r\n <div>{{ row?.items?.length + \" Items\" }}</div>\r\n </ng-template>\r\n <ng-template #userCol let-row>\r\n <div class=\"flex items-center gap-2\">\r\n <mt-avatar [icon]=\"'custom.user-pp'\"> </mt-avatar>\r\n {{ row?.createdBy?.displayName || \"-\" }}\r\n </div>\r\n </ng-template>\r\n <mt-table\r\n [tabs]=\"tabs()\"\r\n [(activeTab)]=\"activeTab\"\r\n [data]=\"lookups()\"\r\n [columns]=\"tableColumns()\"\r\n [actions]=\"tableActions()\"\r\n [rowActions]=\"rowActions()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [loading]=\"loading()\"\r\n >\r\n </mt-table>\r\n </div>\r\n</ng-container>\r\n" }]
666
+ }], propDecorators: { typeCol: [{ type: i0.ViewChild, args: ['typeCol', { isSignal: true }] }], itemsCol: [{ type: i0.ViewChild, args: ['itemsCol', { isSignal: true }] }], userCol: [{ type: i0.ViewChild, args: ['userCol', { isSignal: true }] }] } });
667
+
668
+ var LookupsActionKey;
669
+ (function (LookupsActionKey) {
670
+ LookupsActionKey["GetLookups"] = "getLookups";
671
+ LookupsActionKey["GetLookupById"] = "getLookupById";
672
+ LookupsActionKey["AddLookup"] = "addLookup";
673
+ LookupsActionKey["UpdateLookup"] = "updateLookup";
674
+ LookupsActionKey["DeleteLookup"] = "deleteLookup";
675
+ LookupsActionKey["AddLookupItem"] = "addLookupItem";
676
+ LookupsActionKey["UpdateLookupItem"] = "updateLookupItem";
677
+ LookupsActionKey["DeleteLookupItem"] = "deleteLookupItem";
678
+ })(LookupsActionKey || (LookupsActionKey = {}));
679
+
680
+ class LookupItemForm {
681
+ modal = inject(ModalService);
682
+ ref = inject(ModalRef);
683
+ facade = inject(LookupsFacade);
684
+ transloco = inject(TranslocoService);
685
+ itemData = input(null, ...(ngDevMode ? [{ debugName: "itemData" }] : []));
686
+ lookupId = input(0, ...(ngDevMode ? [{ debugName: "lookupId" }] : []));
687
+ editMode = computed(() => !!this.itemData(), ...(ngDevMode ? [{ debugName: "editMode" }] : []));
688
+ buttonLabel = computed(() => this.editMode()
689
+ ? this.transloco.translate('lookups.Update')
690
+ : this.transloco.translate('lookups.Create'), ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
691
+ lookupItemFormConfig = signal({
692
+ sections: [
693
+ {
694
+ key: 'lookupItemFormConfig',
695
+ type: 'header',
696
+ order: 1,
697
+ fields: [
698
+ {
699
+ key: 'nameEn',
700
+ label: this.transloco.translate('lookups.EnglishName'),
701
+ placeholder: this.transloco.translate('lookups.EnglishName'),
702
+ validators: [ValidatorConfig.required()],
703
+ order: 2,
704
+ },
705
+ {
706
+ key: 'nameAr',
707
+ label: this.transloco.translate('lookups.ArabicName'),
708
+ placeholder: this.transloco.translate('lookups.ArabicName'),
709
+ validators: [ValidatorConfig.required()],
710
+ order: 3,
711
+ },
712
+ new ColorPickerFieldConfig({
713
+ key: 'color',
714
+ label: this.transloco.translate('lookups.Color'),
715
+ placeholder: this.transloco.translate('lookups.Color'),
716
+ required: true,
717
+ validators: [ValidatorConfig.required()],
718
+ order: 4,
719
+ }),
720
+ ],
721
+ },
722
+ ],
723
+ }, ...(ngDevMode ? [{ debugName: "lookupItemFormConfig" }] : []));
724
+ lookupItemFormControl = new FormControl({
725
+ color: '#000000',
726
+ });
727
+ ngOnInit() {
728
+ if (this.editMode() && this.itemData()) {
729
+ const item = this.itemData();
730
+ this.lookupItemFormControl.setValue({
731
+ nameEn: item.name.en,
732
+ nameAr: item.name.ar,
733
+ color: item?.color || '#000000',
734
+ });
735
+ this.lookupItemFormControl.markAsTouched();
736
+ this.lookupItemFormControl.updateValueAndValidity();
737
+ }
738
+ }
739
+ getLookupItemById(id) {
740
+ this.facade.loadOne(id).subscribe(() => { });
741
+ }
742
+ onSubmit() {
743
+ const isSubmitting = this.editMode()
744
+ ? this.facade.isUpdatingLookupItem()
745
+ : this.facade.isAddingLookupItem();
746
+ if (this.lookupItemFormControl.valid && !isSubmitting) {
747
+ const formValue = this.lookupItemFormControl.value;
748
+ if (this.editMode() && this.itemData()) {
749
+ const lookupItemId = this.itemData().id;
750
+ const updatePayload = {
751
+ name: {
752
+ en: formValue.nameEn,
753
+ ar: formValue.nameAr,
754
+ },
755
+ color: formValue.color,
756
+ };
757
+ this.facade
758
+ .updateItem(this.lookupId(), lookupItemId, updatePayload)
759
+ .subscribe({
760
+ next: (response) => {
761
+ this.ref.close({ success: true, data: response });
762
+ },
763
+ error: () => { },
764
+ });
765
+ }
766
+ else {
767
+ const createPayload = {
768
+ lookupId: this.lookupId(),
769
+ name: {
770
+ en: formValue.nameEn,
771
+ ar: formValue.nameAr,
772
+ },
773
+ color: formValue.color,
774
+ };
775
+ this.facade.createItem(this.lookupId(), createPayload).subscribe({
776
+ next: (response) => {
777
+ this.ref.close({ success: true, data: response });
778
+ },
779
+ error: () => { },
780
+ });
781
+ }
782
+ }
783
+ }
784
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupItemForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
785
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: LookupItemForm, isStandalone: true, selector: "mt-lookup-item-form", inputs: { itemData: { classPropertyName: "itemData", publicName: "itemData", isSignal: true, isRequired: false, transformFunction: null }, lookupId: { classPropertyName: "lookupId", publicName: "lookupId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [class]=\"'flex flex-col gap-1 p-4 my-4' + modal.contentClass\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"lookupItemFormConfig()\"\r\n [formControl]=\"lookupItemFormControl\"\r\n />\r\n </form>\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass\" class=\"mt-7\">\r\n <mt-button\r\n [label]=\"buttonLabel()\"\r\n (click)=\"onSubmit()\"\r\n [loading]=\"\r\n editMode() ? facade.isUpdatingLookupItem() : facade.isAddingLookupItem()\r\n \"\r\n [disabled]=\"\r\n !lookupItemFormControl.valid ||\r\n (editMode() ? facade.isUpdatingLookupItem() : facade.isAddingLookupItem())\r\n \"\r\n />\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
786
+ }
787
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupItemForm, decorators: [{
788
+ type: Component,
789
+ args: [{ selector: 'mt-lookup-item-form', imports: [CommonModule, Button, DynamicForm, ReactiveFormsModule], template: "<div [class]=\"'flex flex-col gap-1 p-4 my-4' + modal.contentClass\">\r\n <form class=\"col-span-1\">\r\n <mt-dynamic-form\r\n [formConfig]=\"lookupItemFormConfig()\"\r\n [formControl]=\"lookupItemFormControl\"\r\n />\r\n </form>\r\n</div>\r\n\r\n<div [class]=\"modal.footerClass\" class=\"mt-7\">\r\n <mt-button\r\n [label]=\"buttonLabel()\"\r\n (click)=\"onSubmit()\"\r\n [loading]=\"\r\n editMode() ? facade.isUpdatingLookupItem() : facade.isAddingLookupItem()\r\n \"\r\n [disabled]=\"\r\n !lookupItemFormControl.valid ||\r\n (editMode() ? facade.isUpdatingLookupItem() : facade.isAddingLookupItem())\r\n \"\r\n />\r\n</div>\r\n" }]
790
+ }], propDecorators: { itemData: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemData", required: false }] }], lookupId: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookupId", required: false }] }] } });
791
+
792
+ class LookupDetails {
793
+ statusCol = viewChild.required('statusCol');
794
+ router = inject(Router);
795
+ facade = inject(LookupsFacade);
796
+ route = inject(ActivatedRoute);
797
+ avatarStyle = {
798
+ '--p-avatar-background': '#E0F2FE',
799
+ '--p-avatar-color': '#0086C9',
800
+ };
801
+ fb = inject(FormBuilder);
802
+ modal = inject(ModalService);
803
+ transloco = inject(TranslocoService);
804
+ isEditMode = signal(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
805
+ id = computed(() => {
806
+ const idParam = this.route.snapshot.paramMap.get('id');
807
+ return idParam ? idParam : '';
808
+ }, ...(ngDevMode ? [{ debugName: "id" }] : []));
809
+ lookupItems = computed(() => this.facade.selectedLookup()?.items || [], ...(ngDevMode ? [{ debugName: "lookupItems" }] : []));
810
+ allowManage = computed(() => this.facade.selectedLookup()?.allowManage, ...(ngDevMode ? [{ debugName: "allowManage" }] : []));
811
+ allowDelete = computed(() => this.facade.selectedLookup()?.allowDelete, ...(ngDevMode ? [{ debugName: "allowDelete" }] : []));
812
+ deletingRowIds = signal([], ...(ngDevMode ? [{ debugName: "deletingRowIds" }] : []));
813
+ rowActions = computed(() => {
814
+ const actions = [];
815
+ if (this.allowManage()) {
816
+ actions.push({
817
+ icon: 'custom.pencil',
818
+ tooltip: this.transloco.translate('lookups.Edit'),
819
+ color: 'primary',
820
+ action: (row) => {
821
+ this.addEditItemDialog(row);
822
+ },
823
+ });
824
+ }
825
+ if (this.allowDelete()) {
826
+ actions.push({
827
+ icon: 'general.trash-01',
828
+ tooltip: this.transloco.translate('lookups.Delete'),
829
+ color: 'danger',
830
+ variant: 'outlined',
831
+ action: (row) => {
832
+ this.deletingRowIds.update((ids) => [...ids, row.id]);
833
+ this.facade
834
+ .deleteItem(this.id(), row.id)
835
+ .pipe(finalize(() => {
836
+ this.deletingRowIds.update((ids) => ids.filter((id) => id !== row.id));
837
+ }))
838
+ .subscribe({
839
+ error: () => { },
840
+ });
841
+ },
842
+ confirmation: {
843
+ type: 'popup',
844
+ confirmationType: 'delete',
845
+ },
846
+ loading: (row) => this.deletingRowIds().includes(row.id),
847
+ });
848
+ }
849
+ return actions;
850
+ }, ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
851
+ lookupForm = this.fb.group({
852
+ nameAr: [''],
853
+ nameEn: [''],
854
+ });
855
+ tableColumns = linkedSignal(() => [
856
+ {
857
+ key: 'name.en',
858
+ label: this.transloco.translate('lookups.EnglishTitle'),
859
+ },
860
+ {
861
+ key: 'name.ar',
862
+ label: this.transloco.translate('lookups.ArabicTitle'),
863
+ },
864
+ {
865
+ key: 'color',
866
+ label: this.transloco.translate('lookups.StatusColor'),
867
+ type: 'custom',
868
+ customCellTpl: this.statusCol(),
869
+ },
870
+ ], ...(ngDevMode ? [{ debugName: "tableColumns" }] : []));
871
+ ngOnInit() {
872
+ this.loadLookupData();
873
+ }
874
+ loadLookupData() {
875
+ this.facade.loadOne(this.id(), 'edit').subscribe({
876
+ next: () => {
877
+ const selected = this.facade.selectedLookup();
878
+ if (selected) {
879
+ this.lookupForm.patchValue({
880
+ nameAr: selected.name?.ar || '',
881
+ nameEn: selected.name?.en || '',
882
+ });
883
+ }
884
+ },
885
+ error: () => { },
886
+ });
887
+ }
888
+ goBack() {
889
+ this.router.navigate(['..'], { relativeTo: this.route });
890
+ }
891
+ addEditItemDialog(lookupItem = null) {
892
+ this.modal.openModal(LookupItemForm, 'dialog', {
893
+ header: lookupItem
894
+ ? this.transloco.translate('lookups.Edit_Item')
895
+ : this.transloco.translate('lookups.Create_New_Item'),
896
+ styleClass: '!w-[40vw] ',
897
+ height: 'auto',
898
+ appendTo: 'body',
899
+ dismissableMask: true,
900
+ inputValues: {
901
+ lookupId: this.id(),
902
+ itemData: lookupItem,
903
+ },
904
+ });
905
+ }
906
+ enableEdit() {
907
+ this.isEditMode.set(true);
908
+ }
909
+ cancelEdit() {
910
+ this.isEditMode.set(false);
911
+ const selected = this.facade.selectedLookup();
912
+ if (selected) {
913
+ this.lookupForm.patchValue({
914
+ nameAr: selected.name?.ar || '',
915
+ nameEn: selected.name?.en || '',
916
+ });
917
+ }
918
+ }
919
+ saveLookup() {
920
+ if (this.lookupForm.valid && !this.facade.isUpdatingLookup()) {
921
+ const updatePayload = {
922
+ id: Number(this.id()),
923
+ name: {
924
+ ar: this.lookupForm.value.nameAr || '',
925
+ en: this.lookupForm.value.nameEn || '',
926
+ },
927
+ };
928
+ this.facade.update(updatePayload).subscribe({
929
+ next: () => {
930
+ this.isEditMode.set(false);
931
+ },
932
+ error: () => { },
933
+ });
934
+ }
935
+ }
936
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupDetails, deps: [], target: i0.ɵɵFactoryTarget.Component });
937
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: LookupDetails, isStandalone: true, selector: "mt-lookups-details", viewQueries: [{ propertyName: "statusCol", first: true, predicate: ["statusCol"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t\">\r\n <mt-page\r\n [title]=\"t('lookups.Product_Status')\"\r\n [avatarIcon]=\"'file.file-plus-02'\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-yellow-100)',\r\n '--p-avatar-color': 'var(--p-yellow-700)',\r\n }\"\r\n [avatarStyle]=\"avatarStyle\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n >\r\n <div class=\"flex flex-col gap-4 m-auto w-1/2 max-w-2/3 min-w-md mt-7\">\r\n @if (facade.isLoadingLookupById()) {\r\n <div class=\"p-5\">\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"10rem\"\r\n styleClass=\"mb-5\"\r\n ></p-skeleton>\r\n <p-skeleton width=\"100%\" height=\"20rem\"></p-skeleton>\r\n </div>\r\n } @else {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex justify-between align-center border-b px-4 py-5 border-surface\"\r\n >\r\n <div class=\"flex items-center justify-between\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ t(\"lookups.Information\") }}\r\n </h3>\r\n </div>\r\n @if (allowManage() && !isEditMode()) {\r\n <mt-button\r\n label=\"{{ t('lookups.Edit') }}\"\r\n size=\"small\"\r\n (click)=\"enableEdit()\"\r\n ></mt-button>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-wrap gap-10\">\r\n <form class=\"flex size-full gap-4 p-5\" [formGroup]=\"lookupForm\">\r\n <div class=\"flex-1\">\r\n <mt-text-field\r\n [label]=\"t('lookups.EnglishName')\"\r\n formControlName=\"nameEn\"\r\n [readonly]=\"!isEditMode()\"\r\n ></mt-text-field>\r\n </div>\r\n <div class=\"flex-1\">\r\n <mt-text-field\r\n [label]=\"t('lookups.ArabicName')\"\r\n formControlName=\"nameAr\"\r\n [readonly]=\"!isEditMode()\"\r\n ></mt-text-field>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n @if (isEditMode()) {\r\n <div class=\"actions flex gap-3 px-5 pb-5 justify-end\">\r\n <mt-button\r\n label=\"{{ t('lookups.Save') }}\"\r\n [loading]=\"facade.isUpdatingLookup()\"\r\n [disabled]=\"!lookupForm.valid || facade.isUpdatingLookup()\"\r\n (click)=\"saveLookup()\"\r\n ></mt-button>\r\n <mt-button\r\n label=\"{{ t('lookups.Cancel') }}\"\r\n [outlined]=\"true\"\r\n [disabled]=\"facade.isUpdatingLookup()\"\r\n (click)=\"cancelEdit()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-card>\r\n @if (lookupItems().length > 0) {\r\n <mt-card class=\"mt-4\">\r\n <ng-template #headless>\r\n <div\r\n class=\"flex justify-between align-center border-b px-4 py-5 border-surface\"\r\n >\r\n <div class=\"flex items-center justify-between\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ t(\"lookups.Items_List\") }}\r\n </h3>\r\n </div>\r\n @if (allowManage()) {\r\n <mt-button\r\n icon=\"general.plus\"\r\n label=\"{{ t('lookups.Create_New_Item') }}\"\r\n (click)=\"addEditItemDialog()\"\r\n ></mt-button>\r\n }\r\n </div>\r\n\r\n <mt-table\r\n [data]=\"lookupItems()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n ></mt-table>\r\n <ng-template #statusCol let-row>\r\n <div\r\n class=\"border-circle\"\r\n [style.background-color]=\"row?.color || row.color\"\r\n [style]=\"'width: 1.5rem; height: 1.5rem; border-radius: 50%;'\"\r\n ></div>\r\n </ng-template>\r\n </ng-template>\r\n </mt-card>\r\n } @else {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex justify-between align-center border-b px-4 py-5 border-surface\"\r\n >\r\n <div class=\"flex items-center justify-between\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ t(\"lookups.Items_List\") }}\r\n </h3>\r\n </div>\r\n </div>\r\n <div class=\"p-8\">\r\n <div\r\n class=\"content flex flex-col gap-5 items-center text-center p-8 border-dashed border-2 border-(--p-content-border-color)\"\r\n >\r\n <mt-avatar\r\n style=\"\r\n --p-avatar-background: #d7f5f6;\r\n --p-avatar-color: #2aaec0;\r\n \"\r\n [icon]=\"'editor.dotpoints-01'\"\r\n size=\"large\"\r\n shape=\"square\"\r\n ></mt-avatar>\r\n\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"title text-lg font-semibold\">\r\n {{ t(\"lookups.add_items_title\") }}\r\n </div>\r\n\r\n <div\r\n class=\"description text-sm text-muted-foreground secondary text-surface-500\"\r\n >\r\n {{ t(\"lookups.add_items_description\") }}\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n label=\"{{ t('lookups.Create_New_Item') }}\"\r\n (click)=\"addEditItemDialog()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </mt-page>\r\n</ng-container>\r\n", styles: [""], dependencies: [{ kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }] });
938
+ }
939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupDetails, decorators: [{
940
+ type: Component,
941
+ args: [{ selector: 'mt-lookups-details', imports: [
942
+ Button,
943
+ Card,
944
+ ReactiveFormsModule,
945
+ FormsModule,
946
+ TextField,
947
+ Table,
948
+ Avatar,
949
+ SkeletonModule,
950
+ TranslocoDirective,
951
+ Page,
952
+ ], template: "<ng-container *transloco=\"let t\">\r\n <mt-page\r\n [title]=\"t('lookups.Product_Status')\"\r\n [avatarIcon]=\"'file.file-plus-02'\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-yellow-100)',\r\n '--p-avatar-color': 'var(--p-yellow-700)',\r\n }\"\r\n [avatarStyle]=\"avatarStyle\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n >\r\n <div class=\"flex flex-col gap-4 m-auto w-1/2 max-w-2/3 min-w-md mt-7\">\r\n @if (facade.isLoadingLookupById()) {\r\n <div class=\"p-5\">\r\n <p-skeleton\r\n width=\"100%\"\r\n height=\"10rem\"\r\n styleClass=\"mb-5\"\r\n ></p-skeleton>\r\n <p-skeleton width=\"100%\" height=\"20rem\"></p-skeleton>\r\n </div>\r\n } @else {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex justify-between align-center border-b px-4 py-5 border-surface\"\r\n >\r\n <div class=\"flex items-center justify-between\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ t(\"lookups.Information\") }}\r\n </h3>\r\n </div>\r\n @if (allowManage() && !isEditMode()) {\r\n <mt-button\r\n label=\"{{ t('lookups.Edit') }}\"\r\n size=\"small\"\r\n (click)=\"enableEdit()\"\r\n ></mt-button>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-wrap gap-10\">\r\n <form class=\"flex size-full gap-4 p-5\" [formGroup]=\"lookupForm\">\r\n <div class=\"flex-1\">\r\n <mt-text-field\r\n [label]=\"t('lookups.EnglishName')\"\r\n formControlName=\"nameEn\"\r\n [readonly]=\"!isEditMode()\"\r\n ></mt-text-field>\r\n </div>\r\n <div class=\"flex-1\">\r\n <mt-text-field\r\n [label]=\"t('lookups.ArabicName')\"\r\n formControlName=\"nameAr\"\r\n [readonly]=\"!isEditMode()\"\r\n ></mt-text-field>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n @if (isEditMode()) {\r\n <div class=\"actions flex gap-3 px-5 pb-5 justify-end\">\r\n <mt-button\r\n label=\"{{ t('lookups.Save') }}\"\r\n [loading]=\"facade.isUpdatingLookup()\"\r\n [disabled]=\"!lookupForm.valid || facade.isUpdatingLookup()\"\r\n (click)=\"saveLookup()\"\r\n ></mt-button>\r\n <mt-button\r\n label=\"{{ t('lookups.Cancel') }}\"\r\n [outlined]=\"true\"\r\n [disabled]=\"facade.isUpdatingLookup()\"\r\n (click)=\"cancelEdit()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-card>\r\n @if (lookupItems().length > 0) {\r\n <mt-card class=\"mt-4\">\r\n <ng-template #headless>\r\n <div\r\n class=\"flex justify-between align-center border-b px-4 py-5 border-surface\"\r\n >\r\n <div class=\"flex items-center justify-between\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ t(\"lookups.Items_List\") }}\r\n </h3>\r\n </div>\r\n @if (allowManage()) {\r\n <mt-button\r\n icon=\"general.plus\"\r\n label=\"{{ t('lookups.Create_New_Item') }}\"\r\n (click)=\"addEditItemDialog()\"\r\n ></mt-button>\r\n }\r\n </div>\r\n\r\n <mt-table\r\n [data]=\"lookupItems()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n ></mt-table>\r\n <ng-template #statusCol let-row>\r\n <div\r\n class=\"border-circle\"\r\n [style.background-color]=\"row?.color || row.color\"\r\n [style]=\"'width: 1.5rem; height: 1.5rem; border-radius: 50%;'\"\r\n ></div>\r\n </ng-template>\r\n </ng-template>\r\n </mt-card>\r\n } @else {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex justify-between align-center border-b px-4 py-5 border-surface\"\r\n >\r\n <div class=\"flex items-center justify-between\">\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ t(\"lookups.Items_List\") }}\r\n </h3>\r\n </div>\r\n </div>\r\n <div class=\"p-8\">\r\n <div\r\n class=\"content flex flex-col gap-5 items-center text-center p-8 border-dashed border-2 border-(--p-content-border-color)\"\r\n >\r\n <mt-avatar\r\n style=\"\r\n --p-avatar-background: #d7f5f6;\r\n --p-avatar-color: #2aaec0;\r\n \"\r\n [icon]=\"'editor.dotpoints-01'\"\r\n size=\"large\"\r\n shape=\"square\"\r\n ></mt-avatar>\r\n\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"title text-lg font-semibold\">\r\n {{ t(\"lookups.add_items_title\") }}\r\n </div>\r\n\r\n <div\r\n class=\"description text-sm text-muted-foreground secondary text-surface-500\"\r\n >\r\n {{ t(\"lookups.add_items_description\") }}\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <mt-button\r\n icon=\"general.plus\"\r\n label=\"{{ t('lookups.Create_New_Item') }}\"\r\n (click)=\"addEditItemDialog()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </mt-page>\r\n</ng-container>\r\n" }]
953
+ }], propDecorators: { statusCol: [{ type: i0.ViewChild, args: ['statusCol', { isSignal: true }] }] } });
954
+
955
+ class LookupsCustom {
956
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsCustom, deps: [], target: i0.ɵɵFactoryTarget.Component });
957
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LookupsCustom, isStandalone: true, selector: "mt-lookups-custom", ngImport: i0, template: "<p>lookups-custom works!</p>\r\n", styles: [""] });
958
+ }
959
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupsCustom, decorators: [{
960
+ type: Component,
961
+ args: [{ selector: 'mt-lookups-custom', imports: [], template: "<p>lookups-custom works!</p>\r\n" }]
962
+ }] });
963
+
964
+ // store/index.ts
965
+
966
+ /**
967
+ * Generated bundle index. Do not edit.
968
+ */
969
+
970
+ export { CreateLookup, CreateLookupItem, DeleteLookup, DeleteLookupItem, GetLookup, GetLookups, LookupDetails, LookupForm, LookupItemForm, Lookups, LookupsActionKey, LookupsCustom, LookupsFacade, LookupsList, LookupsState, UpdateLookup, UpdateLookupItem };
971
+ //# sourceMappingURL=masterteam-lookups.mjs.map