@elasticias/screens 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/fesm2022/elasticias-screens.mjs +844 -0
- package/fesm2022/elasticias-screens.mjs.map +1 -0
- package/package.json +39 -0
- package/types/elasticias-screens.d.ts +299 -0
package/README.md
ADDED
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Input, Component, signal, InjectionToken, inject, ChangeDetectorRef, ViewChild, Injector } from '@angular/core';
|
|
3
|
+
import { Subject, combineLatest, take } from 'rxjs';
|
|
4
|
+
import { PermissionsEnum } from '@elasticias/types';
|
|
5
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
6
|
+
import { StorageUtils, AppUtils } from '@elasticias/utils';
|
|
7
|
+
import { CacheService, ToastService, ConfirmDialogService } from '@elasticias/core';
|
|
8
|
+
import { Location } from '@angular/common';
|
|
9
|
+
|
|
10
|
+
class AbstractEntity {
|
|
11
|
+
clone(entity) {
|
|
12
|
+
for (const field of Reflect.ownKeys(entity)) {
|
|
13
|
+
if (this[field] == null) {
|
|
14
|
+
this[field] = entity[field];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
newClone() {
|
|
20
|
+
const cloneObj = {};
|
|
21
|
+
for (const field of Reflect.ownKeys(this)) {
|
|
22
|
+
cloneObj[field] = this[field];
|
|
23
|
+
}
|
|
24
|
+
return cloneObj;
|
|
25
|
+
}
|
|
26
|
+
update(entity) {
|
|
27
|
+
for (const field of Reflect.ownKeys(entity)) {
|
|
28
|
+
if (this[field] != null) {
|
|
29
|
+
this[field] = entity[field];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
buildEntity(entity) {
|
|
35
|
+
Object.keys(entity).forEach((key) => {
|
|
36
|
+
this[key] = entity[key];
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
clearFields() {
|
|
40
|
+
for (const field of Reflect.ownKeys(this)) {
|
|
41
|
+
this[field] = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class AbstractComponent {
|
|
47
|
+
readOnly = false;
|
|
48
|
+
destroyed$ = new Subject();
|
|
49
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
50
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: AbstractComponent, isStandalone: true, selector: "ng-component", inputs: { readOnly: "readOnly" }, ngImport: i0, template: '', isInline: true });
|
|
51
|
+
}
|
|
52
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractComponent, decorators: [{
|
|
53
|
+
type: Component,
|
|
54
|
+
args: [{ template: '' }]
|
|
55
|
+
}], propDecorators: { readOnly: [{
|
|
56
|
+
type: Input
|
|
57
|
+
}] } });
|
|
58
|
+
|
|
59
|
+
class ScreenContext extends AbstractEntity {
|
|
60
|
+
state;
|
|
61
|
+
screenName;
|
|
62
|
+
language;
|
|
63
|
+
group;
|
|
64
|
+
_refDataProvider;
|
|
65
|
+
bundles;
|
|
66
|
+
entity;
|
|
67
|
+
grants;
|
|
68
|
+
duplicateMode = false;
|
|
69
|
+
constructor(state, group, entity, refDataProvider, bundles, grants, screenName = '', language = 'fr') {
|
|
70
|
+
super();
|
|
71
|
+
this.state = state;
|
|
72
|
+
this.group = group;
|
|
73
|
+
this.entity = entity;
|
|
74
|
+
this.screenName = screenName;
|
|
75
|
+
this.language = language;
|
|
76
|
+
this._refDataProvider = refDataProvider;
|
|
77
|
+
this.bundles = bundles ?? new Map();
|
|
78
|
+
this.grants = grants ?? [];
|
|
79
|
+
}
|
|
80
|
+
setReferenceDataProvider(provider) {
|
|
81
|
+
this._refDataProvider = provider;
|
|
82
|
+
}
|
|
83
|
+
get ref() {
|
|
84
|
+
return {
|
|
85
|
+
get: (key) => {
|
|
86
|
+
if (!this._refDataProvider) {
|
|
87
|
+
console.warn('ReferenceDataProvider not set in ScreenContext. Returning empty signal.');
|
|
88
|
+
return signal([]);
|
|
89
|
+
}
|
|
90
|
+
return this._refDataProvider.getReference(key);
|
|
91
|
+
},
|
|
92
|
+
has: (key) => {
|
|
93
|
+
return this._refDataProvider?.hasReference(key) ?? false;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
getLabel(key) {
|
|
98
|
+
try {
|
|
99
|
+
return this.bundles.get(this.language).get(this.screenName).get(key) ?? key;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return key;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
isGranted(permission) {
|
|
106
|
+
return this.grants?.some((value) => value === permission) ?? false;
|
|
107
|
+
}
|
|
108
|
+
isReadOnly() {
|
|
109
|
+
return (this.isGranted(PermissionsEnum.Read) &&
|
|
110
|
+
!this.isGranted(PermissionsEnum.Write) &&
|
|
111
|
+
!this.isGranted(PermissionsEnum.Edit) &&
|
|
112
|
+
!this.isGranted(PermissionsEnum.Delete));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Injection token for the screen reference data service.
|
|
118
|
+
* Apps must provide this token with their concrete implementation.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* // In app module or component providers:
|
|
122
|
+
* { provide: SCREEN_REF_DATA_SERVICE, useExisting: ReferenceDataService }
|
|
123
|
+
*/
|
|
124
|
+
const SCREEN_REF_DATA_SERVICE = new InjectionToken('SCREEN_REF_DATA_SERVICE');
|
|
125
|
+
|
|
126
|
+
class AbstractScreenComponent extends AbstractComponent {
|
|
127
|
+
context;
|
|
128
|
+
connectedUser;
|
|
129
|
+
entityForm;
|
|
130
|
+
serverErrors = signal({}, ...(ngDevMode ? [{ debugName: "serverErrors" }] : /* istanbul ignore next */ []));
|
|
131
|
+
refDataLoaded$ = new Subject();
|
|
132
|
+
cacheService = inject(CacheService);
|
|
133
|
+
changeDetector = inject(ChangeDetectorRef);
|
|
134
|
+
toastService = inject(ToastService);
|
|
135
|
+
confirmDialogService = inject(ConfirmDialogService);
|
|
136
|
+
router = inject(Router);
|
|
137
|
+
route = inject(ActivatedRoute);
|
|
138
|
+
refDataService = inject(SCREEN_REF_DATA_SERVICE);
|
|
139
|
+
currentUrl = '';
|
|
140
|
+
get state() { return this.screenState; }
|
|
141
|
+
screenStateKey = '';
|
|
142
|
+
ngOnInit() {
|
|
143
|
+
this.cacheService.configure(true);
|
|
144
|
+
this.currentUrl = this.router.url;
|
|
145
|
+
this.context = new ScreenContext(this.screenState ?? '', undefined, undefined, this.refDataService);
|
|
146
|
+
this.screenStateKey = `SCREEN_STATE_${this.screenState}_${this.getBundleName()}`;
|
|
147
|
+
this.context.screenName = this.getBundleName();
|
|
148
|
+
this.processGrants();
|
|
149
|
+
}
|
|
150
|
+
ngAfterViewInit() {
|
|
151
|
+
this.changeDetector.detectChanges();
|
|
152
|
+
if (this.context && this.context.isReadOnly()) {
|
|
153
|
+
this.disableAllControls();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
processGrants() {
|
|
157
|
+
const userGrants = StorageUtils.getSession('CURRENT_USER_GRANTS');
|
|
158
|
+
if (userGrants && userGrants[this.context.screenName] && userGrants[this.context.screenName].permissions) {
|
|
159
|
+
this.context.grants = userGrants[this.context.screenName].permissions;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
this.context.grants = [];
|
|
163
|
+
}
|
|
164
|
+
this.changeDetector.detectChanges();
|
|
165
|
+
}
|
|
166
|
+
isFormValid() {
|
|
167
|
+
if (this.context.isReadOnly()) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
if (!this.entityForm) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
return this.entityForm.valid ?? false;
|
|
174
|
+
}
|
|
175
|
+
getConfig() {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
getBundleName() {
|
|
179
|
+
const config = this.getConfig();
|
|
180
|
+
if (config) {
|
|
181
|
+
return config.SCREEN;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.error('getConfig() method should be implemented !!');
|
|
185
|
+
}
|
|
186
|
+
return '';
|
|
187
|
+
}
|
|
188
|
+
setFormErrors(errors) {
|
|
189
|
+
if (!errors || !this.entityForm) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
Object.keys(errors).forEach((field) => {
|
|
193
|
+
const camelCaseField = AppUtils.toCamelCase(field);
|
|
194
|
+
const control = this.entityForm.controls[camelCaseField];
|
|
195
|
+
if (control) {
|
|
196
|
+
control.setErrors({ serverError: errors[field] });
|
|
197
|
+
control.markAsTouched();
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
referentialKeys;
|
|
202
|
+
staticListKeys = [];
|
|
203
|
+
initializeReferenceKeys(keys) {
|
|
204
|
+
if (!keys)
|
|
205
|
+
return;
|
|
206
|
+
const referencialKeys = {};
|
|
207
|
+
keys.forEach(p => {
|
|
208
|
+
referencialKeys[p] = {};
|
|
209
|
+
});
|
|
210
|
+
this.referentialKeys = referencialKeys;
|
|
211
|
+
}
|
|
212
|
+
initializeStaticLists(keys) {
|
|
213
|
+
if (!keys)
|
|
214
|
+
return;
|
|
215
|
+
this.staticListKeys = keys;
|
|
216
|
+
}
|
|
217
|
+
async loadReferenceData(options) {
|
|
218
|
+
const loadPromises = [];
|
|
219
|
+
if (!AppUtils.isNullOrEmpty(this.referentialKeys)) {
|
|
220
|
+
const dynamicKeys = Object.keys(this.referentialKeys);
|
|
221
|
+
const dynamicPromise = this.refDataService
|
|
222
|
+
.loadReferenceKeys(dynamicKeys, options)
|
|
223
|
+
.catch((error) => {
|
|
224
|
+
console.error('Failed to load dynamic reference data:', error);
|
|
225
|
+
});
|
|
226
|
+
loadPromises.push(dynamicPromise);
|
|
227
|
+
}
|
|
228
|
+
if (this.staticListKeys && this.staticListKeys.length > 0) {
|
|
229
|
+
const staticPromise = this.refDataService
|
|
230
|
+
.loadStaticRefs(this.staticListKeys)
|
|
231
|
+
.catch((error) => {
|
|
232
|
+
console.error('Failed to load static lists:', error);
|
|
233
|
+
});
|
|
234
|
+
loadPromises.push(staticPromise);
|
|
235
|
+
}
|
|
236
|
+
if (loadPromises.length === 0) {
|
|
237
|
+
this.refDataLoaded$.next();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
await Promise.all(loadPromises);
|
|
242
|
+
this.refDataLoaded$.next();
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
console.error('Failed to load reference data:', error);
|
|
246
|
+
this.refDataLoaded$.next();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async refreshReferenceData(keys) {
|
|
250
|
+
const keysToRefresh = keys || Object.keys(this.referentialKeys || {});
|
|
251
|
+
if (keysToRefresh.length === 0) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
await this.refDataService.refreshKeys(keysToRefresh, true);
|
|
256
|
+
this.toastService.showSuccess('Reference data refreshed successfully', 'Success');
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
console.error('Failed to refresh reference data:', error);
|
|
260
|
+
this.toastService.showError('Failed to refresh reference data', 'Error');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async refreshStaticLists() {
|
|
264
|
+
if (!this.staticListKeys || this.staticListKeys.length === 0) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
await this.refDataService.loadStaticRefs(this.staticListKeys, true);
|
|
269
|
+
this.toastService.showSuccess('Static lists refreshed successfully', 'Success');
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
console.error('Failed to refresh static lists:', error);
|
|
273
|
+
this.toastService.showError('Failed to refresh static lists', 'Error');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async invalidateReference(key) {
|
|
277
|
+
await this.refDataService.invalidateKeys([key]);
|
|
278
|
+
}
|
|
279
|
+
async invalidateReferences(keys) {
|
|
280
|
+
await this.refDataService.invalidateKeys(keys);
|
|
281
|
+
}
|
|
282
|
+
handleErrors(errors) {
|
|
283
|
+
if (errors && errors.length > 0) {
|
|
284
|
+
errors.forEach(error => this.toastService.showError(error, 'Erreur de validation'));
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this.toastService.showError('Une erreur inconnue est survenue', 'Erreur');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
setServerErrors(errors) {
|
|
291
|
+
this.serverErrors.set(errors || {});
|
|
292
|
+
}
|
|
293
|
+
clearServerErrors() {
|
|
294
|
+
this.serverErrors.set({});
|
|
295
|
+
}
|
|
296
|
+
disableAllControls() {
|
|
297
|
+
setTimeout(() => {
|
|
298
|
+
if (this.entityForm && Object.keys(this.entityForm.controls).length > 0) {
|
|
299
|
+
const controlNames = Object.keys(this.entityForm.controls);
|
|
300
|
+
controlNames.forEach(controlName => {
|
|
301
|
+
const control = this.entityForm.controls[controlName];
|
|
302
|
+
if (control) {
|
|
303
|
+
control.disable();
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}, 10);
|
|
308
|
+
}
|
|
309
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractScreenComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
310
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: AbstractScreenComponent, isStandalone: true, selector: "ng-component", inputs: { context: "context" }, viewQueries: [{ propertyName: "entityForm", first: true, predicate: ["entityForm"], descendants: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
311
|
+
}
|
|
312
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractScreenComponent, decorators: [{
|
|
313
|
+
type: Component,
|
|
314
|
+
args: [{
|
|
315
|
+
template: ''
|
|
316
|
+
}]
|
|
317
|
+
}], propDecorators: { context: [{
|
|
318
|
+
type: Input
|
|
319
|
+
}], entityForm: [{
|
|
320
|
+
type: ViewChild,
|
|
321
|
+
args: ['entityForm']
|
|
322
|
+
}] } });
|
|
323
|
+
|
|
324
|
+
var ScreenStateEnum;
|
|
325
|
+
(function (ScreenStateEnum) {
|
|
326
|
+
ScreenStateEnum["READ_ONLY"] = "READ_ONLY";
|
|
327
|
+
ScreenStateEnum["DETAIL"] = "DETAIL";
|
|
328
|
+
ScreenStateEnum["SEARCH"] = "SEARCH";
|
|
329
|
+
ScreenStateEnum["CUSTOM"] = "CUSTOM";
|
|
330
|
+
})(ScreenStateEnum || (ScreenStateEnum = {}));
|
|
331
|
+
var StateUtilsEnum;
|
|
332
|
+
(function (StateUtilsEnum) {
|
|
333
|
+
StateUtilsEnum["REMOVE"] = "removeState";
|
|
334
|
+
StateUtilsEnum["ADD"] = "addState";
|
|
335
|
+
StateUtilsEnum["DUPLICATE"] = "duplicateState";
|
|
336
|
+
StateUtilsEnum["EDIT"] = "editState";
|
|
337
|
+
StateUtilsEnum["EDIT_AFTER_ERROR"] = "editAfterErrorState";
|
|
338
|
+
StateUtilsEnum["ADD_AFTER_ERROR"] = "addAfterErrorState";
|
|
339
|
+
StateUtilsEnum["SAVE"] = "afterSaveState";
|
|
340
|
+
})(StateUtilsEnum || (StateUtilsEnum = {}));
|
|
341
|
+
|
|
342
|
+
class ViewModelEntity extends AbstractEntity {
|
|
343
|
+
constructor(entity) {
|
|
344
|
+
super();
|
|
345
|
+
this.clone(entity);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
class AbstractDetailScreenComponent extends AbstractScreenComponent {
|
|
350
|
+
screenState = ScreenStateEnum.DETAIL;
|
|
351
|
+
entity = {};
|
|
352
|
+
entityId;
|
|
353
|
+
editionState = false;
|
|
354
|
+
duplicateMode = false;
|
|
355
|
+
location = inject(Location);
|
|
356
|
+
injector = inject(Injector);
|
|
357
|
+
serviceInstance;
|
|
358
|
+
ngOnInit() {
|
|
359
|
+
super.ngOnInit();
|
|
360
|
+
this.serviceInstance = this.injector.get(this.getConfig().SERVICE);
|
|
361
|
+
const screenConfig = this.getConfig();
|
|
362
|
+
if (screenConfig) {
|
|
363
|
+
const hasDynamicRefs = (screenConfig.DETAILS_REFERENTIALS_KEYS?.length ?? 0) > 0;
|
|
364
|
+
const hasStaticLists = (screenConfig.DETAILS_STATIC_LISTS?.length ?? 0) > 0;
|
|
365
|
+
if (hasDynamicRefs) {
|
|
366
|
+
this.initializeReferenceKeys(screenConfig.DETAILS_REFERENTIALS_KEYS);
|
|
367
|
+
}
|
|
368
|
+
if (hasStaticLists) {
|
|
369
|
+
this.initializeStaticLists(screenConfig.DETAILS_STATIC_LISTS);
|
|
370
|
+
}
|
|
371
|
+
if (hasDynamicRefs || hasStaticLists) {
|
|
372
|
+
this.loadReferenceData(screenConfig.REF_DATA_OPTIONS);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
ngAfterViewInit() {
|
|
377
|
+
super.ngAfterViewInit();
|
|
378
|
+
combineLatest([this.route.paramMap, this.route.queryParamMap]).subscribe(([params, queryParams]) => {
|
|
379
|
+
this.entityId = params.get('id');
|
|
380
|
+
this.duplicateMode = queryParams.get('mode') === 'duplicate';
|
|
381
|
+
this.context.duplicateMode = this.duplicateMode;
|
|
382
|
+
if (this.entityId) {
|
|
383
|
+
this.editionState = !this.duplicateMode;
|
|
384
|
+
this.loadData();
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
this.editionState = false;
|
|
388
|
+
this.duplicateMode = false;
|
|
389
|
+
this.context.duplicateMode = false;
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
loadData() {
|
|
394
|
+
try {
|
|
395
|
+
this.serviceInstance.get(this.entityId).subscribe({
|
|
396
|
+
next: (result) => {
|
|
397
|
+
this.entity = new ViewModelEntity(result);
|
|
398
|
+
this.entity.id = this.entityId;
|
|
399
|
+
this.afterLoad();
|
|
400
|
+
},
|
|
401
|
+
error: (_error) => {
|
|
402
|
+
// Errors handled by global error handler
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
console.error(error);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
afterLoad() {
|
|
411
|
+
this.changeDetector.detectChanges();
|
|
412
|
+
}
|
|
413
|
+
save() {
|
|
414
|
+
try {
|
|
415
|
+
this.beforeSave();
|
|
416
|
+
this.clearServerErrors();
|
|
417
|
+
const isCreateOperation = !this.editionState || this.duplicateMode;
|
|
418
|
+
const entityToSave = this.duplicateMode
|
|
419
|
+
? this.prepareEntityForDuplication()
|
|
420
|
+
: this.entity;
|
|
421
|
+
const saveOperation = isCreateOperation
|
|
422
|
+
? this.serviceInstance.create(entityToSave)
|
|
423
|
+
: this.serviceInstance.update(this.entityId, this.entity);
|
|
424
|
+
saveOperation.subscribe({
|
|
425
|
+
next: (response) => {
|
|
426
|
+
if (response && response.errors && response.errors.length > 0) {
|
|
427
|
+
this.handleErrors(response.errors);
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
this.toastService.showSuccess();
|
|
431
|
+
this.afterSave(response);
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
error: (response) => {
|
|
435
|
+
console.log(response);
|
|
436
|
+
if (response.errors) {
|
|
437
|
+
this.setServerErrors(response.errors);
|
|
438
|
+
this.setFormErrors(response.errors);
|
|
439
|
+
this.onSaveError(response.errors);
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
this.toastService.showError(error?.message || "Une erreur est survenue lors de l'enregistrement");
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
onSaveError(_errors) {
|
|
449
|
+
// Override in subclass to handle validation errors
|
|
450
|
+
}
|
|
451
|
+
afterSave(result) {
|
|
452
|
+
const screenConfig = this.getConfig();
|
|
453
|
+
if (screenConfig?.INVALIDATE_KEYS_ON_SAVE) {
|
|
454
|
+
this.invalidateReferences(screenConfig.INVALIDATE_KEYS_ON_SAVE);
|
|
455
|
+
if (screenConfig.REFRESH_ON_SAVE) {
|
|
456
|
+
this.refreshReferenceData(screenConfig.INVALIDATE_KEYS_ON_SAVE);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if (!this.editionState || this.duplicateMode) {
|
|
460
|
+
const baseUrl = this.currentUrl.split('?')[0];
|
|
461
|
+
const detailsIndex = baseUrl.indexOf('/details');
|
|
462
|
+
const cleanBaseUrl = detailsIndex !== -1
|
|
463
|
+
? baseUrl.substring(0, detailsIndex + '/details'.length)
|
|
464
|
+
: baseUrl;
|
|
465
|
+
this.router.navigate([cleanBaseUrl, result]);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
prepareEntityForDuplication() {
|
|
470
|
+
const duplicatedEntity = { ...this.entity };
|
|
471
|
+
delete duplicatedEntity.id;
|
|
472
|
+
delete duplicatedEntity.Id;
|
|
473
|
+
return this.customizeDuplicatedEntity(duplicatedEntity);
|
|
474
|
+
}
|
|
475
|
+
customizeDuplicatedEntity(entity) {
|
|
476
|
+
return entity;
|
|
477
|
+
}
|
|
478
|
+
duplicate() {
|
|
479
|
+
const baseUrl = this.currentUrl.split('?')[0];
|
|
480
|
+
this.router.navigate([baseUrl], {
|
|
481
|
+
queryParams: { mode: 'duplicate' },
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
print() {
|
|
485
|
+
// Override in subclass to implement print functionality
|
|
486
|
+
}
|
|
487
|
+
delete() {
|
|
488
|
+
if (!this.entityId)
|
|
489
|
+
return this.toastService.showError('Item [id] is undefined!');
|
|
490
|
+
this.confirmDialogService.confirm('Êtes-vous sûr de vouloir supprimer ?', () => this.serviceInstance.delete(this.entityId).subscribe({
|
|
491
|
+
next: (result) => {
|
|
492
|
+
if (result && result.errors && result.errors.length > 0) {
|
|
493
|
+
this.handleErrors(result.errors);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
this.toastService.showSuccess();
|
|
497
|
+
this.navigateBack();
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
error: () => {
|
|
501
|
+
// Errors handled by global error handler
|
|
502
|
+
},
|
|
503
|
+
}), () => {
|
|
504
|
+
// User cancelled deletion
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
navigateBack() {
|
|
508
|
+
const currentUrl = this.router.url.split('?')[0];
|
|
509
|
+
const detailsIndex = currentUrl.indexOf('/details');
|
|
510
|
+
if (detailsIndex !== -1) {
|
|
511
|
+
this.router.navigate([currentUrl.substring(0, detailsIndex)]);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
this.location.back();
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractDetailScreenComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
518
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: AbstractDetailScreenComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
519
|
+
}
|
|
520
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractDetailScreenComponent, decorators: [{
|
|
521
|
+
type: Component,
|
|
522
|
+
args: [{
|
|
523
|
+
template: '',
|
|
524
|
+
}]
|
|
525
|
+
}] });
|
|
526
|
+
|
|
527
|
+
var SortDirectionEnum;
|
|
528
|
+
(function (SortDirectionEnum) {
|
|
529
|
+
SortDirectionEnum["ASC"] = "Ascending";
|
|
530
|
+
SortDirectionEnum["DESC"] = "Descending";
|
|
531
|
+
SortDirectionEnum["DEFAULT_SORT_FIELD"] = "id";
|
|
532
|
+
})(SortDirectionEnum || (SortDirectionEnum = {}));
|
|
533
|
+
var PaginationEnum;
|
|
534
|
+
(function (PaginationEnum) {
|
|
535
|
+
PaginationEnum[PaginationEnum["DEFAULT_PAGE"] = 1] = "DEFAULT_PAGE";
|
|
536
|
+
PaginationEnum[PaginationEnum["DEFAULT_PAGE_SIZE"] = 10] = "DEFAULT_PAGE_SIZE";
|
|
537
|
+
})(PaginationEnum || (PaginationEnum = {}));
|
|
538
|
+
class SearchEntity extends AbstractEntity {
|
|
539
|
+
pagination = {
|
|
540
|
+
pageNumber: PaginationEnum.DEFAULT_PAGE,
|
|
541
|
+
pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,
|
|
542
|
+
};
|
|
543
|
+
sort = [];
|
|
544
|
+
totalPages = 0;
|
|
545
|
+
totalCount = 0;
|
|
546
|
+
items = [];
|
|
547
|
+
start = null;
|
|
548
|
+
end = null;
|
|
549
|
+
startEndDateRanges = null;
|
|
550
|
+
constructor(entity) {
|
|
551
|
+
super();
|
|
552
|
+
this.buildEntity(entity);
|
|
553
|
+
if (!this.pagination) {
|
|
554
|
+
this.pagination = {
|
|
555
|
+
pageNumber: PaginationEnum.DEFAULT_PAGE,
|
|
556
|
+
pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
if (!this.sort) {
|
|
560
|
+
this.sort = [{ field: SortDirectionEnum.DEFAULT_SORT_FIELD, sortDirection: SortDirectionEnum.DESC }];
|
|
561
|
+
}
|
|
562
|
+
if (!this.startEndDateRanges && entity['start'] && entity['end']) {
|
|
563
|
+
this.startEndDateRanges = [new Date(entity['start']), new Date(entity['end'])];
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
getSearchCriteria() {
|
|
567
|
+
const { items: _items, totalPages: _totalPages, totalCount: _totalCount, ...criteria } = this;
|
|
568
|
+
return criteria;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
class AbstractSearchScreenComponent extends AbstractScreenComponent {
|
|
573
|
+
screenState = ScreenStateEnum.SEARCH;
|
|
574
|
+
pTable;
|
|
575
|
+
entity = new ViewModelEntity({});
|
|
576
|
+
searchEntity = new SearchEntity(this.entity);
|
|
577
|
+
enableDateRangeFilter = true;
|
|
578
|
+
isLazySearch = true;
|
|
579
|
+
lastSearchEvent = null;
|
|
580
|
+
tableColumns = [];
|
|
581
|
+
injector = inject(Injector);
|
|
582
|
+
serviceInstance;
|
|
583
|
+
isInitialLoad = true;
|
|
584
|
+
ngOnInit() {
|
|
585
|
+
super.ngOnInit();
|
|
586
|
+
this.serviceInstance = this.injector.get(this.getConfig().SERVICE);
|
|
587
|
+
this.tableColumns = this.getTableColumns();
|
|
588
|
+
const screenConfig = this.getConfig();
|
|
589
|
+
const hasDynamicRefs = (screenConfig?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;
|
|
590
|
+
const hasStaticLists = (screenConfig?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;
|
|
591
|
+
if (hasDynamicRefs || hasStaticLists) {
|
|
592
|
+
if (hasDynamicRefs) {
|
|
593
|
+
this.initializeReferenceKeys(screenConfig.SEARCH_REFERENTIALS_KEYS);
|
|
594
|
+
}
|
|
595
|
+
if (hasStaticLists) {
|
|
596
|
+
this.initializeStaticLists(screenConfig.SEARCH_STATIC_LISTS);
|
|
597
|
+
}
|
|
598
|
+
this.loadReferenceData(screenConfig.REF_DATA_OPTIONS);
|
|
599
|
+
this.refDataLoaded$.pipe(take(1)).subscribe(() => {
|
|
600
|
+
this.triggerSearchIfNeeded();
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
this.triggerSearchIfNeeded();
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
getTableColumns() {
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
triggerSearchIfNeeded() {
|
|
611
|
+
const cachedCriteria = this.cacheService.getCache(this.screenStateKey);
|
|
612
|
+
if (cachedCriteria) {
|
|
613
|
+
this.searchEntity = new SearchEntity(cachedCriteria);
|
|
614
|
+
this.entity.buildEntity(this.searchEntity);
|
|
615
|
+
this.searchEntity.items = [];
|
|
616
|
+
if (this.searchEntity.startEndDateRanges) {
|
|
617
|
+
this.entity.startEndDateRanges = [
|
|
618
|
+
new Date(this.searchEntity.start),
|
|
619
|
+
new Date(this.searchEntity.end),
|
|
620
|
+
];
|
|
621
|
+
}
|
|
622
|
+
this.changeDetector.detectChanges();
|
|
623
|
+
this.search();
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
this.search();
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
onLazyLoad(event) {
|
|
630
|
+
if (this.isInitialLoad) {
|
|
631
|
+
this.isInitialLoad = false;
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
if (this.isReactiveBindingEcho(event)) {
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
this.search(event);
|
|
638
|
+
}
|
|
639
|
+
isReactiveBindingEcho(event) {
|
|
640
|
+
if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
643
|
+
const currentSort = this.searchEntity.sort[0];
|
|
644
|
+
const eventSortField = Array.isArray(event.sortField)
|
|
645
|
+
? event.sortField[0]
|
|
646
|
+
: event.sortField;
|
|
647
|
+
const eventSortDirection = event.sortOrder === 1 ? SortDirectionEnum.ASC : SortDirectionEnum.DESC;
|
|
648
|
+
const currentPage = this.searchEntity.pagination?.pageNumber || 1;
|
|
649
|
+
const currentPageSize = this.searchEntity.pagination?.pageSize || 10;
|
|
650
|
+
const eventPage = this.getPageNumber(event);
|
|
651
|
+
const eventPageSize = event.rows || 10;
|
|
652
|
+
return (currentSort.field === eventSortField &&
|
|
653
|
+
currentSort.sortDirection === eventSortDirection &&
|
|
654
|
+
currentPage === eventPage &&
|
|
655
|
+
currentPageSize === eventPageSize);
|
|
656
|
+
}
|
|
657
|
+
prepareSearch(event) {
|
|
658
|
+
this.searchEntity.buildEntity(this.entity);
|
|
659
|
+
const e = event || this.lastSearchEvent || { first: 0, rows: 10 };
|
|
660
|
+
this.searchEntity.pagination = {
|
|
661
|
+
pageNumber: this.getPageNumber(e),
|
|
662
|
+
pageSize: e.rows || 10,
|
|
663
|
+
};
|
|
664
|
+
if (this.entity.startEndDateRanges) {
|
|
665
|
+
this.searchEntity.start = this.entity.startEndDateRanges[0];
|
|
666
|
+
this.searchEntity.end = this.entity.startEndDateRanges[1];
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
this.searchEntity.start = null;
|
|
670
|
+
this.searchEntity.end = null;
|
|
671
|
+
}
|
|
672
|
+
if (this.isLazySearch) {
|
|
673
|
+
if (e.sortField) {
|
|
674
|
+
const sortField = this.getSortField(e);
|
|
675
|
+
this.searchEntity.sort = [
|
|
676
|
+
{
|
|
677
|
+
field: sortField,
|
|
678
|
+
sortDirection: this.getSortDirection(e),
|
|
679
|
+
},
|
|
680
|
+
];
|
|
681
|
+
}
|
|
682
|
+
else if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {
|
|
683
|
+
const defaultSort = this.getConfig()?.DEFAULT_SORT;
|
|
684
|
+
this.searchEntity.sort = [
|
|
685
|
+
{
|
|
686
|
+
field: defaultSort?.field || 'id',
|
|
687
|
+
sortDirection: defaultSort?.direction || SortDirectionEnum.DESC,
|
|
688
|
+
},
|
|
689
|
+
];
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
search(event = null) {
|
|
694
|
+
this.prepareSearch(event);
|
|
695
|
+
this.serviceInstance.search(this.searchEntity).subscribe({
|
|
696
|
+
next: (result) => {
|
|
697
|
+
this.lastSearchEvent = event;
|
|
698
|
+
this.searchEntity = Object.assign(new SearchEntity({}), this.searchEntity, result);
|
|
699
|
+
this.cacheService.setCache(this.screenStateKey, this.searchEntity);
|
|
700
|
+
this.changeDetector.detectChanges();
|
|
701
|
+
},
|
|
702
|
+
error: () => {
|
|
703
|
+
// Errors handled by global error handler
|
|
704
|
+
},
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
paginate(event) {
|
|
708
|
+
const pageNumber = this.getPageNumber(event);
|
|
709
|
+
const pageSize = event.rows;
|
|
710
|
+
this.searchEntity.pagination.pageNumber = pageNumber;
|
|
711
|
+
this.searchEntity.pagination.pageSize = pageSize;
|
|
712
|
+
if (this.searchEntity.items == null ||
|
|
713
|
+
this.searchEntity.items.length === 0) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
getPageNumber(event) {
|
|
718
|
+
return event.first != null
|
|
719
|
+
? Math.floor(event.first / (event.rows || 10)) + 1
|
|
720
|
+
: 1;
|
|
721
|
+
}
|
|
722
|
+
getSortField(event) {
|
|
723
|
+
return Array.isArray(event.sortField)
|
|
724
|
+
? event.sortField[0]
|
|
725
|
+
: event.sortField || 'id';
|
|
726
|
+
}
|
|
727
|
+
getSortDirection(event) {
|
|
728
|
+
return event.sortOrder === 1
|
|
729
|
+
? SortDirectionEnum.ASC
|
|
730
|
+
: SortDirectionEnum.DESC;
|
|
731
|
+
}
|
|
732
|
+
navigateToDetails(id) {
|
|
733
|
+
const path = id || id === 0
|
|
734
|
+
? `${this.currentUrl}/details/${id}`
|
|
735
|
+
: `${this.currentUrl}/details`;
|
|
736
|
+
this.router.navigate([path]);
|
|
737
|
+
}
|
|
738
|
+
add() {
|
|
739
|
+
this.router.navigate([this.currentUrl.concat('/details')]);
|
|
740
|
+
}
|
|
741
|
+
edit(id) {
|
|
742
|
+
if (!id) {
|
|
743
|
+
this.toastService.showError('Item [id] is undefined !');
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
this.router.navigate([this.currentUrl.concat('/details/'), id]);
|
|
747
|
+
}
|
|
748
|
+
delete(id) {
|
|
749
|
+
if (!id)
|
|
750
|
+
return this.toastService.showError('Item [id] is undefined!');
|
|
751
|
+
this.confirmDialogService.confirm('Êtes-vous sûr de vouloir supprimer ?', () => this.serviceInstance.delete(id).subscribe({
|
|
752
|
+
next: (result) => {
|
|
753
|
+
if (result && result.errors && result.errors.length > 0) {
|
|
754
|
+
this.handleErrors(result.errors);
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
this.search();
|
|
758
|
+
this.toastService.showSuccess();
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
error: () => {
|
|
762
|
+
// Errors handled by global error handler
|
|
763
|
+
},
|
|
764
|
+
}), () => {
|
|
765
|
+
// User cancelled deletion
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
duplicate(id) {
|
|
769
|
+
if (!id) {
|
|
770
|
+
this.toastService.showError('Item [id] is undefined !');
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
this.router.navigate([this.currentUrl.concat('/details/'), id], { queryParams: { mode: 'duplicate' } });
|
|
774
|
+
}
|
|
775
|
+
clear() {
|
|
776
|
+
this.entity.clearFields();
|
|
777
|
+
this.searchEntity.clearFields();
|
|
778
|
+
this.searchEntity = new SearchEntity({});
|
|
779
|
+
this.lastSearchEvent = null;
|
|
780
|
+
this.isInitialLoad = true;
|
|
781
|
+
this.cacheService.setCache(this.screenStateKey, this.searchEntity);
|
|
782
|
+
if (this.pTable) {
|
|
783
|
+
this.pTable.first = 0;
|
|
784
|
+
this.pTable.reset();
|
|
785
|
+
}
|
|
786
|
+
this.changeDetector.detectChanges();
|
|
787
|
+
}
|
|
788
|
+
ngOnDestroy() {
|
|
789
|
+
this.destroyed$.next();
|
|
790
|
+
this.destroyed$.complete();
|
|
791
|
+
}
|
|
792
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractSearchScreenComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
793
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: AbstractSearchScreenComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "pTable", first: true, predicate: ["pTable"], descendants: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
794
|
+
}
|
|
795
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractSearchScreenComponent, decorators: [{
|
|
796
|
+
type: Component,
|
|
797
|
+
args: [{
|
|
798
|
+
template: '',
|
|
799
|
+
standalone: true,
|
|
800
|
+
}]
|
|
801
|
+
}], propDecorators: { pTable: [{
|
|
802
|
+
type: ViewChild,
|
|
803
|
+
args: ['pTable']
|
|
804
|
+
}] } });
|
|
805
|
+
|
|
806
|
+
class AbstractSubScreenComponent extends AbstractScreenComponent {
|
|
807
|
+
screenState = null;
|
|
808
|
+
ngOnInit() {
|
|
809
|
+
super.ngOnInit();
|
|
810
|
+
}
|
|
811
|
+
ngAfterViewInit() {
|
|
812
|
+
super.ngAfterViewInit();
|
|
813
|
+
}
|
|
814
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractSubScreenComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
815
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: AbstractSubScreenComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
816
|
+
}
|
|
817
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: AbstractSubScreenComponent, decorators: [{
|
|
818
|
+
type: Component,
|
|
819
|
+
args: [{
|
|
820
|
+
template: ''
|
|
821
|
+
}]
|
|
822
|
+
}] });
|
|
823
|
+
|
|
824
|
+
class ScreenConfig {
|
|
825
|
+
SCREEN;
|
|
826
|
+
SERVICE;
|
|
827
|
+
SEARCH_REFERENTIALS_KEYS;
|
|
828
|
+
DETAILS_REFERENTIALS_KEYS;
|
|
829
|
+
SEARCH_STATIC_LISTS = [];
|
|
830
|
+
DETAILS_STATIC_LISTS = [];
|
|
831
|
+
INVALIDATE_KEYS_ON_SAVE;
|
|
832
|
+
REFRESH_ON_SAVE;
|
|
833
|
+
REF_DATA_OPTIONS;
|
|
834
|
+
DEFAULT_SORT;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// Abstract base classes
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Generated bundle index. Do not edit.
|
|
841
|
+
*/
|
|
842
|
+
|
|
843
|
+
export { AbstractComponent, AbstractDetailScreenComponent, AbstractEntity, AbstractScreenComponent, AbstractSearchScreenComponent, AbstractSubScreenComponent, PaginationEnum, SCREEN_REF_DATA_SERVICE, ScreenConfig, ScreenContext, ScreenStateEnum, SearchEntity, SortDirectionEnum, StateUtilsEnum, ViewModelEntity };
|
|
844
|
+
//# sourceMappingURL=elasticias-screens.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elasticias-screens.mjs","sources":["../../../../libs/screens/src/lib/abstract/abstract.entity.ts","../../../../libs/screens/src/lib/abstract/abstract.component.ts","../../../../libs/screens/src/lib/config/screen-context.ts","../../../../libs/screens/src/lib/services/screen-reference-data.service.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-screen.component.ts","../../../../libs/screens/src/lib/config/screen-state.enum.ts","../../../../libs/screens/src/lib/entities/view-model.entity.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-detail-screen.component.ts","../../../../libs/screens/src/lib/entities/search.entity.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-search-screen.component.ts","../../../../libs/screens/src/lib/abstract/screen/abstract-sub-screen.component.ts","../../../../libs/screens/src/lib/config/screen-config.ts","../../../../libs/screens/src/index.ts","../../../../libs/screens/src/elasticias-screens.ts"],"sourcesContent":["export abstract class AbstractEntity {\n [key: string]: unknown;\n clone(entity: AbstractEntity): AbstractEntity {\n for (const field of Reflect.ownKeys(entity)) {\n if ((this as Record<string | symbol, unknown>)[field] == null) {\n (this as Record<string | symbol, unknown>)[field] = (entity as unknown as Record<string | symbol, unknown>)[field];\n }\n }\n return this;\n }\n\n newClone(): Record<string, unknown> {\n const cloneObj: Record<string, unknown> = {};\n for (const field of Reflect.ownKeys(this)) {\n cloneObj[field as string] = (this as Record<string | symbol, unknown>)[field];\n }\n return cloneObj;\n }\n\n update(entity: Record<string, unknown>): AbstractEntity {\n for (const field of Reflect.ownKeys(entity)) {\n if ((this as Record<string | symbol, unknown>)[field] != null) {\n (this as Record<string | symbol, unknown>)[field] = entity[field as string];\n }\n }\n return this;\n }\n\n buildEntity(entity: Record<string, unknown>): void {\n Object.keys(entity).forEach((key) => {\n (this as Record<string, unknown>)[key] = entity[key];\n });\n }\n\n clearFields(): void {\n for (const field of Reflect.ownKeys(this)) {\n (this as Record<string | symbol, unknown>)[field] = null;\n }\n }\n}\n","import { Component, Input, OnDestroy, OnInit } from '@angular/core';\nimport { Subject } from 'rxjs';\n\n@Component({ template: '' })\nexport abstract class AbstractComponent implements OnInit, OnDestroy {\n @Input() readOnly = false;\n\n protected destroyed$ = new Subject<void>();\n\n abstract ngOnInit(): void;\n\n abstract ngOnDestroy(): void;\n}\n","import { Signal, signal } from '@angular/core';\nimport { AbstractEntity } from '../abstract/abstract.entity';\nimport { PermissionsEnum } from '@elasticias/types';\n\n/**\n * Abstract interface for reference data providers.\n * Apps must implement this and provide it to ScreenContext.\n */\nexport interface ReferenceDataProvider {\n getReference(key: string): Signal<any[]>;\n hasReference(key: string): boolean;\n}\n\nexport class ScreenContext extends AbstractEntity {\n state: string;\n screenName!: string;\n language: string;\n group: unknown;\n private _refDataProvider?: ReferenceDataProvider;\n bundles: Map<string, Map<string, Map<string, string>>>;\n entity: unknown;\n grants: string[];\n duplicateMode = false;\n\n constructor(\n state: string,\n group?: unknown,\n entity?: unknown,\n refDataProvider?: ReferenceDataProvider,\n bundles?: Map<string, Map<string, Map<string, string>>>,\n grants?: string[],\n screenName = '',\n language = 'fr'\n ) {\n super();\n this.state = state;\n this.group = group;\n this.entity = entity;\n this.screenName = screenName;\n this.language = language;\n this._refDataProvider = refDataProvider;\n this.bundles = bundles ?? new Map();\n this.grants = grants ?? [];\n }\n\n setReferenceDataProvider(provider: ReferenceDataProvider): void {\n this._refDataProvider = provider;\n }\n\n get ref() {\n return {\n get: (key: string): Signal<any[]> => {\n if (!this._refDataProvider) {\n console.warn('ReferenceDataProvider not set in ScreenContext. Returning empty signal.');\n return signal([]);\n }\n return this._refDataProvider.getReference(key);\n },\n has: (key: string): boolean => {\n return this._refDataProvider?.hasReference(key) ?? false;\n },\n };\n }\n\n getLabel(key: string): string {\n try {\n return this.bundles.get(this.language)!.get(this.screenName)!.get(key) ?? key;\n } catch {\n return key;\n }\n }\n\n isGranted(permission: PermissionsEnum): boolean {\n return this.grants?.some((value) => value === permission) ?? false;\n }\n\n isReadOnly(): boolean {\n return (\n this.isGranted(PermissionsEnum.Read) &&\n !this.isGranted(PermissionsEnum.Write) &&\n !this.isGranted(PermissionsEnum.Edit) &&\n !this.isGranted(PermissionsEnum.Delete)\n );\n }\n}\n","import { InjectionToken, Signal } from '@angular/core';\nimport { ReferenceDataProvider } from '../config/screen-context';\nimport { LoadOptions } from '../config/screen-config';\n\n/**\n * Abstract interface for reference data services used by screen components.\n * Apps must implement this interface and provide it via SCREEN_REF_DATA_SERVICE token.\n *\n * Extends ReferenceDataProvider (getReference/hasReference for ScreenContext)\n * with methods for loading, refreshing, and invalidating reference data.\n */\nexport interface ScreenReferenceDataService extends ReferenceDataProvider {\n /**\n * Load dynamic reference data by keys\n * @param keys Array of reference data keys to load\n * @param options Optional load options (bypassCache, ttl, forceRefresh)\n */\n loadReferenceKeys(keys: string[], options?: LoadOptions): Promise<void>;\n\n /**\n * Load static reference data by type names\n * @param types Array of static reference type names\n * @param forceRefresh Force reload from server\n */\n loadStaticRefs(types: string[], forceRefresh?: boolean): Promise<void>;\n\n /**\n * Refresh reference data keys (force reload from server)\n * @param keys Array of keys to refresh\n * @param bypassCache Bypass cache entirely\n */\n refreshKeys(keys: string[], bypassCache?: boolean): Promise<void>;\n\n /**\n * Invalidate reference data keys (mark as stale)\n * @param keys Array of keys to invalidate\n */\n invalidateKeys(keys: string[]): Promise<void>;\n}\n\n/**\n * Injection token for the screen reference data service.\n * Apps must provide this token with their concrete implementation.\n *\n * @example\n * // In app module or component providers:\n * { provide: SCREEN_REF_DATA_SERVICE, useExisting: ReferenceDataService }\n */\nexport const SCREEN_REF_DATA_SERVICE = new InjectionToken<ScreenReferenceDataService>(\n 'SCREEN_REF_DATA_SERVICE'\n);\n","import { AfterViewInit, ChangeDetectorRef, Component, inject, Input, OnDestroy, OnInit, signal, ViewChild } from '@angular/core';\nimport { AbstractComponent } from '../abstract.component';\nimport { ScreenContext } from '../../config/screen-context';\nimport { ScreenConfig, LoadOptions } from '../../config/screen-config';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { NgForm } from '@angular/forms';\nimport { AppUtils, StorageUtils } from '@elasticias/utils';\nimport { ToastService, ConfirmDialogService, CacheService } from '@elasticias/core';\nimport { Subject } from 'rxjs';\nimport { ScreenReferenceDataService, SCREEN_REF_DATA_SERVICE } from '../../services/screen-reference-data.service';\n\n@Component({\n template: ''\n})\nexport abstract class AbstractScreenComponent extends AbstractComponent implements OnInit, AfterViewInit, OnDestroy {\n @Input() context!: ScreenContext;\n connectedUser: any;\n\n @ViewChild('entityForm') entityForm!: NgForm;\n serverErrors = signal<{ [key: string]: string[] }>({});\n protected refDataLoaded$ = new Subject<void>();\n\n cacheService = inject(CacheService);\n changeDetector = inject(ChangeDetectorRef);\n toastService = inject(ToastService);\n confirmDialogService = inject(ConfirmDialogService);\n router = inject(Router);\n route = inject(ActivatedRoute);\n refDataService = inject(SCREEN_REF_DATA_SERVICE);\n\n currentUrl = '';\n\n protected abstract readonly screenState: string | null;\n get state(): string | null { return this.screenState; }\n screenStateKey = '';\n\n ngOnInit(): void {\n this.cacheService.configure(true);\n this.currentUrl = this.router.url;\n this.context = new ScreenContext(this.screenState ?? '', undefined, undefined, this.refDataService);\n\n this.screenStateKey = `SCREEN_STATE_${this.screenState}_${this.getBundleName()}`;\n this.context.screenName = this.getBundleName();\n this.processGrants();\n }\n\n ngAfterViewInit(): void {\n this.changeDetector.detectChanges();\n if (this.context && this.context.isReadOnly()) {\n this.disableAllControls();\n }\n }\n\n processGrants() {\n const userGrants: any = StorageUtils.getSession('CURRENT_USER_GRANTS');\n if (userGrants && userGrants[this.context.screenName] && userGrants[this.context.screenName].permissions) {\n this.context.grants = userGrants[this.context.screenName].permissions;\n } else {\n this.context.grants = [];\n }\n this.changeDetector.detectChanges();\n }\n\n isFormValid(): boolean {\n if (this.context.isReadOnly()) { return true; }\n if (!this.entityForm) {\n return false;\n }\n return this.entityForm.valid ?? false;\n }\n\n getConfig(): any {\n return null;\n }\n\n getBundleName(): string {\n const config = this.getConfig();\n if (config) {\n return config.SCREEN;\n } else {\n console.error('getConfig() method should be implemented !!');\n }\n return '';\n }\n\n setFormErrors(errors: { [key: string]: string[] }) {\n if (!errors || !this.entityForm) { return; }\n\n Object.keys(errors).forEach((field) => {\n const camelCaseField = AppUtils.toCamelCase(field);\n const control = this.entityForm.controls[camelCaseField];\n\n if (control) {\n control.setErrors({ serverError: errors[field] });\n control.markAsTouched();\n }\n });\n }\n\n referentialKeys: any;\n staticListKeys: string[] = [];\n\n initializeReferenceKeys(keys: string[]): void {\n if (!keys) return;\n const referencialKeys: any = {};\n\n keys.forEach(p => {\n referencialKeys[p] = {};\n });\n\n this.referentialKeys = referencialKeys;\n }\n\n initializeStaticLists(keys: string[]): void {\n if (!keys) return;\n this.staticListKeys = keys;\n }\n\n async loadReferenceData(options?: LoadOptions) {\n const loadPromises: Promise<void>[] = [];\n\n if (!AppUtils.isNullOrEmpty(this.referentialKeys)) {\n const dynamicKeys = Object.keys(this.referentialKeys);\n\n const dynamicPromise = this.refDataService\n .loadReferenceKeys(dynamicKeys, options)\n .catch((error: unknown) => {\n console.error('Failed to load dynamic reference data:', error);\n });\n\n loadPromises.push(dynamicPromise);\n }\n\n if (this.staticListKeys && this.staticListKeys.length > 0) {\n const staticPromise = this.refDataService\n .loadStaticRefs(this.staticListKeys)\n .catch((error: unknown) => {\n console.error('Failed to load static lists:', error);\n });\n\n loadPromises.push(staticPromise);\n }\n\n if (loadPromises.length === 0) {\n this.refDataLoaded$.next();\n return;\n }\n\n try {\n await Promise.all(loadPromises);\n this.refDataLoaded$.next();\n } catch (error) {\n console.error('Failed to load reference data:', error);\n this.refDataLoaded$.next();\n }\n }\n\n async refreshReferenceData(keys?: string[]) {\n const keysToRefresh = keys || Object.keys(this.referentialKeys || {});\n\n if (keysToRefresh.length === 0) {\n return;\n }\n\n try {\n await this.refDataService.refreshKeys(keysToRefresh, true);\n this.toastService.showSuccess('Reference data refreshed successfully', 'Success');\n } catch (error) {\n console.error('Failed to refresh reference data:', error);\n this.toastService.showError('Failed to refresh reference data', 'Error');\n }\n }\n\n async refreshStaticLists() {\n if (!this.staticListKeys || this.staticListKeys.length === 0) {\n return;\n }\n\n try {\n await this.refDataService.loadStaticRefs(this.staticListKeys, true);\n this.toastService.showSuccess('Static lists refreshed successfully', 'Success');\n } catch (error) {\n console.error('Failed to refresh static lists:', error);\n this.toastService.showError('Failed to refresh static lists', 'Error');\n }\n }\n\n async invalidateReference(key: string) {\n await this.refDataService.invalidateKeys([key]);\n }\n\n async invalidateReferences(keys: string[]) {\n await this.refDataService.invalidateKeys(keys);\n }\n\n handleErrors(errors: string[]) {\n if (errors && errors.length > 0) {\n errors.forEach(error => this.toastService.showError(error, 'Erreur de validation'));\n } else {\n this.toastService.showError('Une erreur inconnue est survenue', 'Erreur');\n }\n }\n\n setServerErrors(errors: { [key: string]: string[] }) {\n this.serverErrors.set(errors || {});\n }\n\n clearServerErrors() {\n this.serverErrors.set({});\n }\n\n disableAllControls() {\n setTimeout(() => {\n if (this.entityForm && Object.keys(this.entityForm.controls).length > 0) {\n const controlNames = Object.keys(this.entityForm.controls);\n controlNames.forEach(controlName => {\n const control = this.entityForm.controls[controlName];\n if (control) {\n control.disable();\n }\n });\n }\n }, 10);\n }\n}\n","export enum ScreenStateEnum {\n READ_ONLY = 'READ_ONLY',\n DETAIL = 'DETAIL',\n SEARCH = 'SEARCH',\n CUSTOM = 'CUSTOM',\n}\n\nexport enum StateUtilsEnum {\n REMOVE = 'removeState',\n ADD = 'addState',\n DUPLICATE = 'duplicateState',\n EDIT = 'editState',\n EDIT_AFTER_ERROR = 'editAfterErrorState',\n ADD_AFTER_ERROR = 'addAfterErrorState',\n SAVE = 'afterSaveState',\n}\n","import { AbstractEntity } from '../abstract/abstract.entity';\n\nexport class ViewModelEntity extends AbstractEntity {\n constructor(entity: Record<string, unknown>) {\n super();\n this.clone(entity as unknown as AbstractEntity);\n }\n}\n","import {\n AfterViewInit,\n Component,\n inject,\n Injector,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { Location } from '@angular/common';\nimport { combineLatest } from 'rxjs';\n\n@Component({\n template: '',\n})\nexport abstract class AbstractDetailScreenComponent\n extends AbstractScreenComponent\n implements AfterViewInit, OnInit, OnDestroy\n{\n protected readonly screenState = ScreenStateEnum.DETAIL;\n\n entity: any = {};\n entityId: any;\n editionState = false;\n duplicateMode = false;\n\n private location = inject(Location);\n protected injector = inject(Injector);\n private serviceInstance: any;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n const screenConfig = this.getConfig();\n if (screenConfig) {\n const hasDynamicRefs = (screenConfig.DETAILS_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (screenConfig.DETAILS_STATIC_LISTS?.length ?? 0) > 0;\n\n if (hasDynamicRefs) {\n this.initializeReferenceKeys(screenConfig.DETAILS_REFERENTIALS_KEYS);\n }\n if (hasStaticLists) {\n this.initializeStaticLists(screenConfig.DETAILS_STATIC_LISTS);\n }\n if (hasDynamicRefs || hasStaticLists) {\n this.loadReferenceData(screenConfig.REF_DATA_OPTIONS);\n }\n }\n }\n\n override ngAfterViewInit(): void {\n super.ngAfterViewInit();\n combineLatest([this.route.paramMap, this.route.queryParamMap]).subscribe(\n ([params, queryParams]) => {\n this.entityId = params.get('id');\n this.duplicateMode = queryParams.get('mode') === 'duplicate';\n this.context.duplicateMode = this.duplicateMode;\n\n if (this.entityId) {\n this.editionState = !this.duplicateMode;\n this.loadData();\n } else {\n this.editionState = false;\n this.duplicateMode = false;\n this.context.duplicateMode = false;\n }\n },\n );\n }\n\n public loadData(): void {\n try {\n this.serviceInstance.get(this.entityId).subscribe({\n next: (result: any) => {\n this.entity = new ViewModelEntity(result);\n this.entity.id = this.entityId;\n this.afterLoad();\n },\n error: (_error: any) => {\n // Errors handled by global error handler\n },\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n protected afterLoad() {\n this.changeDetector.detectChanges();\n }\n\n abstract beforeSave(): void;\n\n save() {\n try {\n this.beforeSave();\n this.clearServerErrors();\n\n const isCreateOperation = !this.editionState || this.duplicateMode;\n const entityToSave = this.duplicateMode\n ? this.prepareEntityForDuplication()\n : this.entity;\n\n const saveOperation = isCreateOperation\n ? this.serviceInstance.create(entityToSave)\n : this.serviceInstance.update(this.entityId, this.entity);\n\n saveOperation.subscribe({\n next: (response: any) => {\n if (response && response.errors && response.errors.length > 0) {\n this.handleErrors(response.errors);\n } else {\n this.toastService.showSuccess();\n this.afterSave(response);\n }\n },\n error: (response: any) => {\n console.log(response);\n if (response.errors) {\n this.setServerErrors(response.errors);\n this.setFormErrors(response.errors);\n this.onSaveError(response.errors);\n }\n },\n });\n } catch (error: any) {\n this.toastService.showError(\n error?.message || \"Une erreur est survenue lors de l'enregistrement\",\n );\n }\n }\n\n protected onSaveError(_errors: { [key: string]: string[] }) {\n // Override in subclass to handle validation errors\n }\n\n protected afterSave(result: any) {\n const screenConfig = this.getConfig();\n if (screenConfig?.INVALIDATE_KEYS_ON_SAVE) {\n this.invalidateReferences(screenConfig.INVALIDATE_KEYS_ON_SAVE);\n\n if (screenConfig.REFRESH_ON_SAVE) {\n this.refreshReferenceData(screenConfig.INVALIDATE_KEYS_ON_SAVE);\n }\n }\n\n if (!this.editionState || this.duplicateMode) {\n const baseUrl = this.currentUrl.split('?')[0];\n const detailsIndex = baseUrl.indexOf('/details');\n const cleanBaseUrl =\n detailsIndex !== -1\n ? baseUrl.substring(0, detailsIndex + '/details'.length)\n : baseUrl;\n this.router.navigate([cleanBaseUrl, result]);\n return;\n }\n }\n\n protected prepareEntityForDuplication(): any {\n const duplicatedEntity = { ...this.entity };\n delete duplicatedEntity.id;\n delete duplicatedEntity.Id;\n return this.customizeDuplicatedEntity(duplicatedEntity);\n }\n\n protected customizeDuplicatedEntity(entity: any): any {\n return entity;\n }\n\n duplicate() {\n const baseUrl = this.currentUrl.split('?')[0];\n this.router.navigate([baseUrl], {\n queryParams: { mode: 'duplicate' },\n });\n }\n\n print() {\n // Override in subclass to implement print functionality\n }\n\n delete(): void {\n if (!this.entityId)\n return this.toastService.showError('Item [id] is undefined!');\n\n this.confirmDialogService.confirm(\n 'Êtes-vous sûr de vouloir supprimer ?',\n () =>\n this.serviceInstance.delete(this.entityId).subscribe({\n next: (result: any) => {\n if (result && result.errors && result.errors.length > 0) {\n this.handleErrors(result.errors);\n } else {\n this.toastService.showSuccess();\n this.navigateBack();\n }\n },\n error: () => {\n // Errors handled by global error handler\n },\n }),\n () => {\n // User cancelled deletion\n },\n );\n }\n\n navigateBack() {\n const currentUrl = this.router.url.split('?')[0];\n const detailsIndex = currentUrl.indexOf('/details');\n if (detailsIndex !== -1) {\n this.router.navigate([currentUrl.substring(0, detailsIndex)]);\n } else {\n this.location.back();\n }\n }\n}\n","import { AbstractEntity } from '../abstract/abstract.entity';\n\nexport enum SortDirectionEnum {\n ASC = 'Ascending',\n DESC = 'Descending',\n DEFAULT_SORT_FIELD = 'id',\n}\n\nexport enum PaginationEnum {\n DEFAULT_PAGE = 1,\n DEFAULT_PAGE_SIZE = 10,\n}\n\nexport class SearchEntity extends AbstractEntity {\n pagination: { pageNumber: number; pageSize: number } = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n\n sort: Array<{ field: string; sortDirection: string }> = [];\n\n totalPages = 0;\n totalCount = 0;\n items: AbstractEntity[] = [];\n start: Date | null = null;\n end: Date | null = null;\n startEndDateRanges: Date[] | null = null;\n\n constructor(entity: Record<string, unknown>) {\n super();\n this.buildEntity(entity);\n\n if (!this.pagination) {\n this.pagination = {\n pageNumber: PaginationEnum.DEFAULT_PAGE,\n pageSize: PaginationEnum.DEFAULT_PAGE_SIZE,\n };\n }\n\n if (!this.sort) {\n this.sort = [{ field: SortDirectionEnum.DEFAULT_SORT_FIELD, sortDirection: SortDirectionEnum.DESC }];\n }\n\n if (!this.startEndDateRanges && entity['start'] && entity['end']) {\n this.startEndDateRanges = [new Date(entity['start'] as string), new Date(entity['end'] as string)];\n }\n }\n\n getSearchCriteria(): Record<string, unknown> {\n const { items: _items, totalPages: _totalPages, totalCount: _totalCount, ...criteria } = this;\n return criteria;\n }\n}\n","import {\n AfterViewInit,\n Component,\n inject,\n Injector,\n OnDestroy,\n OnInit,\n ViewChild,\n} from '@angular/core';\nimport { ScreenStateEnum } from '../../config/screen-state.enum';\nimport { ViewModelEntity } from '../../entities/view-model.entity';\nimport { SearchEntity, SortDirectionEnum } from '../../entities/search.entity';\nimport { AbstractScreenComponent } from './abstract-screen.component';\nimport { Table, TableLazyLoadEvent } from 'primeng/table';\nimport { take } from 'rxjs';\n\n/**\n * Column definition interface for ef-datatable integration.\n * Kept minimal here to avoid circular dependency on @elasticias/ui.\n */\nexport interface ScreenDatatableColumn {\n field: string;\n header: string;\n type?: string;\n [key: string]: any;\n}\n\n@Component({\n template: '',\n standalone: true,\n})\nexport abstract class AbstractSearchScreenComponent\n extends AbstractScreenComponent\n implements AfterViewInit, OnInit, OnDestroy\n{\n protected readonly screenState = ScreenStateEnum.SEARCH;\n\n @ViewChild('pTable') pTable!: Table;\n\n entity: any = new ViewModelEntity({});\n searchEntity = new SearchEntity(this.entity);\n enableDateRangeFilter = true;\n isLazySearch = true;\n lastSearchEvent: TableLazyLoadEvent | null = null;\n\n tableColumns: any[] = [];\n\n protected injector = inject(Injector);\n private serviceInstance: any;\n private isInitialLoad = true;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.serviceInstance = this.injector.get(this.getConfig()!.SERVICE as any);\n\n this.tableColumns = this.getTableColumns();\n\n const screenConfig = this.getConfig();\n const hasDynamicRefs = (screenConfig?.SEARCH_REFERENTIALS_KEYS?.length ?? 0) > 0;\n const hasStaticLists = (screenConfig?.SEARCH_STATIC_LISTS?.length ?? 0) > 0;\n\n if (hasDynamicRefs || hasStaticLists) {\n if (hasDynamicRefs) {\n this.initializeReferenceKeys(screenConfig!.SEARCH_REFERENTIALS_KEYS);\n }\n\n if (hasStaticLists) {\n this.initializeStaticLists(screenConfig!.SEARCH_STATIC_LISTS);\n }\n\n this.loadReferenceData(screenConfig!.REF_DATA_OPTIONS);\n\n this.refDataLoaded$.pipe(take(1)).subscribe(() => {\n this.triggerSearchIfNeeded();\n });\n } else {\n this.triggerSearchIfNeeded();\n }\n }\n\n protected getTableColumns(): any[] {\n return [];\n }\n\n private triggerSearchIfNeeded() {\n const cachedCriteria = this.cacheService.getCache<any>(this.screenStateKey);\n if (cachedCriteria) {\n this.searchEntity = new SearchEntity(cachedCriteria);\n this.entity.buildEntity(this.searchEntity);\n this.searchEntity.items = [];\n\n if (this.searchEntity.startEndDateRanges) {\n this.entity.startEndDateRanges = [\n new Date(this.searchEntity.start!),\n new Date(this.searchEntity.end!),\n ];\n }\n\n this.changeDetector.detectChanges();\n this.search();\n } else {\n this.search();\n }\n }\n\n onLazyLoad(event: TableLazyLoadEvent): void {\n if (this.isInitialLoad) {\n this.isInitialLoad = false;\n return;\n }\n\n if (this.isReactiveBindingEcho(event)) {\n return;\n }\n\n this.search(event);\n }\n\n private isReactiveBindingEcho(event: TableLazyLoadEvent): boolean {\n if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {\n return false;\n }\n\n const currentSort = this.searchEntity.sort[0];\n const eventSortField = Array.isArray(event.sortField)\n ? event.sortField[0]\n : event.sortField;\n const eventSortDirection =\n event.sortOrder === 1 ? SortDirectionEnum.ASC : SortDirectionEnum.DESC;\n\n const currentPage = this.searchEntity.pagination?.pageNumber || 1;\n const currentPageSize = this.searchEntity.pagination?.pageSize || 10;\n const eventPage = this.getPageNumber(event);\n const eventPageSize = event.rows || 10;\n\n return (\n currentSort.field === eventSortField &&\n currentSort.sortDirection === eventSortDirection &&\n currentPage === eventPage &&\n currentPageSize === eventPageSize\n );\n }\n\n private prepareSearch(event: TableLazyLoadEvent | null): void {\n this.searchEntity.buildEntity(this.entity);\n const e = event || this.lastSearchEvent || { first: 0, rows: 10 };\n\n this.searchEntity.pagination = {\n pageNumber: this.getPageNumber(e),\n pageSize: e.rows || 10,\n };\n\n if (this.entity.startEndDateRanges) {\n this.searchEntity.start = this.entity.startEndDateRanges[0];\n this.searchEntity.end = this.entity.startEndDateRanges[1];\n } else {\n this.searchEntity.start = null;\n this.searchEntity.end = null;\n }\n\n if (this.isLazySearch) {\n if (e.sortField) {\n const sortField = this.getSortField(e);\n this.searchEntity.sort = [\n {\n field: sortField,\n sortDirection: this.getSortDirection(e),\n },\n ];\n } else if (!this.searchEntity.sort || this.searchEntity.sort.length === 0) {\n const defaultSort = this.getConfig()?.DEFAULT_SORT;\n this.searchEntity.sort = [\n {\n field: defaultSort?.field || 'id',\n sortDirection: defaultSort?.direction || SortDirectionEnum.DESC,\n },\n ];\n }\n }\n }\n\n protected search(event: TableLazyLoadEvent | null = null): void {\n this.prepareSearch(event);\n\n this.serviceInstance.search(this.searchEntity).subscribe({\n next: (result: any) => {\n this.lastSearchEvent = event;\n this.searchEntity = Object.assign(new SearchEntity({}), this.searchEntity, result);\n this.cacheService.setCache(this.screenStateKey, this.searchEntity);\n this.changeDetector.detectChanges();\n },\n error: () => {\n // Errors handled by global error handler\n },\n });\n }\n\n paginate(event: any) {\n const pageNumber = this.getPageNumber(event);\n const pageSize = event.rows;\n\n this.searchEntity.pagination.pageNumber = pageNumber;\n this.searchEntity.pagination.pageSize = pageSize;\n\n if (\n this.searchEntity.items == null ||\n this.searchEntity.items.length === 0\n ) {\n return;\n }\n }\n\n getPageNumber(event: TableLazyLoadEvent): number {\n return event.first != null\n ? Math.floor(event.first / (event.rows || 10)) + 1\n : 1;\n }\n\n getSortField(event: TableLazyLoadEvent): string {\n return Array.isArray(event.sortField)\n ? event.sortField[0]\n : event.sortField || 'id';\n }\n\n getSortDirection(event: TableLazyLoadEvent): string {\n return event.sortOrder === 1\n ? SortDirectionEnum.ASC\n : SortDirectionEnum.DESC;\n }\n\n navigateToDetails(id?: any): void {\n const path =\n id || id === 0\n ? `${this.currentUrl}/details/${id}`\n : `${this.currentUrl}/details`;\n this.router.navigate([path]);\n }\n\n add() {\n this.router.navigate([this.currentUrl.concat('/details')]);\n }\n\n edit(id: any) {\n if (!id) {\n this.toastService.showError('Item [id] is undefined !');\n return;\n }\n this.router.navigate([this.currentUrl.concat('/details/'), id]);\n }\n\n delete(id: any): void {\n if (!id) return this.toastService.showError('Item [id] is undefined!');\n\n this.confirmDialogService.confirm(\n 'Êtes-vous sûr de vouloir supprimer ?',\n () =>\n this.serviceInstance.delete(id).subscribe({\n next: (result: any) => {\n if (result && result.errors && result.errors.length > 0) {\n this.handleErrors(result.errors);\n } else {\n this.search();\n this.toastService.showSuccess();\n }\n },\n error: () => {\n // Errors handled by global error handler\n },\n }),\n () => {\n // User cancelled deletion\n },\n );\n }\n\n duplicate(id: any) {\n if (!id) {\n this.toastService.showError('Item [id] is undefined !');\n return;\n }\n this.router.navigate(\n [this.currentUrl.concat('/details/'), id],\n { queryParams: { mode: 'duplicate' } }\n );\n }\n\n clear(): void {\n this.entity.clearFields();\n this.searchEntity.clearFields();\n this.searchEntity = new SearchEntity({});\n\n this.lastSearchEvent = null;\n this.isInitialLoad = true;\n\n this.cacheService.setCache(this.screenStateKey, this.searchEntity);\n\n if (this.pTable) {\n this.pTable.first = 0;\n this.pTable.reset();\n }\n\n this.changeDetector.detectChanges();\n }\n\n ngOnDestroy(): void {\n this.destroyed$.next();\n this.destroyed$.complete();\n }\n}\n","import { Component } from '@angular/core';\nimport { AbstractScreenComponent } from './abstract-screen.component';\n\n@Component({\n template: ''\n})\nexport abstract class AbstractSubScreenComponent extends AbstractScreenComponent {\n protected readonly screenState = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n }\n\n override ngAfterViewInit(): void {\n super.ngAfterViewInit();\n }\n}\n","import { SortDirectionEnum } from '../entities/search.entity';\n\nexport interface DefaultSort {\n field: string;\n direction: SortDirectionEnum;\n}\n\nexport interface LoadOptions {\n bypassCache?: boolean;\n ttl?: number;\n forceRefresh?: boolean;\n useSql?: boolean;\n}\n\nexport abstract class ScreenConfig {\n SCREEN!: string;\n SERVICE!: unknown;\n\n SEARCH_REFERENTIALS_KEYS!: string[];\n DETAILS_REFERENTIALS_KEYS!: string[];\n\n SEARCH_STATIC_LISTS: string[] = [];\n DETAILS_STATIC_LISTS: string[] = [];\n\n INVALIDATE_KEYS_ON_SAVE?: string[];\n REFRESH_ON_SAVE?: boolean;\n REF_DATA_OPTIONS?: LoadOptions;\n DEFAULT_SORT?: DefaultSort;\n}\n","// Abstract base classes\nexport { AbstractEntity } from './lib/abstract/abstract.entity';\nexport { AbstractComponent } from './lib/abstract/abstract.component';\n\n// Screen abstract components\nexport { AbstractScreenComponent } from './lib/abstract/screen/abstract-screen.component';\nexport { AbstractDetailScreenComponent } from './lib/abstract/screen/abstract-detail-screen.component';\nexport { AbstractSearchScreenComponent } from './lib/abstract/screen/abstract-search-screen.component';\nexport type { ScreenDatatableColumn } from './lib/abstract/screen/abstract-search-screen.component';\nexport { AbstractSubScreenComponent } from './lib/abstract/screen/abstract-sub-screen.component';\n\n// Services\nexport { SCREEN_REF_DATA_SERVICE } from './lib/services/screen-reference-data.service';\nexport type { ScreenReferenceDataService } from './lib/services/screen-reference-data.service';\n\n// Config\nexport { ScreenStateEnum, StateUtilsEnum } from './lib/config/screen-state.enum';\nexport { ScreenConfig } from './lib/config/screen-config';\nexport type { LoadOptions, DefaultSort } from './lib/config/screen-config';\nexport { ScreenContext } from './lib/config/screen-context';\nexport type { ReferenceDataProvider } from './lib/config/screen-context';\n\n// Entities\nexport { SearchEntity, SortDirectionEnum, PaginationEnum } from './lib/entities/search.entity';\nexport { ViewModelEntity } from './lib/entities/view-model.entity';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elasticias/screens",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^21.0.0",
|
|
6
|
+
"@angular/core": "^21.0.0",
|
|
7
|
+
"@angular/forms": "^21.0.0",
|
|
8
|
+
"@angular/router": "^21.0.0",
|
|
9
|
+
"@elasticias/core": ">=0.0.1",
|
|
10
|
+
"@elasticias/types": ">=0.0.1",
|
|
11
|
+
"@elasticias/utils": ">=0.0.1",
|
|
12
|
+
"primeng": "^21.0.0",
|
|
13
|
+
"rxjs": "~7.8.0"
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/elasticias/elasticias-framework-ui.git",
|
|
19
|
+
"directory": "libs/screens"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"registry": "https://registry.npmjs.org",
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"module": "fesm2022/elasticias-screens.mjs",
|
|
26
|
+
"typings": "types/elasticias-screens.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
"./package.json": {
|
|
29
|
+
"default": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./types/elasticias-screens.d.ts",
|
|
33
|
+
"default": "./fesm2022/elasticias-screens.mjs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"tslib": "^2.3.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnInit, OnDestroy, Signal, InjectionToken, AfterViewInit, ChangeDetectorRef, Injector } from '@angular/core';
|
|
3
|
+
import { Subject } from 'rxjs';
|
|
4
|
+
import { PermissionsEnum } from '@elasticias/types';
|
|
5
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
6
|
+
import { NgForm } from '@angular/forms';
|
|
7
|
+
import { CacheService, ToastService, ConfirmDialogService } from '@elasticias/core';
|
|
8
|
+
import { Table, TableLazyLoadEvent } from 'primeng/table';
|
|
9
|
+
|
|
10
|
+
declare abstract class AbstractEntity {
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
clone(entity: AbstractEntity): AbstractEntity;
|
|
13
|
+
newClone(): Record<string, unknown>;
|
|
14
|
+
update(entity: Record<string, unknown>): AbstractEntity;
|
|
15
|
+
buildEntity(entity: Record<string, unknown>): void;
|
|
16
|
+
clearFields(): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare abstract class AbstractComponent implements OnInit, OnDestroy {
|
|
20
|
+
readOnly: boolean;
|
|
21
|
+
protected destroyed$: Subject<void>;
|
|
22
|
+
abstract ngOnInit(): void;
|
|
23
|
+
abstract ngOnDestroy(): void;
|
|
24
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AbstractComponent, never>;
|
|
25
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AbstractComponent, "ng-component", never, { "readOnly": { "alias": "readOnly"; "required": false; }; }, {}, never, never, true, never>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Abstract interface for reference data providers.
|
|
30
|
+
* Apps must implement this and provide it to ScreenContext.
|
|
31
|
+
*/
|
|
32
|
+
interface ReferenceDataProvider {
|
|
33
|
+
getReference(key: string): Signal<any[]>;
|
|
34
|
+
hasReference(key: string): boolean;
|
|
35
|
+
}
|
|
36
|
+
declare class ScreenContext extends AbstractEntity {
|
|
37
|
+
state: string;
|
|
38
|
+
screenName: string;
|
|
39
|
+
language: string;
|
|
40
|
+
group: unknown;
|
|
41
|
+
private _refDataProvider?;
|
|
42
|
+
bundles: Map<string, Map<string, Map<string, string>>>;
|
|
43
|
+
entity: unknown;
|
|
44
|
+
grants: string[];
|
|
45
|
+
duplicateMode: boolean;
|
|
46
|
+
constructor(state: string, group?: unknown, entity?: unknown, refDataProvider?: ReferenceDataProvider, bundles?: Map<string, Map<string, Map<string, string>>>, grants?: string[], screenName?: string, language?: string);
|
|
47
|
+
setReferenceDataProvider(provider: ReferenceDataProvider): void;
|
|
48
|
+
get ref(): {
|
|
49
|
+
get: (key: string) => Signal<any[]>;
|
|
50
|
+
has: (key: string) => boolean;
|
|
51
|
+
};
|
|
52
|
+
getLabel(key: string): string;
|
|
53
|
+
isGranted(permission: PermissionsEnum): boolean;
|
|
54
|
+
isReadOnly(): boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
declare enum SortDirectionEnum {
|
|
58
|
+
ASC = "Ascending",
|
|
59
|
+
DESC = "Descending",
|
|
60
|
+
DEFAULT_SORT_FIELD = "id"
|
|
61
|
+
}
|
|
62
|
+
declare enum PaginationEnum {
|
|
63
|
+
DEFAULT_PAGE = 1,
|
|
64
|
+
DEFAULT_PAGE_SIZE = 10
|
|
65
|
+
}
|
|
66
|
+
declare class SearchEntity extends AbstractEntity {
|
|
67
|
+
pagination: {
|
|
68
|
+
pageNumber: number;
|
|
69
|
+
pageSize: number;
|
|
70
|
+
};
|
|
71
|
+
sort: Array<{
|
|
72
|
+
field: string;
|
|
73
|
+
sortDirection: string;
|
|
74
|
+
}>;
|
|
75
|
+
totalPages: number;
|
|
76
|
+
totalCount: number;
|
|
77
|
+
items: AbstractEntity[];
|
|
78
|
+
start: Date | null;
|
|
79
|
+
end: Date | null;
|
|
80
|
+
startEndDateRanges: Date[] | null;
|
|
81
|
+
constructor(entity: Record<string, unknown>);
|
|
82
|
+
getSearchCriteria(): Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface DefaultSort {
|
|
86
|
+
field: string;
|
|
87
|
+
direction: SortDirectionEnum;
|
|
88
|
+
}
|
|
89
|
+
interface LoadOptions {
|
|
90
|
+
bypassCache?: boolean;
|
|
91
|
+
ttl?: number;
|
|
92
|
+
forceRefresh?: boolean;
|
|
93
|
+
useSql?: boolean;
|
|
94
|
+
}
|
|
95
|
+
declare abstract class ScreenConfig {
|
|
96
|
+
SCREEN: string;
|
|
97
|
+
SERVICE: unknown;
|
|
98
|
+
SEARCH_REFERENTIALS_KEYS: string[];
|
|
99
|
+
DETAILS_REFERENTIALS_KEYS: string[];
|
|
100
|
+
SEARCH_STATIC_LISTS: string[];
|
|
101
|
+
DETAILS_STATIC_LISTS: string[];
|
|
102
|
+
INVALIDATE_KEYS_ON_SAVE?: string[];
|
|
103
|
+
REFRESH_ON_SAVE?: boolean;
|
|
104
|
+
REF_DATA_OPTIONS?: LoadOptions;
|
|
105
|
+
DEFAULT_SORT?: DefaultSort;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Abstract interface for reference data services used by screen components.
|
|
110
|
+
* Apps must implement this interface and provide it via SCREEN_REF_DATA_SERVICE token.
|
|
111
|
+
*
|
|
112
|
+
* Extends ReferenceDataProvider (getReference/hasReference for ScreenContext)
|
|
113
|
+
* with methods for loading, refreshing, and invalidating reference data.
|
|
114
|
+
*/
|
|
115
|
+
interface ScreenReferenceDataService extends ReferenceDataProvider {
|
|
116
|
+
/**
|
|
117
|
+
* Load dynamic reference data by keys
|
|
118
|
+
* @param keys Array of reference data keys to load
|
|
119
|
+
* @param options Optional load options (bypassCache, ttl, forceRefresh)
|
|
120
|
+
*/
|
|
121
|
+
loadReferenceKeys(keys: string[], options?: LoadOptions): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Load static reference data by type names
|
|
124
|
+
* @param types Array of static reference type names
|
|
125
|
+
* @param forceRefresh Force reload from server
|
|
126
|
+
*/
|
|
127
|
+
loadStaticRefs(types: string[], forceRefresh?: boolean): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Refresh reference data keys (force reload from server)
|
|
130
|
+
* @param keys Array of keys to refresh
|
|
131
|
+
* @param bypassCache Bypass cache entirely
|
|
132
|
+
*/
|
|
133
|
+
refreshKeys(keys: string[], bypassCache?: boolean): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Invalidate reference data keys (mark as stale)
|
|
136
|
+
* @param keys Array of keys to invalidate
|
|
137
|
+
*/
|
|
138
|
+
invalidateKeys(keys: string[]): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Injection token for the screen reference data service.
|
|
142
|
+
* Apps must provide this token with their concrete implementation.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* // In app module or component providers:
|
|
146
|
+
* { provide: SCREEN_REF_DATA_SERVICE, useExisting: ReferenceDataService }
|
|
147
|
+
*/
|
|
148
|
+
declare const SCREEN_REF_DATA_SERVICE: InjectionToken<ScreenReferenceDataService>;
|
|
149
|
+
|
|
150
|
+
declare abstract class AbstractScreenComponent extends AbstractComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
151
|
+
context: ScreenContext;
|
|
152
|
+
connectedUser: any;
|
|
153
|
+
entityForm: NgForm;
|
|
154
|
+
serverErrors: i0.WritableSignal<{
|
|
155
|
+
[key: string]: string[];
|
|
156
|
+
}>;
|
|
157
|
+
protected refDataLoaded$: Subject<void>;
|
|
158
|
+
cacheService: CacheService;
|
|
159
|
+
changeDetector: ChangeDetectorRef;
|
|
160
|
+
toastService: ToastService;
|
|
161
|
+
confirmDialogService: ConfirmDialogService;
|
|
162
|
+
router: Router;
|
|
163
|
+
route: ActivatedRoute;
|
|
164
|
+
refDataService: ScreenReferenceDataService;
|
|
165
|
+
currentUrl: string;
|
|
166
|
+
protected abstract readonly screenState: string | null;
|
|
167
|
+
get state(): string | null;
|
|
168
|
+
screenStateKey: string;
|
|
169
|
+
ngOnInit(): void;
|
|
170
|
+
ngAfterViewInit(): void;
|
|
171
|
+
processGrants(): void;
|
|
172
|
+
isFormValid(): boolean;
|
|
173
|
+
getConfig(): any;
|
|
174
|
+
getBundleName(): string;
|
|
175
|
+
setFormErrors(errors: {
|
|
176
|
+
[key: string]: string[];
|
|
177
|
+
}): void;
|
|
178
|
+
referentialKeys: any;
|
|
179
|
+
staticListKeys: string[];
|
|
180
|
+
initializeReferenceKeys(keys: string[]): void;
|
|
181
|
+
initializeStaticLists(keys: string[]): void;
|
|
182
|
+
loadReferenceData(options?: LoadOptions): Promise<void>;
|
|
183
|
+
refreshReferenceData(keys?: string[]): Promise<void>;
|
|
184
|
+
refreshStaticLists(): Promise<void>;
|
|
185
|
+
invalidateReference(key: string): Promise<void>;
|
|
186
|
+
invalidateReferences(keys: string[]): Promise<void>;
|
|
187
|
+
handleErrors(errors: string[]): void;
|
|
188
|
+
setServerErrors(errors: {
|
|
189
|
+
[key: string]: string[];
|
|
190
|
+
}): void;
|
|
191
|
+
clearServerErrors(): void;
|
|
192
|
+
disableAllControls(): void;
|
|
193
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AbstractScreenComponent, never>;
|
|
194
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AbstractScreenComponent, "ng-component", never, { "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
declare enum ScreenStateEnum {
|
|
198
|
+
READ_ONLY = "READ_ONLY",
|
|
199
|
+
DETAIL = "DETAIL",
|
|
200
|
+
SEARCH = "SEARCH",
|
|
201
|
+
CUSTOM = "CUSTOM"
|
|
202
|
+
}
|
|
203
|
+
declare enum StateUtilsEnum {
|
|
204
|
+
REMOVE = "removeState",
|
|
205
|
+
ADD = "addState",
|
|
206
|
+
DUPLICATE = "duplicateState",
|
|
207
|
+
EDIT = "editState",
|
|
208
|
+
EDIT_AFTER_ERROR = "editAfterErrorState",
|
|
209
|
+
ADD_AFTER_ERROR = "addAfterErrorState",
|
|
210
|
+
SAVE = "afterSaveState"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
declare abstract class AbstractDetailScreenComponent extends AbstractScreenComponent implements AfterViewInit, OnInit, OnDestroy {
|
|
214
|
+
protected readonly screenState = ScreenStateEnum.DETAIL;
|
|
215
|
+
entity: any;
|
|
216
|
+
entityId: any;
|
|
217
|
+
editionState: boolean;
|
|
218
|
+
duplicateMode: boolean;
|
|
219
|
+
private location;
|
|
220
|
+
protected injector: Injector;
|
|
221
|
+
private serviceInstance;
|
|
222
|
+
ngOnInit(): void;
|
|
223
|
+
ngAfterViewInit(): void;
|
|
224
|
+
loadData(): void;
|
|
225
|
+
protected afterLoad(): void;
|
|
226
|
+
abstract beforeSave(): void;
|
|
227
|
+
save(): void;
|
|
228
|
+
protected onSaveError(_errors: {
|
|
229
|
+
[key: string]: string[];
|
|
230
|
+
}): void;
|
|
231
|
+
protected afterSave(result: any): void;
|
|
232
|
+
protected prepareEntityForDuplication(): any;
|
|
233
|
+
protected customizeDuplicatedEntity(entity: any): any;
|
|
234
|
+
duplicate(): void;
|
|
235
|
+
print(): void;
|
|
236
|
+
delete(): void;
|
|
237
|
+
navigateBack(): void;
|
|
238
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AbstractDetailScreenComponent, never>;
|
|
239
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AbstractDetailScreenComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Column definition interface for ef-datatable integration.
|
|
244
|
+
* Kept minimal here to avoid circular dependency on @elasticias/ui.
|
|
245
|
+
*/
|
|
246
|
+
interface ScreenDatatableColumn {
|
|
247
|
+
field: string;
|
|
248
|
+
header: string;
|
|
249
|
+
type?: string;
|
|
250
|
+
[key: string]: any;
|
|
251
|
+
}
|
|
252
|
+
declare abstract class AbstractSearchScreenComponent extends AbstractScreenComponent implements AfterViewInit, OnInit, OnDestroy {
|
|
253
|
+
protected readonly screenState = ScreenStateEnum.SEARCH;
|
|
254
|
+
pTable: Table;
|
|
255
|
+
entity: any;
|
|
256
|
+
searchEntity: SearchEntity;
|
|
257
|
+
enableDateRangeFilter: boolean;
|
|
258
|
+
isLazySearch: boolean;
|
|
259
|
+
lastSearchEvent: TableLazyLoadEvent | null;
|
|
260
|
+
tableColumns: any[];
|
|
261
|
+
protected injector: Injector;
|
|
262
|
+
private serviceInstance;
|
|
263
|
+
private isInitialLoad;
|
|
264
|
+
ngOnInit(): void;
|
|
265
|
+
protected getTableColumns(): any[];
|
|
266
|
+
private triggerSearchIfNeeded;
|
|
267
|
+
onLazyLoad(event: TableLazyLoadEvent): void;
|
|
268
|
+
private isReactiveBindingEcho;
|
|
269
|
+
private prepareSearch;
|
|
270
|
+
protected search(event?: TableLazyLoadEvent | null): void;
|
|
271
|
+
paginate(event: any): void;
|
|
272
|
+
getPageNumber(event: TableLazyLoadEvent): number;
|
|
273
|
+
getSortField(event: TableLazyLoadEvent): string;
|
|
274
|
+
getSortDirection(event: TableLazyLoadEvent): string;
|
|
275
|
+
navigateToDetails(id?: any): void;
|
|
276
|
+
add(): void;
|
|
277
|
+
edit(id: any): void;
|
|
278
|
+
delete(id: any): void;
|
|
279
|
+
duplicate(id: any): void;
|
|
280
|
+
clear(): void;
|
|
281
|
+
ngOnDestroy(): void;
|
|
282
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AbstractSearchScreenComponent, never>;
|
|
283
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AbstractSearchScreenComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
declare abstract class AbstractSubScreenComponent extends AbstractScreenComponent {
|
|
287
|
+
protected readonly screenState: null;
|
|
288
|
+
ngOnInit(): void;
|
|
289
|
+
ngAfterViewInit(): void;
|
|
290
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AbstractSubScreenComponent, never>;
|
|
291
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AbstractSubScreenComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
declare class ViewModelEntity extends AbstractEntity {
|
|
295
|
+
constructor(entity: Record<string, unknown>);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { AbstractComponent, AbstractDetailScreenComponent, AbstractEntity, AbstractScreenComponent, AbstractSearchScreenComponent, AbstractSubScreenComponent, PaginationEnum, SCREEN_REF_DATA_SERVICE, ScreenConfig, ScreenContext, ScreenStateEnum, SearchEntity, SortDirectionEnum, StateUtilsEnum, ViewModelEntity };
|
|
299
|
+
export type { DefaultSort, LoadOptions, ReferenceDataProvider, ScreenDatatableColumn, ScreenReferenceDataService };
|