@flusys/ng-shared 1.1.1-beta → 1.2.0-rc.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.
- package/README.md +88 -1216
- package/fesm2022/flusys-ng-shared.mjs +3553 -2119
- package/fesm2022/flusys-ng-shared.mjs.map +1 -1
- package/package.json +9 -8
- package/types/flusys-ng-shared.d.ts +1023 -1181
|
@@ -1,90 +1,263 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { Signal, Injector, ResourceRef, model, ElementRef, InjectionToken } from '@angular/core';
|
|
1
|
+
import * as rxjs from 'rxjs';
|
|
3
2
|
import { Observable } from 'rxjs';
|
|
3
|
+
import * as _angular_core from '@angular/core';
|
|
4
|
+
import { Signal, PipeTransform, ResourceRef, ResourceStatus, Injector, model, TemplateRef, OnDestroy, ElementRef, DestroyRef, InjectionToken } from '@angular/core';
|
|
5
|
+
import { HttpContextToken, HttpRequest, HttpHandlerFn, HttpEvent, HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
|
6
|
+
import * as i3 from '@angular/router';
|
|
7
|
+
import { ResolveFn, CanActivateFn } from '@angular/router';
|
|
4
8
|
import * as i1 from '@angular/common';
|
|
5
9
|
import * as i2 from '@angular/forms';
|
|
6
10
|
import { ControlValueAccessor } from '@angular/forms';
|
|
7
|
-
import * as i3 from '@angular/router';
|
|
8
|
-
import { CanActivateFn } from '@angular/router';
|
|
9
|
-
import * as i1$1 from 'primeng/autocomplete';
|
|
10
|
-
import * as i2$1 from 'primeng/avatar';
|
|
11
|
-
import * as i3$1 from 'primeng/button';
|
|
12
|
-
import * as i4 from 'primeng/card';
|
|
13
|
-
import * as i5 from 'primeng/checkbox';
|
|
14
|
-
import { CheckboxChangeEvent } from 'primeng/checkbox';
|
|
15
|
-
import * as i6 from 'primeng/confirmdialog';
|
|
16
|
-
import * as i7 from 'primeng/datepicker';
|
|
17
|
-
import * as i8 from 'primeng/dialog';
|
|
18
|
-
import * as i9 from 'primeng/divider';
|
|
19
|
-
import * as i10 from 'primeng/fileupload';
|
|
20
|
-
import * as i11 from 'primeng/iconfield';
|
|
21
|
-
import * as i12 from 'primeng/image';
|
|
22
|
-
import * as i13 from 'primeng/inputicon';
|
|
23
|
-
import * as i14 from 'primeng/inputnumber';
|
|
24
|
-
import * as i15 from 'primeng/inputtext';
|
|
25
|
-
import * as i16 from 'primeng/listbox';
|
|
26
|
-
import * as i17 from 'primeng/multiselect';
|
|
27
|
-
import * as i18 from 'primeng/paginator';
|
|
28
|
-
import * as i19 from 'primeng/panel';
|
|
29
|
-
import * as i20 from 'primeng/password';
|
|
30
|
-
import * as i21 from 'primeng/popover';
|
|
31
|
-
import * as i22 from 'primeng/progressbar';
|
|
32
|
-
import * as i23 from 'primeng/radiobutton';
|
|
33
|
-
import * as i24 from 'primeng/ripple';
|
|
34
|
-
import * as i25 from 'primeng/selectbutton';
|
|
35
|
-
import * as i26 from 'primeng/select';
|
|
36
|
-
import * as i27 from 'primeng/skeleton';
|
|
37
|
-
import * as i28 from 'primeng/splitbutton';
|
|
38
|
-
import * as i29 from 'primeng/steps';
|
|
39
|
-
import * as i30 from 'primeng/table';
|
|
40
|
-
import * as i31 from 'primeng/tabs';
|
|
41
|
-
import * as i32 from 'primeng/tag';
|
|
42
|
-
import * as i33 from 'primeng/textarea';
|
|
43
|
-
import * as i34 from 'primeng/toast';
|
|
44
|
-
import * as i35 from 'primeng/toggleswitch';
|
|
45
|
-
import * as i36 from 'primeng/tooltip';
|
|
46
|
-
import * as i37 from 'primeng/treetable';
|
|
47
11
|
import * as _flusys_ng_shared from '@flusys/ng-shared';
|
|
48
|
-
import {
|
|
49
|
-
import { ApiLoaderService } from '@flusys/ng-core';
|
|
12
|
+
import { ServiceName } from '@flusys/ng-core';
|
|
50
13
|
import { FormValueControl } from '@angular/forms/signals';
|
|
14
|
+
import * as _angular_platform_browser from '@angular/platform-browser';
|
|
15
|
+
import { CheckboxChangeEvent } from '@flusys/ng-ui';
|
|
51
16
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
17
|
+
declare const SHARED_MESSAGES: Record<string, string>;
|
|
18
|
+
|
|
19
|
+
declare const USER_PERMISSIONS: {
|
|
20
|
+
readonly CREATE: "user.create";
|
|
21
|
+
readonly READ: "user.read";
|
|
22
|
+
readonly UPDATE: "user.update";
|
|
23
|
+
readonly DELETE: "user.delete";
|
|
24
|
+
};
|
|
25
|
+
declare const COMPANY_PERMISSIONS: {
|
|
26
|
+
readonly CREATE: "company.create";
|
|
27
|
+
readonly READ: "company.read";
|
|
28
|
+
readonly UPDATE: "company.update";
|
|
29
|
+
readonly DELETE: "company.delete";
|
|
30
|
+
};
|
|
31
|
+
declare const BRANCH_PERMISSIONS: {
|
|
32
|
+
readonly CREATE: "branch.create";
|
|
33
|
+
readonly READ: "branch.read";
|
|
34
|
+
readonly UPDATE: "branch.update";
|
|
35
|
+
readonly DELETE: "branch.delete";
|
|
36
|
+
};
|
|
37
|
+
declare const ACTION_PERMISSIONS: {
|
|
38
|
+
readonly CREATE: "action.create";
|
|
39
|
+
readonly READ: "action.read";
|
|
40
|
+
readonly UPDATE: "action.update";
|
|
41
|
+
readonly DELETE: "action.delete";
|
|
42
|
+
};
|
|
43
|
+
declare const ROLE_PERMISSIONS: {
|
|
44
|
+
readonly CREATE: "role.create";
|
|
45
|
+
readonly READ: "role.read";
|
|
46
|
+
readonly UPDATE: "role.update";
|
|
47
|
+
readonly DELETE: "role.delete";
|
|
48
|
+
};
|
|
49
|
+
declare const ROLE_ACTION_PERMISSIONS: {
|
|
50
|
+
readonly READ: "role-action.read";
|
|
51
|
+
readonly ASSIGN: "role-action.assign";
|
|
52
|
+
};
|
|
53
|
+
declare const USER_ROLE_PERMISSIONS: {
|
|
54
|
+
readonly READ: "user-role.read";
|
|
55
|
+
readonly ASSIGN: "user-role.assign";
|
|
56
|
+
};
|
|
57
|
+
declare const USER_ACTION_PERMISSIONS: {
|
|
58
|
+
readonly READ: "user-action.read";
|
|
59
|
+
readonly ASSIGN: "user-action.assign";
|
|
60
|
+
};
|
|
61
|
+
declare const COMPANY_ACTION_PERMISSIONS: {
|
|
62
|
+
readonly READ: "company-action.read";
|
|
63
|
+
readonly ASSIGN: "company-action.assign";
|
|
64
|
+
};
|
|
65
|
+
declare const FILE_PERMISSIONS: {
|
|
66
|
+
readonly CREATE: "file.create";
|
|
67
|
+
readonly READ: "file.read";
|
|
68
|
+
readonly UPDATE: "file.update";
|
|
69
|
+
readonly DELETE: "file.delete";
|
|
70
|
+
};
|
|
71
|
+
declare const FOLDER_PERMISSIONS: {
|
|
72
|
+
readonly CREATE: "folder.create";
|
|
73
|
+
readonly READ: "folder.read";
|
|
74
|
+
readonly UPDATE: "folder.update";
|
|
75
|
+
readonly DELETE: "folder.delete";
|
|
76
|
+
};
|
|
77
|
+
declare const STORAGE_CONFIG_PERMISSIONS: {
|
|
78
|
+
readonly CREATE: "storage-config.create";
|
|
79
|
+
readonly READ: "storage-config.read";
|
|
80
|
+
readonly UPDATE: "storage-config.update";
|
|
81
|
+
readonly DELETE: "storage-config.delete";
|
|
82
|
+
};
|
|
83
|
+
declare const UPLOAD_CONFIG_PERMISSIONS: {
|
|
84
|
+
readonly DELETE: "upload-config.delete";
|
|
85
|
+
};
|
|
86
|
+
declare const EMAIL_CONFIG_PERMISSIONS: {
|
|
87
|
+
readonly CREATE: "email-config.create";
|
|
88
|
+
readonly READ: "email-config.read";
|
|
89
|
+
readonly UPDATE: "email-config.update";
|
|
90
|
+
readonly DELETE: "email-config.delete";
|
|
91
|
+
};
|
|
92
|
+
declare const EMAIL_TEMPLATE_PERMISSIONS: {
|
|
93
|
+
readonly CREATE: "email-template.create";
|
|
94
|
+
readonly READ: "email-template.read";
|
|
95
|
+
readonly UPDATE: "email-template.update";
|
|
96
|
+
readonly DELETE: "email-template.delete";
|
|
97
|
+
};
|
|
98
|
+
declare const FORM_PERMISSIONS: {
|
|
99
|
+
readonly CREATE: "form.create";
|
|
100
|
+
readonly READ: "form.read";
|
|
101
|
+
readonly UPDATE: "form.update";
|
|
102
|
+
readonly DELETE: "form.delete";
|
|
103
|
+
};
|
|
104
|
+
declare const FORM_RESULT_PERMISSIONS: {
|
|
105
|
+
readonly CREATE: "form-result.create";
|
|
106
|
+
readonly READ: "form-result.read";
|
|
107
|
+
readonly UPDATE: "form-result.update";
|
|
108
|
+
readonly DELETE: "form-result.delete";
|
|
109
|
+
};
|
|
110
|
+
declare const EVENT_PERMISSIONS: {
|
|
111
|
+
readonly CREATE: "event.create";
|
|
112
|
+
readonly READ: "event.read";
|
|
113
|
+
readonly UPDATE: "event.update";
|
|
114
|
+
readonly DELETE: "event.delete";
|
|
115
|
+
};
|
|
116
|
+
declare const NOTIFICATION_PERMISSIONS: {
|
|
117
|
+
readonly CREATE: "notification.create";
|
|
118
|
+
readonly READ: "notification.read";
|
|
119
|
+
readonly UPDATE: "notification.update";
|
|
120
|
+
readonly DELETE: "notification.delete";
|
|
121
|
+
};
|
|
122
|
+
declare const LANGUAGE_PERMISSIONS: {
|
|
123
|
+
readonly CREATE: "language.create";
|
|
124
|
+
readonly READ: "language.read";
|
|
125
|
+
readonly UPDATE: "language.update";
|
|
126
|
+
readonly DELETE: "language.delete";
|
|
127
|
+
};
|
|
128
|
+
declare const TRANSLATION_KEY_PERMISSIONS: {
|
|
129
|
+
readonly CREATE: "translation-key.create";
|
|
130
|
+
readonly READ: "translation-key.read";
|
|
131
|
+
readonly UPDATE: "translation-key.update";
|
|
132
|
+
readonly DELETE: "translation-key.delete";
|
|
133
|
+
};
|
|
134
|
+
declare const TRANSLATION_PERMISSIONS: {
|
|
135
|
+
readonly CREATE: "translation.create";
|
|
136
|
+
readonly READ: "translation.read";
|
|
137
|
+
readonly UPDATE: "translation.update";
|
|
138
|
+
readonly DELETE: "translation.delete";
|
|
139
|
+
};
|
|
140
|
+
declare const PERMISSIONS: {
|
|
141
|
+
readonly USER: {
|
|
142
|
+
readonly CREATE: "user.create";
|
|
143
|
+
readonly READ: "user.read";
|
|
144
|
+
readonly UPDATE: "user.update";
|
|
145
|
+
readonly DELETE: "user.delete";
|
|
146
|
+
};
|
|
147
|
+
readonly COMPANY: {
|
|
148
|
+
readonly CREATE: "company.create";
|
|
149
|
+
readonly READ: "company.read";
|
|
150
|
+
readonly UPDATE: "company.update";
|
|
151
|
+
readonly DELETE: "company.delete";
|
|
152
|
+
};
|
|
153
|
+
readonly BRANCH: {
|
|
154
|
+
readonly CREATE: "branch.create";
|
|
155
|
+
readonly READ: "branch.read";
|
|
156
|
+
readonly UPDATE: "branch.update";
|
|
157
|
+
readonly DELETE: "branch.delete";
|
|
158
|
+
};
|
|
159
|
+
readonly ACTION: {
|
|
160
|
+
readonly CREATE: "action.create";
|
|
161
|
+
readonly READ: "action.read";
|
|
162
|
+
readonly UPDATE: "action.update";
|
|
163
|
+
readonly DELETE: "action.delete";
|
|
164
|
+
};
|
|
165
|
+
readonly ROLE: {
|
|
166
|
+
readonly CREATE: "role.create";
|
|
167
|
+
readonly READ: "role.read";
|
|
168
|
+
readonly UPDATE: "role.update";
|
|
169
|
+
readonly DELETE: "role.delete";
|
|
170
|
+
};
|
|
171
|
+
readonly ROLE_ACTION: {
|
|
172
|
+
readonly READ: "role-action.read";
|
|
173
|
+
readonly ASSIGN: "role-action.assign";
|
|
174
|
+
};
|
|
175
|
+
readonly USER_ROLE: {
|
|
176
|
+
readonly READ: "user-role.read";
|
|
177
|
+
readonly ASSIGN: "user-role.assign";
|
|
178
|
+
};
|
|
179
|
+
readonly USER_ACTION: {
|
|
180
|
+
readonly READ: "user-action.read";
|
|
181
|
+
readonly ASSIGN: "user-action.assign";
|
|
182
|
+
};
|
|
183
|
+
readonly COMPANY_ACTION: {
|
|
184
|
+
readonly READ: "company-action.read";
|
|
185
|
+
readonly ASSIGN: "company-action.assign";
|
|
186
|
+
};
|
|
187
|
+
readonly FILE: {
|
|
188
|
+
readonly CREATE: "file.create";
|
|
189
|
+
readonly READ: "file.read";
|
|
190
|
+
readonly UPDATE: "file.update";
|
|
191
|
+
readonly DELETE: "file.delete";
|
|
192
|
+
};
|
|
193
|
+
readonly FOLDER: {
|
|
194
|
+
readonly CREATE: "folder.create";
|
|
195
|
+
readonly READ: "folder.read";
|
|
196
|
+
readonly UPDATE: "folder.update";
|
|
197
|
+
readonly DELETE: "folder.delete";
|
|
198
|
+
};
|
|
199
|
+
readonly STORAGE_CONFIG: {
|
|
200
|
+
readonly CREATE: "storage-config.create";
|
|
201
|
+
readonly READ: "storage-config.read";
|
|
202
|
+
readonly UPDATE: "storage-config.update";
|
|
203
|
+
readonly DELETE: "storage-config.delete";
|
|
204
|
+
};
|
|
205
|
+
readonly EMAIL_CONFIG: {
|
|
206
|
+
readonly CREATE: "email-config.create";
|
|
207
|
+
readonly READ: "email-config.read";
|
|
208
|
+
readonly UPDATE: "email-config.update";
|
|
209
|
+
readonly DELETE: "email-config.delete";
|
|
210
|
+
};
|
|
211
|
+
readonly EMAIL_TEMPLATE: {
|
|
212
|
+
readonly CREATE: "email-template.create";
|
|
213
|
+
readonly READ: "email-template.read";
|
|
214
|
+
readonly UPDATE: "email-template.update";
|
|
215
|
+
readonly DELETE: "email-template.delete";
|
|
216
|
+
};
|
|
217
|
+
readonly FORM: {
|
|
218
|
+
readonly CREATE: "form.create";
|
|
219
|
+
readonly READ: "form.read";
|
|
220
|
+
readonly UPDATE: "form.update";
|
|
221
|
+
readonly DELETE: "form.delete";
|
|
222
|
+
};
|
|
223
|
+
readonly FORM_RESULT: {
|
|
224
|
+
readonly CREATE: "form-result.create";
|
|
225
|
+
readonly READ: "form-result.read";
|
|
226
|
+
readonly UPDATE: "form-result.update";
|
|
227
|
+
readonly DELETE: "form-result.delete";
|
|
228
|
+
};
|
|
229
|
+
readonly EVENT: {
|
|
230
|
+
readonly CREATE: "event.create";
|
|
231
|
+
readonly READ: "event.read";
|
|
232
|
+
readonly UPDATE: "event.update";
|
|
233
|
+
readonly DELETE: "event.delete";
|
|
234
|
+
};
|
|
235
|
+
readonly NOTIFICATION: {
|
|
236
|
+
readonly CREATE: "notification.create";
|
|
237
|
+
readonly READ: "notification.read";
|
|
238
|
+
readonly UPDATE: "notification.update";
|
|
239
|
+
readonly DELETE: "notification.delete";
|
|
240
|
+
};
|
|
241
|
+
readonly LANGUAGE: {
|
|
242
|
+
readonly CREATE: "language.create";
|
|
243
|
+
readonly READ: "language.read";
|
|
244
|
+
readonly UPDATE: "language.update";
|
|
245
|
+
readonly DELETE: "language.delete";
|
|
246
|
+
};
|
|
247
|
+
readonly TRANSLATION_KEY: {
|
|
248
|
+
readonly CREATE: "translation-key.create";
|
|
249
|
+
readonly READ: "translation-key.read";
|
|
250
|
+
readonly UPDATE: "translation-key.update";
|
|
251
|
+
readonly DELETE: "translation-key.delete";
|
|
252
|
+
};
|
|
253
|
+
readonly TRANSLATION: {
|
|
254
|
+
readonly CREATE: "translation.create";
|
|
255
|
+
readonly READ: "translation.read";
|
|
256
|
+
readonly UPDATE: "translation.update";
|
|
257
|
+
readonly DELETE: "translation.delete";
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
type PermissionCode = (typeof PERMISSIONS)[keyof typeof PERMISSIONS][keyof (typeof PERMISSIONS)[keyof typeof PERMISSIONS]];
|
|
88
261
|
|
|
89
262
|
/**
|
|
90
263
|
* Base entity interface - matches backend Identity entity
|
|
@@ -123,12 +296,6 @@ interface IActivatable {
|
|
|
123
296
|
interface IOrderable {
|
|
124
297
|
serial?: number | null;
|
|
125
298
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Entity with metadata JSON field
|
|
128
|
-
*/
|
|
129
|
-
interface IMetadata {
|
|
130
|
-
metadata?: Record<string, unknown> | null;
|
|
131
|
-
}
|
|
132
299
|
/**
|
|
133
300
|
* Logged-in user info - matches backend ILoggedUserInfo
|
|
134
301
|
*/
|
|
@@ -143,6 +310,42 @@ interface ILoggedUserInfo {
|
|
|
143
310
|
companyLogoId?: string;
|
|
144
311
|
branchLogoId?: string;
|
|
145
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Simple dropdown item for select components
|
|
315
|
+
*/
|
|
316
|
+
interface IDropDown {
|
|
317
|
+
label: string;
|
|
318
|
+
value: string;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Delete operation types
|
|
322
|
+
* - 'delete': Soft delete (sets deletedAt timestamp)
|
|
323
|
+
* - 'restore': Restore soft-deleted item (clears deletedAt)
|
|
324
|
+
* - 'permanent': Permanently delete from database
|
|
325
|
+
*/
|
|
326
|
+
type DeleteType = 'delete' | 'restore' | 'permanent';
|
|
327
|
+
/**
|
|
328
|
+
* Delete request payload - matches backend DeleteDto
|
|
329
|
+
*/
|
|
330
|
+
interface IDeleteData {
|
|
331
|
+
/** Single ID or array of IDs to delete */
|
|
332
|
+
id: string | string[];
|
|
333
|
+
/** Type of delete operation */
|
|
334
|
+
type: DeleteType;
|
|
335
|
+
}
|
|
336
|
+
/** Action node - checks a single permission */
|
|
337
|
+
interface IActionNode {
|
|
338
|
+
type: 'action';
|
|
339
|
+
actionId: string;
|
|
340
|
+
}
|
|
341
|
+
/** Group node - combines children with AND/OR logic */
|
|
342
|
+
interface IGroupNode {
|
|
343
|
+
type: 'group';
|
|
344
|
+
operator: 'AND' | 'OR';
|
|
345
|
+
children: ILogicNode[];
|
|
346
|
+
}
|
|
347
|
+
/** Permission logic tree (discriminated union of action/group) */
|
|
348
|
+
type ILogicNode = IActionNode | IGroupNode;
|
|
146
349
|
|
|
147
350
|
/**
|
|
148
351
|
* Request metadata added by backend ResponseMetaInterceptor
|
|
@@ -171,20 +374,14 @@ interface IBulkMeta {
|
|
|
171
374
|
failed?: number;
|
|
172
375
|
total?: number;
|
|
173
376
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Validation error detail
|
|
176
|
-
*/
|
|
177
|
-
interface IValidationError {
|
|
178
|
-
field: string;
|
|
179
|
-
message: string;
|
|
180
|
-
constraint?: string;
|
|
181
|
-
}
|
|
182
377
|
/**
|
|
183
378
|
* Single item response (insert, update, get-by-id)
|
|
184
379
|
*/
|
|
185
380
|
interface ISingleResponse<T> {
|
|
186
381
|
success: boolean;
|
|
187
382
|
message: string;
|
|
383
|
+
messageKey?: string;
|
|
384
|
+
messageVariables?: Record<string, unknown>;
|
|
188
385
|
data?: T;
|
|
189
386
|
_meta?: IRequestMeta;
|
|
190
387
|
}
|
|
@@ -194,6 +391,8 @@ interface ISingleResponse<T> {
|
|
|
194
391
|
interface IListResponse<T> {
|
|
195
392
|
success: boolean;
|
|
196
393
|
message: string;
|
|
394
|
+
messageKey?: string;
|
|
395
|
+
messageVariables?: Record<string, unknown>;
|
|
197
396
|
data?: T[];
|
|
198
397
|
meta: IPaginationMeta;
|
|
199
398
|
_meta?: IRequestMeta;
|
|
@@ -204,6 +403,8 @@ interface IListResponse<T> {
|
|
|
204
403
|
interface IBulkResponse<T> {
|
|
205
404
|
success: boolean;
|
|
206
405
|
message: string;
|
|
406
|
+
messageKey?: string;
|
|
407
|
+
messageVariables?: Record<string, unknown>;
|
|
207
408
|
data?: T[];
|
|
208
409
|
meta: IBulkMeta;
|
|
209
410
|
_meta?: IRequestMeta;
|
|
@@ -214,128 +415,74 @@ interface IBulkResponse<T> {
|
|
|
214
415
|
interface IMessageResponse {
|
|
215
416
|
success: boolean;
|
|
216
417
|
message: string;
|
|
418
|
+
messageKey?: string;
|
|
419
|
+
messageVariables?: Record<string, unknown>;
|
|
217
420
|
_meta?: IRequestMeta;
|
|
218
421
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
*/
|
|
222
|
-
interface IErrorResponse {
|
|
223
|
-
success: false;
|
|
224
|
-
message: string;
|
|
225
|
-
code?: string;
|
|
226
|
-
errors?: IValidationError[];
|
|
227
|
-
_meta?: IRequestMeta;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Union type for all API responses
|
|
231
|
-
*/
|
|
232
|
-
type ApiResponse<T> = ISingleResponse<T> | IListResponse<T> | IBulkResponse<T> | IMessageResponse | IErrorResponse;
|
|
233
|
-
interface IUserCompanyPayload {
|
|
422
|
+
|
|
423
|
+
interface IFileBasicInfo {
|
|
234
424
|
id: string;
|
|
235
425
|
name: string;
|
|
236
|
-
|
|
237
|
-
|
|
426
|
+
contentType: string;
|
|
427
|
+
size: string;
|
|
428
|
+
url: string | null;
|
|
238
429
|
}
|
|
239
|
-
interface
|
|
240
|
-
id
|
|
430
|
+
interface IUploadedFile {
|
|
431
|
+
id?: string;
|
|
241
432
|
name: string;
|
|
242
|
-
|
|
243
|
-
|
|
433
|
+
key: string;
|
|
434
|
+
size: number;
|
|
435
|
+
contentType: string;
|
|
244
436
|
}
|
|
245
|
-
interface
|
|
437
|
+
interface IFolderBasicInfo {
|
|
246
438
|
id: string;
|
|
247
439
|
name: string;
|
|
248
|
-
|
|
249
|
-
phone?: string;
|
|
250
|
-
profilePictureId?: string | null;
|
|
251
|
-
companyId?: string;
|
|
252
|
-
branchId?: string;
|
|
253
|
-
company?: IUserCompanyPayload;
|
|
254
|
-
branch?: IUserBranchPayload;
|
|
255
|
-
}
|
|
256
|
-
interface ILoginResponse {
|
|
257
|
-
success: boolean;
|
|
258
|
-
message: string;
|
|
259
|
-
data: {
|
|
260
|
-
accessToken: string;
|
|
261
|
-
refreshToken: string;
|
|
262
|
-
user: ILoginUserData;
|
|
263
|
-
};
|
|
264
|
-
_meta?: IRequestMeta;
|
|
265
|
-
}
|
|
266
|
-
interface IRefreshTokenResponse {
|
|
267
|
-
success: boolean;
|
|
268
|
-
message: string;
|
|
269
|
-
data: {
|
|
270
|
-
accessToken: string;
|
|
271
|
-
refreshToken?: string;
|
|
272
|
-
};
|
|
273
|
-
_meta?: IRequestMeta;
|
|
440
|
+
slug: string;
|
|
274
441
|
}
|
|
275
|
-
interface
|
|
442
|
+
interface IStorageConfigBasicInfo {
|
|
276
443
|
id: string;
|
|
277
444
|
name: string;
|
|
278
|
-
|
|
279
|
-
contentType: string;
|
|
280
|
-
size: number;
|
|
281
|
-
key: string;
|
|
282
|
-
url?: string;
|
|
283
|
-
thumbnailUrl?: string;
|
|
284
|
-
createdAt: Date;
|
|
445
|
+
isDefault: boolean;
|
|
285
446
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
interface ICompanyApiProvider {
|
|
296
|
-
/**
|
|
297
|
-
* Get list of companies with pagination
|
|
298
|
-
*/
|
|
299
|
-
getCompanies(filter?: {
|
|
300
|
-
page?: number;
|
|
301
|
-
pageSize?: number;
|
|
302
|
-
search?: string;
|
|
303
|
-
[key: string]: any;
|
|
304
|
-
}): Observable<IListResponse<ICompanyBasicInfo>>;
|
|
447
|
+
interface IFileUploadOptions {
|
|
448
|
+
storageConfigId?: string;
|
|
449
|
+
folderPath?: string;
|
|
450
|
+
maxWidth?: number;
|
|
451
|
+
maxHeight?: number;
|
|
452
|
+
quality?: number;
|
|
453
|
+
compress?: boolean;
|
|
454
|
+
isPrivate?: boolean;
|
|
305
455
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
* - 'restore': Restore soft-deleted item (clears deletedAt)
|
|
311
|
-
* - 'permanent': Permanently delete from database
|
|
312
|
-
*/
|
|
313
|
-
type DeleteType = 'delete' | 'restore' | 'permanent';
|
|
314
|
-
/**
|
|
315
|
-
* Delete request payload - matches backend DeleteDto
|
|
316
|
-
*/
|
|
317
|
-
interface IDeleteData {
|
|
318
|
-
/** Single ID or array of IDs to delete */
|
|
319
|
-
id: string | string[];
|
|
320
|
-
/** Type of delete operation */
|
|
321
|
-
type: DeleteType;
|
|
456
|
+
interface ISelectFilter {
|
|
457
|
+
page: number;
|
|
458
|
+
pageSize: number;
|
|
459
|
+
search: string;
|
|
322
460
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
461
|
+
interface IFileSelectFilter extends ISelectFilter {
|
|
462
|
+
contentTypes?: string[];
|
|
463
|
+
folderId?: string;
|
|
464
|
+
storageConfigId?: string;
|
|
327
465
|
}
|
|
466
|
+
type UploadFileFn = (file: File, options?: IFileUploadOptions) => Observable<ISingleResponse<IUploadedFile>>;
|
|
467
|
+
type UploadMultipleFilesFn = (files: File[], options?: IFileUploadOptions) => Observable<ISingleResponse<IUploadedFile[]>>;
|
|
468
|
+
declare const FILE_TYPE_FILTERS: {
|
|
469
|
+
readonly IMAGES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
|
|
470
|
+
readonly DOCUMENTS: readonly ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"];
|
|
471
|
+
readonly VIDEOS: readonly ["video/mp4", "video/webm", "video/ogg", "video/quicktime"];
|
|
472
|
+
readonly AUDIO: readonly ["audio/mpeg", "audio/wav", "audio/ogg", "audio/webm"];
|
|
473
|
+
readonly ALL: string[];
|
|
474
|
+
};
|
|
475
|
+
declare function getAcceptString(contentTypes: string[]): string;
|
|
476
|
+
declare function isFileTypeAllowed(file: File, allowedTypes: string[]): boolean;
|
|
477
|
+
declare function getFileIconClass(contentType: string): string;
|
|
478
|
+
declare function formatFileSize(sizeInKb: string | number): string;
|
|
328
479
|
|
|
329
480
|
interface IPagination {
|
|
330
481
|
pageSize: number;
|
|
331
482
|
currentPage: number;
|
|
332
483
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
interface IFilter {
|
|
337
|
-
[key: string]: any;
|
|
338
|
-
}
|
|
484
|
+
type ISort = Record<string, 'ASC' | 'DESC'>;
|
|
485
|
+
type IFilter = Record<string, string | number | boolean | null | undefined | string[] | number[]>;
|
|
339
486
|
interface IFilterData {
|
|
340
487
|
filter?: IFilter;
|
|
341
488
|
pagination?: IPagination;
|
|
@@ -345,46 +492,18 @@ interface IFilterData {
|
|
|
345
492
|
extraKey?: string[];
|
|
346
493
|
}
|
|
347
494
|
|
|
348
|
-
/** Action node - checks a single permission */
|
|
349
|
-
interface IActionNode {
|
|
350
|
-
type: 'action';
|
|
351
|
-
actionId: string;
|
|
352
|
-
}
|
|
353
|
-
/** Group node - combines children with AND/OR logic */
|
|
354
|
-
interface IGroupNode {
|
|
355
|
-
type: 'group';
|
|
356
|
-
operator: 'AND' | 'OR';
|
|
357
|
-
children: ILogicNode[];
|
|
358
|
-
}
|
|
359
|
-
/** Permission logic tree (discriminated union of action/group) */
|
|
360
|
-
type ILogicNode = IActionNode | IGroupNode;
|
|
361
|
-
|
|
362
495
|
/**
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
* Abstracts user permission data access operations.
|
|
366
|
-
* Implemented by auth package, used by IAM for user permission queries.
|
|
367
|
-
*
|
|
368
|
-
* @example
|
|
369
|
-
* // In IAM component
|
|
370
|
-
* class UserActionSelectorComponent {
|
|
371
|
-
* private readonly userPermissionProvider = inject(USER_PERMISSION_PROVIDER);
|
|
496
|
+
* Auth State Provider Interface
|
|
372
497
|
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* .getUserBranchPermissions(userId, '')
|
|
376
|
-
* .toPromise();
|
|
377
|
-
* this.branches.set(response?.data ?? []);
|
|
378
|
-
* }
|
|
379
|
-
* }
|
|
498
|
+
* Abstracts auth state access for feature packages (form-builder, etc.)
|
|
499
|
+
* that need to check authentication status without depending on ng-auth directly.
|
|
380
500
|
*/
|
|
381
|
-
interface
|
|
382
|
-
/**
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
501
|
+
interface IAuthStateProvider {
|
|
502
|
+
/** Signal indicating if user is currently authenticated */
|
|
503
|
+
isAuthenticated: Signal<boolean>;
|
|
504
|
+
/** Initialize auth state (restore session from cookies/storage) */
|
|
505
|
+
initialize(): Observable<void>;
|
|
386
506
|
}
|
|
387
|
-
|
|
388
507
|
/**
|
|
389
508
|
* User data for dropdowns and selectors
|
|
390
509
|
*/
|
|
@@ -394,381 +513,103 @@ interface IUserBasicInfo {
|
|
|
394
513
|
email: string;
|
|
395
514
|
}
|
|
396
515
|
/**
|
|
397
|
-
* User Provider Interface
|
|
398
|
-
*
|
|
399
|
-
* Abstracts user data access for IAM and other feature packages.
|
|
400
|
-
* Implemented by auth package, used by IAM for user selection in permission assignment.
|
|
401
|
-
*
|
|
402
|
-
* @example
|
|
403
|
-
* // In IAM component
|
|
404
|
-
* class UserActionSelectorComponent {
|
|
405
|
-
* private readonly userProvider = inject(USER_PROVIDER);
|
|
406
|
-
*
|
|
407
|
-
* loadUsers() {
|
|
408
|
-
* this.userProvider.getUsers({ page: 0, pageSize: 50 }).subscribe(users => {
|
|
409
|
-
* this.users.set(users.data);
|
|
410
|
-
* });
|
|
411
|
-
* }
|
|
412
|
-
* }
|
|
516
|
+
* User Provider Interface - Abstracts user data access for IAM and other feature packages.
|
|
413
517
|
*/
|
|
414
518
|
interface IUserProvider {
|
|
415
|
-
/**
|
|
416
|
-
* Get list of users with pagination
|
|
417
|
-
* @param filter Optional filter (page, pageSize, search, etc.)
|
|
418
|
-
*/
|
|
419
519
|
getUsers(filter?: {
|
|
420
520
|
page?: number;
|
|
421
521
|
pageSize?: number;
|
|
422
522
|
search?: string;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
[key: string]: any;
|
|
523
|
+
isActive?: boolean;
|
|
524
|
+
[key: string]: unknown;
|
|
426
525
|
}): Observable<IListResponse<IUserBasicInfo>>;
|
|
427
526
|
}
|
|
428
|
-
|
|
429
527
|
/** Filter params passed to loadUsers function */
|
|
430
528
|
interface IUserSelectFilter {
|
|
431
529
|
page: number;
|
|
432
530
|
pageSize: number;
|
|
433
531
|
search: string;
|
|
434
|
-
[key: string]: unknown;
|
|
435
532
|
}
|
|
436
533
|
/** Function type for loading users */
|
|
437
534
|
type LoadUsersFn = (filter: IUserSelectFilter) => Observable<IListResponse<IUserBasicInfo>>;
|
|
438
|
-
|
|
439
535
|
/**
|
|
440
|
-
*
|
|
536
|
+
* User branch permission data
|
|
441
537
|
*/
|
|
442
|
-
interface
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
size: string;
|
|
447
|
-
url: string | null;
|
|
538
|
+
interface IUserBranchPermission {
|
|
539
|
+
branchId: string;
|
|
540
|
+
branchName: string;
|
|
541
|
+
companyId: string;
|
|
448
542
|
}
|
|
449
543
|
/**
|
|
450
|
-
*
|
|
544
|
+
* User Permission Provider Interface - Abstracts user permission data access operations.
|
|
451
545
|
*/
|
|
452
|
-
interface
|
|
453
|
-
|
|
454
|
-
folderPath?: string;
|
|
455
|
-
maxWidth?: number;
|
|
456
|
-
maxHeight?: number;
|
|
457
|
-
quality?: number;
|
|
458
|
-
compress?: boolean;
|
|
546
|
+
interface IUserPermissionProvider {
|
|
547
|
+
getUserBranchPermissions(userId: string): Observable<ISingleResponse<IUserBranchPermission[]>>;
|
|
459
548
|
}
|
|
460
549
|
/**
|
|
461
|
-
*
|
|
550
|
+
* Company basic info for dropdowns
|
|
462
551
|
*/
|
|
463
|
-
interface
|
|
464
|
-
id
|
|
552
|
+
interface ICompanyBasicInfo {
|
|
553
|
+
id: string;
|
|
465
554
|
name: string;
|
|
466
|
-
|
|
467
|
-
size: number;
|
|
468
|
-
contentType: string;
|
|
555
|
+
slug?: string;
|
|
469
556
|
}
|
|
470
557
|
/**
|
|
471
|
-
*
|
|
558
|
+
* Company API Provider Interface
|
|
472
559
|
*/
|
|
473
|
-
interface
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
[key: string]: unknown;
|
|
560
|
+
interface ICompanyApiProvider {
|
|
561
|
+
getCompanies(filter?: {
|
|
562
|
+
page?: number;
|
|
563
|
+
pageSize?: number;
|
|
564
|
+
search?: string;
|
|
565
|
+
}): Observable<IListResponse<ICompanyBasicInfo>>;
|
|
480
566
|
}
|
|
481
|
-
/**
|
|
482
|
-
* Function type for loading files
|
|
483
|
-
*/
|
|
484
|
-
type LoadFilesFn = (filter: IFileSelectFilter) => Observable<IListResponse<IFileBasicInfo>>;
|
|
485
|
-
/**
|
|
486
|
-
* Function type for uploading a file
|
|
487
|
-
*/
|
|
488
|
-
type UploadFileFn = (file: File, options?: IFileUploadOptions) => Observable<ISingleResponse<IUploadedFile>>;
|
|
489
|
-
/**
|
|
490
|
-
* Function type for getting file URLs (presigned URL refresh)
|
|
491
|
-
*/
|
|
492
|
-
type GetFileUrlsFn = (fileIds: string[]) => Observable<ISingleResponse<IFileBasicInfo[]>>;
|
|
493
|
-
/**
|
|
494
|
-
* Common file type filters
|
|
495
|
-
*/
|
|
496
|
-
declare const FILE_TYPE_FILTERS: {
|
|
497
|
-
readonly IMAGES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
|
|
498
|
-
readonly DOCUMENTS: readonly ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"];
|
|
499
|
-
readonly VIDEOS: readonly ["video/mp4", "video/webm", "video/ogg", "video/quicktime"];
|
|
500
|
-
readonly AUDIO: readonly ["audio/mpeg", "audio/wav", "audio/ogg", "audio/webm"];
|
|
501
|
-
readonly ALL: string[];
|
|
502
|
-
};
|
|
503
|
-
/**
|
|
504
|
-
* Get accept string for file input from content types
|
|
505
|
-
*/
|
|
506
|
-
declare function getAcceptString(contentTypes: string[]): string;
|
|
507
|
-
/**
|
|
508
|
-
* Check if file matches allowed content types
|
|
509
|
-
*/
|
|
510
|
-
declare function isFileTypeAllowed(file: File, allowedTypes: string[]): boolean;
|
|
511
|
-
/**
|
|
512
|
-
* Get file icon class based on content type
|
|
513
|
-
*/
|
|
514
|
-
declare function getFileIconClass(contentType: string): string;
|
|
515
|
-
/**
|
|
516
|
-
* Format file size for display
|
|
517
|
-
*/
|
|
518
|
-
declare function formatFileSize(sizeInKb: string | number): string;
|
|
519
|
-
|
|
520
567
|
/**
|
|
521
568
|
* User role info for profile display
|
|
522
569
|
*/
|
|
523
570
|
interface IProfileRoleInfo {
|
|
524
571
|
id: string;
|
|
525
572
|
name: string;
|
|
526
|
-
description?: string | null;
|
|
527
|
-
}
|
|
528
|
-
/**
|
|
529
|
-
* User action info for profile display
|
|
530
|
-
*/
|
|
531
|
-
interface IProfileActionInfo {
|
|
532
|
-
id: string;
|
|
533
|
-
name: string;
|
|
534
|
-
code: string;
|
|
535
|
-
description?: string | null;
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Profile Permission Provider Interface
|
|
539
|
-
*
|
|
540
|
-
* Abstracts permission data access for profile page.
|
|
541
|
-
* Implemented by ng-iam, consumed by ng-auth profile page.
|
|
542
|
-
* Optional injection - if not provided, permissions section is hidden.
|
|
543
|
-
*
|
|
544
|
-
* @example
|
|
545
|
-
* // In profile component
|
|
546
|
-
* private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, { optional: true });
|
|
547
|
-
*
|
|
548
|
-
* ngOnInit() {
|
|
549
|
-
* if (this.permissionProvider) {
|
|
550
|
-
* this.loadPermissions();
|
|
551
|
-
* }
|
|
552
|
-
* }
|
|
553
|
-
*/
|
|
554
|
-
interface IProfilePermissionProvider {
|
|
555
|
-
/**
|
|
556
|
-
* Get user's assigned roles
|
|
557
|
-
* @param userId User ID
|
|
558
|
-
* @param branchId Optional branch ID for branch-scoped roles
|
|
559
|
-
*/
|
|
560
|
-
getUserRoles(userId: string, branchId?: string): Observable<ISingleResponse<IProfileRoleInfo[]>>;
|
|
561
|
-
/**
|
|
562
|
-
* Get user's direct actions
|
|
563
|
-
* @param userId User ID
|
|
564
|
-
* @param branchId Optional branch ID for branch-scoped actions
|
|
565
|
-
*/
|
|
566
|
-
getUserActions(userId: string, branchId?: string): Observable<ISingleResponse<IProfileActionInfo[]>>;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* Uploaded file result with file manager ID
|
|
571
|
-
*/
|
|
572
|
-
interface IProfileUploadResult {
|
|
573
|
-
/** File manager ID (UUID) for storing in profilePictureId */
|
|
574
|
-
id: string;
|
|
575
|
-
/** Original file name */
|
|
576
|
-
name: string;
|
|
577
|
-
/** Storage key/path */
|
|
578
|
-
key: string;
|
|
579
|
-
/** File size in bytes */
|
|
580
|
-
size: number;
|
|
581
|
-
/** MIME type */
|
|
582
|
-
contentType: string;
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* Profile Upload Options
|
|
586
|
-
*/
|
|
587
|
-
interface IProfileUploadOptions {
|
|
588
|
-
/** Folder path for organizing uploads */
|
|
589
|
-
folderPath?: string;
|
|
590
|
-
/** Enable image compression */
|
|
591
|
-
compress?: boolean;
|
|
592
|
-
/** Max width for image compression */
|
|
593
|
-
maxWidth?: number;
|
|
594
|
-
/** Max height for image compression */
|
|
595
|
-
maxHeight?: number;
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* Profile Upload Provider Interface
|
|
599
|
-
*
|
|
600
|
-
* Provides file upload functionality for profile pictures.
|
|
601
|
-
* Implemented by ng-storage, consumed by ng-auth profile page.
|
|
602
|
-
*
|
|
603
|
-
* This interface enables ng-auth to use storage functionality
|
|
604
|
-
* without directly depending on ng-storage package.
|
|
605
|
-
*/
|
|
606
|
-
interface IProfileUploadProvider {
|
|
607
|
-
/**
|
|
608
|
-
* Upload profile picture and register in file manager
|
|
609
|
-
* Returns file manager ID (UUID) for storing in user.profilePictureId
|
|
610
|
-
*
|
|
611
|
-
* @param file - File to upload
|
|
612
|
-
* @param options - Upload options (compression, folder, etc.)
|
|
613
|
-
* @returns Observable with upload result including file manager ID
|
|
614
|
-
*/
|
|
615
|
-
uploadProfilePicture(file: File, options?: IProfileUploadOptions): Observable<ISingleResponse<IProfileUploadResult>>;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
/**
|
|
619
|
-
* Base user interface for list operations
|
|
620
|
-
* Extends this with app-specific user fields
|
|
621
|
-
*/
|
|
622
|
-
interface IUserListItem {
|
|
623
|
-
id: string;
|
|
624
|
-
name: string;
|
|
625
|
-
email: string;
|
|
626
|
-
phone?: string;
|
|
627
|
-
isActive?: boolean;
|
|
628
|
-
[key: string]: unknown;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* User list action definition
|
|
632
|
-
* @template T User type, defaults to IUserListItem
|
|
633
|
-
*/
|
|
634
|
-
interface IUserListAction<T = IUserListItem> {
|
|
635
|
-
/** Unique action identifier */
|
|
636
|
-
id: string;
|
|
637
|
-
/** Display label */
|
|
638
|
-
label: string;
|
|
639
|
-
/** PrimeNG icon class (e.g., 'pi pi-pencil') */
|
|
640
|
-
icon?: string;
|
|
641
|
-
/** Severity for styling (e.g., 'primary', 'danger', 'warning') */
|
|
642
|
-
severity?: 'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'danger' | 'help' | 'contrast';
|
|
643
|
-
/** Permission code required (checked via hasPermission) */
|
|
644
|
-
permission?: string;
|
|
645
|
-
/** Tooltip text */
|
|
646
|
-
tooltip?: string;
|
|
647
|
-
/** Whether action is disabled */
|
|
648
|
-
disabled?: boolean | ((user: T) => boolean);
|
|
649
|
-
/** Whether action is visible */
|
|
650
|
-
visible?: boolean | ((user: T) => boolean);
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Extra column definition for user list
|
|
654
|
-
*/
|
|
655
|
-
interface IUserListColumn {
|
|
656
|
-
/** Column field name */
|
|
657
|
-
field: string;
|
|
658
|
-
/** Column header label */
|
|
659
|
-
header: string;
|
|
660
|
-
/** Column width */
|
|
661
|
-
width?: string;
|
|
662
|
-
/** Whether column is sortable */
|
|
663
|
-
sortable?: boolean;
|
|
664
|
-
/** Whether column is filterable */
|
|
665
|
-
filterable?: boolean;
|
|
666
|
-
/** Custom template type for rendering */
|
|
667
|
-
templateType?: 'text' | 'badge' | 'date' | 'boolean' | 'custom';
|
|
668
|
-
}
|
|
669
|
-
/**
|
|
670
|
-
* User List Provider Interface
|
|
671
|
-
*
|
|
672
|
-
* Allows consuming applications to extend user list pages with:
|
|
673
|
-
* - Extra columns
|
|
674
|
-
* - Extra row actions
|
|
675
|
-
* - Extra toolbar actions
|
|
676
|
-
* - Custom data enrichment
|
|
677
|
-
*
|
|
678
|
-
* This follows the Provider Interface Pattern:
|
|
679
|
-
* - ng-shared defines the interface (this file)
|
|
680
|
-
* - Consuming apps (via ng-iam or app-specific) implement the interface
|
|
681
|
-
* - ng-auth user list optionally injects and uses the implementation
|
|
682
|
-
*
|
|
683
|
-
* @template T User type, defaults to IUserListItem
|
|
684
|
-
*
|
|
685
|
-
* @example
|
|
686
|
-
* // In app.config.ts
|
|
687
|
-
* providers: [
|
|
688
|
-
* { provide: USER_LIST_PROVIDER, useClass: MyUserListProvider },
|
|
689
|
-
* ]
|
|
690
|
-
*
|
|
691
|
-
* // Implementation
|
|
692
|
-
* @Injectable({ providedIn: 'root' })
|
|
693
|
-
* export class MyUserListProvider implements IUserListProvider {
|
|
694
|
-
* getExtraRowActions() {
|
|
695
|
-
* return [
|
|
696
|
-
* { id: 'assign-role', label: 'Assign Role', icon: 'pi pi-users' },
|
|
697
|
-
* ];
|
|
698
|
-
* }
|
|
699
|
-
* }
|
|
700
|
-
*/
|
|
701
|
-
interface IUserListProvider<T extends IUserListItem = IUserListItem> {
|
|
702
|
-
/**
|
|
703
|
-
* Get extra columns to display in user list
|
|
704
|
-
* @returns Array of extra column definitions
|
|
705
|
-
*/
|
|
706
|
-
getExtraColumns?(): IUserListColumn[];
|
|
707
|
-
/**
|
|
708
|
-
* Get extra row-level actions (per-user actions)
|
|
709
|
-
* Displayed in actions column for each row
|
|
710
|
-
* @returns Array of action definitions
|
|
711
|
-
*/
|
|
712
|
-
getExtraRowActions?(): IUserListAction<T>[];
|
|
713
|
-
/**
|
|
714
|
-
* Get extra toolbar actions
|
|
715
|
-
* Displayed in toolbar above the list
|
|
716
|
-
* @returns Array of action definitions
|
|
717
|
-
*/
|
|
718
|
-
getExtraToolbarActions?(): IUserListAction<T>[];
|
|
719
|
-
/**
|
|
720
|
-
* Handle row action click
|
|
721
|
-
* @param actionId Action identifier
|
|
722
|
-
* @param user User data from the row
|
|
723
|
-
*/
|
|
724
|
-
onRowAction?(actionId: string, user: T): void;
|
|
725
|
-
/**
|
|
726
|
-
* Handle toolbar action click
|
|
727
|
-
* @param actionId Action identifier
|
|
728
|
-
* @param selectedUsers Currently selected users (for bulk actions)
|
|
729
|
-
*/
|
|
730
|
-
onToolbarAction?(actionId: string, selectedUsers: T[]): void;
|
|
731
|
-
/**
|
|
732
|
-
* Enrich user list data with extra fields
|
|
733
|
-
* Called after data is loaded from API
|
|
734
|
-
* @param users List of users from API
|
|
735
|
-
* @returns Observable of enriched users
|
|
736
|
-
*/
|
|
737
|
-
enrichListData?(users: T[]): Observable<T[]>;
|
|
738
|
-
/**
|
|
739
|
-
* Get extra filters for user list
|
|
740
|
-
* @returns Array of filter definitions
|
|
741
|
-
*/
|
|
742
|
-
getExtraFilters?(): IUserListFilter[];
|
|
573
|
+
description?: string | null;
|
|
743
574
|
}
|
|
744
575
|
/**
|
|
745
|
-
*
|
|
576
|
+
* User action info for profile display
|
|
746
577
|
*/
|
|
747
|
-
interface
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
/** Filter type */
|
|
753
|
-
type: 'text' | 'dropdown' | 'multiselect' | 'date' | 'boolean';
|
|
754
|
-
/** Options for dropdown/multiselect */
|
|
755
|
-
options?: {
|
|
756
|
-
label: string;
|
|
757
|
-
value: string | number | boolean;
|
|
758
|
-
}[];
|
|
759
|
-
/** Placeholder text */
|
|
760
|
-
placeholder?: string;
|
|
578
|
+
interface IProfileActionInfo {
|
|
579
|
+
id: string;
|
|
580
|
+
name: string;
|
|
581
|
+
code: string;
|
|
582
|
+
description?: string | null;
|
|
761
583
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
584
|
+
/**
|
|
585
|
+
* Profile Permission Provider Interface - Abstracts permission data access for profile page.
|
|
586
|
+
*/
|
|
587
|
+
interface IProfilePermissionProvider {
|
|
588
|
+
getUserRoles(userId: string, branchId?: string): Observable<ISingleResponse<IProfileRoleInfo[]>>;
|
|
589
|
+
getUserActions(userId: string, branchId?: string): Observable<ISingleResponse<IProfileActionInfo[]>>;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* File Provider Interface - Provides file loading and upload functionality.
|
|
593
|
+
* Used by FileSelectorDialogComponent to load files and handle uploads.
|
|
594
|
+
*/
|
|
595
|
+
interface IFileProvider {
|
|
596
|
+
/** Load files with filtering and pagination */
|
|
597
|
+
loadFiles(filter: IFileSelectFilter): Observable<IListResponse<IFileBasicInfo>>;
|
|
598
|
+
/** Upload a single file and register in file manager */
|
|
599
|
+
uploadFile(file: File, options?: IFileUploadOptions): Observable<ISingleResponse<IUploadedFile>>;
|
|
600
|
+
/** Upload multiple files at once (more efficient batch upload) */
|
|
601
|
+
uploadMultipleFiles?(files: File[], options?: IFileUploadOptions): Observable<ISingleResponse<IUploadedFile[]>>;
|
|
602
|
+
/** Get file URLs by IDs (for refreshing presigned URLs) */
|
|
603
|
+
getFileUrls?(fileIds: string[]): Observable<ISingleResponse<IFileBasicInfo[]>>;
|
|
604
|
+
/** Load folders for folder selector (optional) */
|
|
605
|
+
loadFolders?(filter: ISelectFilter): Observable<IListResponse<IFolderBasicInfo>>;
|
|
606
|
+
/** Load storage configs for config selector (optional) */
|
|
607
|
+
loadStorageConfigs?(filter: ISelectFilter): Observable<IListResponse<IStorageConfigBasicInfo>>;
|
|
766
608
|
}
|
|
767
609
|
|
|
768
610
|
declare enum IconTypeEnum {
|
|
769
|
-
|
|
770
|
-
IMAGE_FILE_LINK = 2
|
|
771
|
-
DIRECT_TAG_SVG = 3
|
|
611
|
+
ICON_NAME = 1,
|
|
612
|
+
IMAGE_FILE_LINK = 2
|
|
772
613
|
}
|
|
773
614
|
|
|
774
615
|
declare class CookieService {
|
|
@@ -780,15 +621,17 @@ declare class CookieService {
|
|
|
780
621
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<CookieService>;
|
|
781
622
|
}
|
|
782
623
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
624
|
+
declare class FaviconService {
|
|
625
|
+
private readonly http;
|
|
626
|
+
private readonly platformService;
|
|
627
|
+
private readonly document;
|
|
628
|
+
private svgTemplate;
|
|
629
|
+
apply(): void;
|
|
630
|
+
private render;
|
|
631
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FaviconService, never>;
|
|
632
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<FaviconService>;
|
|
788
633
|
}
|
|
789
|
-
|
|
790
|
-
* Response DTO with file information including URL
|
|
791
|
-
*/
|
|
634
|
+
|
|
792
635
|
interface FilesResponseDto {
|
|
793
636
|
id: string;
|
|
794
637
|
name: string;
|
|
@@ -797,113 +640,40 @@ interface FilesResponseDto {
|
|
|
797
640
|
}
|
|
798
641
|
/**
|
|
799
642
|
* Service to fetch file URLs from the backend.
|
|
800
|
-
*
|
|
801
|
-
* - Handles presigned URLs for cloud storage (AWS S3, Azure)
|
|
802
|
-
* - Auto-refreshes expired URLs
|
|
803
|
-
* - Validates file access permissions
|
|
804
|
-
* - Works with all storage providers (Local, S3, Azure, SFTP)
|
|
643
|
+
* Handles presigned URLs for cloud storage, auto-refresh, and caching.
|
|
805
644
|
*/
|
|
806
645
|
declare class FileUrlService {
|
|
807
646
|
private readonly http;
|
|
808
647
|
private readonly appConfig;
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
* Get file URL by ID from cache (reactive signal)
|
|
813
|
-
*/
|
|
814
|
-
getFileUrl(fileId: string | null | undefined): string | null;
|
|
815
|
-
/**
|
|
816
|
-
* Get file URL signal (computed from cache)
|
|
817
|
-
*/
|
|
818
|
-
fileUrlSignal(fileId: string | null | undefined): _angular_core.Signal<string | null>;
|
|
819
|
-
/**
|
|
820
|
-
* Fetch file URLs from backend and update cache.
|
|
821
|
-
* Skips IDs already in cache to prevent duplicate calls.
|
|
822
|
-
* Returns Observable of fetched files (including cached ones).
|
|
823
|
-
*/
|
|
648
|
+
private readonly _cache;
|
|
649
|
+
readonly cache: _angular_core.Signal<Map<string, FilesResponseDto>>;
|
|
650
|
+
/** Fetch file URLs from backend and update cache */
|
|
824
651
|
fetchFileUrls(fileIds: string[], forceRefresh?: boolean): Observable<FilesResponseDto[]>;
|
|
825
|
-
/**
|
|
826
|
-
* Fetch a single file URL.
|
|
827
|
-
* Uses cache if available to prevent duplicate calls.
|
|
828
|
-
* Returns Observable of file info or null if not found.
|
|
829
|
-
*/
|
|
652
|
+
/** Fetch single file URL (delegates to fetchFileUrls) */
|
|
830
653
|
fetchSingleFileUrl(fileId: string, forceRefresh?: boolean): Observable<FilesResponseDto | null>;
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
* Useful on logout or when switching contexts.
|
|
834
|
-
*/
|
|
835
|
-
clearCache(): void;
|
|
836
|
-
/**
|
|
837
|
-
* Remove specific file from cache.
|
|
838
|
-
*/
|
|
839
|
-
removeFromCache(fileId: string): void;
|
|
654
|
+
private addToCache;
|
|
655
|
+
private getFromCache;
|
|
840
656
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUrlService, never>;
|
|
841
657
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<FileUrlService>;
|
|
842
658
|
}
|
|
843
659
|
|
|
844
660
|
/**
|
|
845
|
-
* Permission
|
|
846
|
-
*
|
|
847
|
-
* Centralized service for permission validation across all packages.
|
|
848
|
-
* Provides signal-based state management and reactive permission checking.
|
|
849
|
-
*
|
|
850
|
-
* Features:
|
|
851
|
-
* - Signal-based permission storage
|
|
852
|
-
* - Individual permission checks
|
|
853
|
-
* - Permission change detection
|
|
854
|
-
* - Reactive permission state updates
|
|
855
|
-
*
|
|
856
|
-
* Usage:
|
|
857
|
-
* ```typescript
|
|
858
|
-
* // In component
|
|
859
|
-
* readonly permissionValidator = inject(PermissionValidatorService);
|
|
860
|
-
*
|
|
861
|
-
* // Set permissions (typically from auth/IAM)
|
|
862
|
-
* this.permissionValidator.setPermissions(['user.view', 'user.create']);
|
|
863
|
-
*
|
|
864
|
-
* // Check individual permission
|
|
865
|
-
* if (this.permissionValidator.hasPermission('user.view')) {
|
|
866
|
-
* // Show UI element
|
|
867
|
-
* }
|
|
868
|
-
*
|
|
869
|
-
* // Access current permissions reactively
|
|
870
|
-
* const permissions = this.permissionValidator.permissions();
|
|
871
|
-
* ```
|
|
872
|
-
*
|
|
873
|
-
* @packageDocumentation
|
|
661
|
+
* Permission state management service.
|
|
662
|
+
* Provides signal-based storage and permission checking with wildcard support.
|
|
874
663
|
*/
|
|
875
664
|
declare class PermissionValidatorService {
|
|
876
|
-
/**
|
|
877
|
-
* Private writable signal for permissions
|
|
878
|
-
*/
|
|
879
665
|
private readonly _permissions;
|
|
880
|
-
/**
|
|
881
|
-
* Readonly permission signal for external consumers
|
|
882
|
-
*/
|
|
883
666
|
readonly permissions: _angular_core.Signal<string[]>;
|
|
884
|
-
/**
|
|
885
|
-
* Private writable signal for loaded state
|
|
886
|
-
*/
|
|
887
667
|
private readonly _isLoaded;
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
* @param permissions - Array of permission codes
|
|
891
|
-
*/
|
|
668
|
+
readonly isLoaded: _angular_core.Signal<boolean>;
|
|
669
|
+
/** Set permissions (replaces existing) */
|
|
892
670
|
setPermissions(permissions: string[]): void;
|
|
893
|
-
/**
|
|
894
|
-
* Clear all permissions
|
|
895
|
-
*/
|
|
671
|
+
/** Clear all permissions */
|
|
896
672
|
clearPermissions(): void;
|
|
897
|
-
/**
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
*/
|
|
902
|
-
hasPermission(permissionCode: string): boolean;
|
|
903
|
-
/**
|
|
904
|
-
* Check if permissions are loaded
|
|
905
|
-
* @returns True if permissions have been loaded
|
|
906
|
-
*/
|
|
673
|
+
/** Check if user has permission (supports wildcards: '*', 'module.*') */
|
|
674
|
+
hasPermission(code: string): boolean;
|
|
675
|
+
/** Check if user has ANY of the specified permissions (OR logic) */
|
|
676
|
+
hasAnyPermission(code: string[]): boolean;
|
|
907
677
|
isPermissionsLoaded(): boolean;
|
|
908
678
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PermissionValidatorService, never>;
|
|
909
679
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<PermissionValidatorService>;
|
|
@@ -916,6 +686,16 @@ declare class PlatformService {
|
|
|
916
686
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<PlatformService>;
|
|
917
687
|
}
|
|
918
688
|
|
|
689
|
+
declare class TranslateService {
|
|
690
|
+
private readonly localizationState;
|
|
691
|
+
private readonly registry;
|
|
692
|
+
translate(key: string, params?: Record<string, string | unknown>): string;
|
|
693
|
+
translateSignal(key: string, params?: Record<string, string | number>): Signal<string>;
|
|
694
|
+
private interpolate;
|
|
695
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TranslateService, never>;
|
|
696
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<TranslateService>;
|
|
697
|
+
}
|
|
698
|
+
|
|
919
699
|
declare class EditModeElementChangerDirective {
|
|
920
700
|
private readonly el;
|
|
921
701
|
private readonly ngControl;
|
|
@@ -954,20 +734,18 @@ declare class EditModeElementChangerDirective {
|
|
|
954
734
|
* @example
|
|
955
735
|
* // In component
|
|
956
736
|
* readonly userManageLogic: ILogicNode = {
|
|
957
|
-
* id: 'root',
|
|
958
737
|
* type: 'group',
|
|
959
738
|
* operator: 'AND',
|
|
960
739
|
* children: [
|
|
961
740
|
* {
|
|
962
|
-
* id: '1',
|
|
963
741
|
* type: 'group',
|
|
964
742
|
* operator: 'OR',
|
|
965
743
|
* children: [
|
|
966
|
-
* {
|
|
967
|
-
* {
|
|
744
|
+
* { type: 'action', actionId: 'user.view' },
|
|
745
|
+
* { type: 'action', actionId: 'user.create' }
|
|
968
746
|
* ]
|
|
969
747
|
* },
|
|
970
|
-
* {
|
|
748
|
+
* { type: 'action', actionId: 'department.manage' }
|
|
971
749
|
* ]
|
|
972
750
|
* };
|
|
973
751
|
*
|
|
@@ -1015,9 +793,9 @@ declare class IsEmptyImageDirective {
|
|
|
1015
793
|
}
|
|
1016
794
|
|
|
1017
795
|
declare class PreventDefaultDirective {
|
|
1018
|
-
eventType: _angular_core.InputSignal<"click" | "keydown" | "keyup">;
|
|
1019
|
-
preventKey: _angular_core.InputSignal<string | undefined>;
|
|
1020
|
-
action: _angular_core.OutputEmitterRef<Event>;
|
|
796
|
+
readonly eventType: _angular_core.InputSignal<"click" | "keydown" | "keyup">;
|
|
797
|
+
readonly preventKey: _angular_core.InputSignal<string | undefined>;
|
|
798
|
+
readonly action: _angular_core.OutputEmitterRef<Event>;
|
|
1021
799
|
onClick(event: MouseEvent): void;
|
|
1022
800
|
onKeydown(event: KeyboardEvent): void;
|
|
1023
801
|
onKeyup(event: KeyboardEvent): void;
|
|
@@ -1026,206 +804,458 @@ declare class PreventDefaultDirective {
|
|
|
1026
804
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PreventDefaultDirective, "[appPreventDefault]", never, { "eventType": { "alias": "eventType"; "required": false; "isSignal": true; }; "preventKey": { "alias": "preventKey"; "required": false; "isSignal": true; }; }, { "action": "action"; }, never, never, true, never>;
|
|
1027
805
|
}
|
|
1028
806
|
|
|
1029
|
-
declare class
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
static
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
declare class PrimeModule {
|
|
1036
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PrimeModule, never>;
|
|
1037
|
-
static ɵmod: _angular_core.ɵɵNgModuleDeclaration<PrimeModule, never, never, [typeof i1$1.AutoCompleteModule, typeof i2$1.AvatarModule, typeof i3$1.ButtonModule, typeof i4.CardModule, typeof i5.CheckboxModule, typeof i6.ConfirmDialogModule, typeof i7.DatePickerModule, typeof i8.DialogModule, typeof i9.DividerModule, typeof i10.FileUploadModule, typeof i11.IconFieldModule, typeof i12.ImageModule, typeof i13.InputIconModule, typeof i14.InputNumberModule, typeof i15.InputTextModule, typeof i16.ListboxModule, typeof i17.MultiSelectModule, typeof i18.PaginatorModule, typeof i19.PanelModule, typeof i20.PasswordModule, typeof i21.PopoverModule, typeof i22.ProgressBarModule, typeof i23.RadioButtonModule, typeof i24.RippleModule, typeof i25.SelectButtonModule, typeof i26.SelectModule, typeof i27.SkeletonModule, typeof i28.SplitButtonModule, typeof i29.StepsModule, typeof i30.TableModule, typeof i31.TabsModule, typeof i32.TagModule, typeof i33.TextareaModule, typeof i34.ToastModule, typeof i35.ToggleSwitchModule, typeof i36.TooltipModule, typeof i37.TreeTableModule]>;
|
|
1038
|
-
static ɵinj: _angular_core.ɵɵInjectorDeclaration<PrimeModule>;
|
|
807
|
+
declare class TranslatePipe implements PipeTransform {
|
|
808
|
+
private readonly translateAdapter;
|
|
809
|
+
transform(key: string | null | undefined, params?: Record<string, string | number> | null, fallback?: string): string;
|
|
810
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TranslatePipe, never>;
|
|
811
|
+
static ɵpipe: _angular_core.ɵɵPipeDeclaration<TranslatePipe, "translate", true>;
|
|
1039
812
|
}
|
|
1040
813
|
|
|
1041
814
|
/**
|
|
1042
|
-
*
|
|
1043
|
-
*
|
|
815
|
+
* HTTP context token to skip global error toast.
|
|
816
|
+
* Use when component handles error display locally.
|
|
1044
817
|
*
|
|
1045
|
-
*
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1049
|
-
*
|
|
1050
|
-
*
|
|
1051
|
-
* | update() | POST | /{resource}/update | ISingleResponse<T> |
|
|
1052
|
-
* | updateMany() | POST | /{resource}/update-many| IBulkResponse<T> |
|
|
1053
|
-
* | delete() | POST | /{resource}/delete | IMessageResponse |
|
|
818
|
+
* @example
|
|
819
|
+
* ```typescript
|
|
820
|
+
* this.http.post(url, data, {
|
|
821
|
+
* context: new HttpContext().set(SKIP_ERROR_TOAST, true)
|
|
822
|
+
* });
|
|
823
|
+
* ```
|
|
1054
824
|
*/
|
|
1055
|
-
|
|
1056
|
-
insert(dto: DtoT): Observable<ISingleResponse<InterfaceT>>;
|
|
1057
|
-
insertMany(dtos: DtoT[]): Observable<IBulkResponse<InterfaceT>>;
|
|
1058
|
-
findById(id: string, select?: string[]): Observable<ISingleResponse<InterfaceT>>;
|
|
1059
|
-
getAll(search: string, filter: IFilterData): Observable<IListResponse<InterfaceT>>;
|
|
1060
|
-
update(dto: DtoT): Observable<ISingleResponse<InterfaceT>>;
|
|
1061
|
-
updateMany(dtos: DtoT[]): Observable<IBulkResponse<InterfaceT>>;
|
|
1062
|
-
delete(deleteDto: IDeleteData): Observable<IMessageResponse>;
|
|
1063
|
-
}
|
|
825
|
+
declare const SKIP_ERROR_TOAST: HttpContextToken<boolean>;
|
|
1064
826
|
/**
|
|
1065
|
-
*
|
|
1066
|
-
*
|
|
1067
|
-
* Response types match FLUSYS_NEST backend DTOs.
|
|
827
|
+
* Error Catching Interceptor
|
|
828
|
+
* Displays error messages for failed HTTP requests using backend response.
|
|
1068
829
|
*
|
|
1069
|
-
*
|
|
830
|
+
* Features:
|
|
831
|
+
* - Uses backend's error title (error.error.error) as summary
|
|
832
|
+
* - Uses backend's error message (error.error.message) as detail
|
|
833
|
+
* - Falls back to sensible defaults based on status code
|
|
834
|
+
* - Skip with SKIP_ERROR_TOAST context token for local handling
|
|
1070
835
|
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
* - `POST /{resource}/insert-many` - Create multiple items
|
|
1074
|
-
* - `POST /{resource}/get/:id` - Get single item by ID
|
|
1075
|
-
* - `POST /{resource}/get-all?q=` - List with pagination/filter
|
|
1076
|
-
* - `POST /{resource}/update` - Update single item
|
|
1077
|
-
* - `POST /{resource}/update-many` - Update multiple items
|
|
1078
|
-
* - `POST /{resource}/delete` - Delete/restore/permanent delete
|
|
836
|
+
* NOTE: This interceptor only handles error display.
|
|
837
|
+
* For 401 handling and token refresh, use tokenRefreshInterceptor from @flusys/ng-auth.
|
|
1079
838
|
*
|
|
1080
839
|
* @example
|
|
1081
840
|
* ```typescript
|
|
1082
|
-
* //
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1086
|
-
*
|
|
1087
|
-
*
|
|
1088
|
-
*
|
|
1089
|
-
*
|
|
1090
|
-
*
|
|
1091
|
-
*
|
|
1092
|
-
* users = this.userService.data; // Signal<User[]>
|
|
1093
|
-
* isLoading = this.userService.isLoading; // Signal<boolean>
|
|
1094
|
-
* total = this.userService.total; // Signal<number>
|
|
1095
|
-
*
|
|
1096
|
-
* // Trigger fetch
|
|
1097
|
-
* this.userService.fetchList('search', { pagination: { currentPage: 0, pageSize: 10 } });
|
|
1098
|
-
*
|
|
1099
|
-
* // CRUD operations
|
|
1100
|
-
* await this.userService.insertAsync({ name: 'John', email: 'john@example.com' });
|
|
1101
|
-
* await this.userService.updateAsync({ id: '123', name: 'John Updated' });
|
|
1102
|
-
* await this.userService.deleteAsync({ id: '123', type: 'delete' });
|
|
841
|
+
* // In app.config.ts
|
|
842
|
+
* provideHttpClient(
|
|
843
|
+
* withFetch(),
|
|
844
|
+
* withInterceptors([
|
|
845
|
+
* authInterceptor, // from @flusys/ng-auth
|
|
846
|
+
* tokenRefreshInterceptor, // from @flusys/ng-auth
|
|
847
|
+
* errorCatchingInterceptor, // from @flusys/ng-core
|
|
848
|
+
* apiLoaderInterceptor, // from @flusys/ng-core
|
|
849
|
+
* ])
|
|
850
|
+
* )
|
|
1103
851
|
* ```
|
|
1104
852
|
*/
|
|
853
|
+
declare function errorCatchingInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>;
|
|
854
|
+
|
|
855
|
+
interface IResolverModuleConfig {
|
|
856
|
+
modules: string[];
|
|
857
|
+
fallbackMessages?: Record<string, string>;
|
|
858
|
+
}
|
|
859
|
+
declare function resolveTranslationModule(config: IResolverModuleConfig): ResolveFn<boolean>;
|
|
860
|
+
|
|
861
|
+
declare class AngularModule {
|
|
862
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AngularModule, never>;
|
|
863
|
+
static ɵmod: _angular_core.ɵɵNgModuleDeclaration<AngularModule, never, [typeof i1.CommonModule, typeof i2.FormsModule, typeof i2.ReactiveFormsModule, typeof i3.RouterOutlet, typeof i3.RouterLink, typeof i3.RouterLinkActive, typeof IsEmptyImageDirective, typeof i1.NgOptimizedImage, typeof i1.NgComponentOutlet, typeof PreventDefaultDirective], [typeof i1.CommonModule, typeof i2.FormsModule, typeof i2.ReactiveFormsModule, typeof i3.RouterOutlet, typeof i3.RouterLink, typeof i3.RouterLinkActive, typeof IsEmptyImageDirective, typeof i1.NgOptimizedImage, typeof i1.NgComponentOutlet, typeof PreventDefaultDirective]>;
|
|
864
|
+
static ɵinj: _angular_core.ɵɵInjectorDeclaration<AngularModule>;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
interface IApiService<DtoT, InterfaceT> {
|
|
868
|
+
insert(dto: DtoT): Promise<ISingleResponse<InterfaceT>>;
|
|
869
|
+
insertMany(dtos: DtoT[]): Promise<IBulkResponse<InterfaceT>>;
|
|
870
|
+
findById(id: string, select?: string[]): Promise<ISingleResponse<InterfaceT>>;
|
|
871
|
+
findByIds(ids: string[], select?: string[] | string): Promise<IListResponse<InterfaceT>>;
|
|
872
|
+
getAll(filter: IFilterData, search?: string): Promise<IListResponse<InterfaceT>>;
|
|
873
|
+
getByFilter(filter: Record<string, unknown>): Promise<ISingleResponse<InterfaceT>>;
|
|
874
|
+
update(dto: DtoT): Promise<ISingleResponse<InterfaceT>>;
|
|
875
|
+
updateMany(dtos: DtoT[]): Promise<IBulkResponse<InterfaceT>>;
|
|
876
|
+
bulkUpsert(toInsert: DtoT[], toUpdate: DtoT[]): Promise<InterfaceT[]>;
|
|
877
|
+
delete(deleteDto: IDeleteData): Promise<IMessageResponse>;
|
|
878
|
+
}
|
|
1105
879
|
declare abstract class ApiResourceService<DtoT, InterfaceT> implements IApiService<DtoT, InterfaceT> {
|
|
1106
|
-
protected readonly baseUrl: string;
|
|
1107
|
-
protected readonly loaderService: ApiLoaderService;
|
|
1108
|
-
protected readonly injector: Injector;
|
|
1109
880
|
protected readonly http: HttpClient;
|
|
881
|
+
private readonly _config;
|
|
882
|
+
protected readonly baseUrl: string;
|
|
1110
883
|
protected readonly moduleApiName: string;
|
|
1111
|
-
/** Current search term */
|
|
1112
884
|
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1113
|
-
/** Current filter and pagination state */
|
|
1114
885
|
readonly filterData: _angular_core.WritableSignal<IFilterData>;
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
* Call initListResource() or any list method (fetchList, reload, etc.) to initialize.
|
|
1118
|
-
*/
|
|
1119
|
-
private _listResource;
|
|
1120
|
-
/** Whether the list resource has been initialized */
|
|
1121
|
-
private _resourceInitialized;
|
|
1122
|
-
/** Get or create the list resource (lazy initialization) */
|
|
1123
|
-
get listResource(): ResourceRef<IListResponse<InterfaceT> | undefined>;
|
|
1124
|
-
/**
|
|
1125
|
-
* Initialize the list resource. Called automatically when accessing listResource
|
|
1126
|
-
* or any list-related computed signals/methods.
|
|
1127
|
-
* Uses runInInjectionContext to support lazy initialization outside constructor.
|
|
1128
|
-
*/
|
|
1129
|
-
initListResource(): void;
|
|
1130
|
-
/** Whether data is currently loading */
|
|
886
|
+
private readonly _active;
|
|
887
|
+
readonly listResource: ResourceRef<IListResponse<InterfaceT> | undefined>;
|
|
1131
888
|
readonly isLoading: _angular_core.Signal<boolean>;
|
|
1132
|
-
/** List data array */
|
|
1133
889
|
readonly data: _angular_core.Signal<InterfaceT[]>;
|
|
1134
|
-
/** Total count of items */
|
|
1135
890
|
readonly total: _angular_core.Signal<number>;
|
|
1136
|
-
/** Pagination metadata */
|
|
1137
891
|
readonly pageInfo: _angular_core.Signal<_flusys_ng_shared.IPaginationMeta | undefined>;
|
|
1138
|
-
/** Whether there are more pages */
|
|
1139
892
|
readonly hasMore: _angular_core.Signal<boolean>;
|
|
1140
|
-
|
|
893
|
+
readonly error: _angular_core.Signal<Error | undefined>;
|
|
894
|
+
readonly status: _angular_core.Signal<ResourceStatus>;
|
|
895
|
+
constructor(moduleApiName: string, serviceName?: ServiceName);
|
|
1141
896
|
protected getHttpOptions(endpoint: string, params?: HttpParams): {
|
|
1142
897
|
params?: HttpParams | undefined;
|
|
1143
898
|
headers: HttpHeaders;
|
|
1144
899
|
};
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
*/
|
|
900
|
+
private _getAllObs;
|
|
901
|
+
private _activate;
|
|
1148
902
|
fetchList(search?: string, filter?: Partial<IFilterData>): void;
|
|
1149
|
-
/**
|
|
1150
|
-
* Update pagination
|
|
1151
|
-
*/
|
|
1152
903
|
setPagination(pagination: IPagination): void;
|
|
1153
|
-
/**
|
|
1154
|
-
* Go to next page
|
|
1155
|
-
*/
|
|
1156
904
|
nextPage(): void;
|
|
1157
|
-
/**
|
|
1158
|
-
* Reset to first page
|
|
1159
|
-
*/
|
|
1160
905
|
resetPagination(): void;
|
|
1161
|
-
/**
|
|
1162
|
-
* Reload current data
|
|
1163
|
-
*/
|
|
1164
906
|
reload(): void;
|
|
907
|
+
private _post;
|
|
908
|
+
insert(dto: DtoT): Promise<ISingleResponse<InterfaceT>>;
|
|
909
|
+
insertMany(dtos: DtoT[]): Promise<IBulkResponse<InterfaceT>>;
|
|
910
|
+
findById(id: string, select?: string[]): Promise<ISingleResponse<InterfaceT>>;
|
|
911
|
+
getAll(filter: IFilterData, search?: string): Promise<IListResponse<InterfaceT>>;
|
|
912
|
+
update(dto: DtoT): Promise<ISingleResponse<InterfaceT>>;
|
|
913
|
+
updateMany(dtos: DtoT[]): Promise<IBulkResponse<InterfaceT>>;
|
|
914
|
+
delete(deleteDto: IDeleteData): Promise<IMessageResponse>;
|
|
915
|
+
findByIds(ids: string[], select?: string[] | string): Promise<IListResponse<InterfaceT>>;
|
|
916
|
+
getByFilter(filter: Record<string, unknown>): Promise<ISingleResponse<InterfaceT>>;
|
|
917
|
+
bulkUpsert(toInsert: DtoT[], toUpdate: DtoT[]): Promise<InterfaceT[]>;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
declare abstract class BaseFormControl<T> implements ControlValueAccessor, FormValueControl<T> {
|
|
921
|
+
protected readonly injector: Injector;
|
|
922
|
+
abstract readonly value: ReturnType<typeof model<T>>;
|
|
923
|
+
readonly disabled: _angular_core.ModelSignal<boolean>;
|
|
924
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
925
|
+
private onChange;
|
|
926
|
+
private onTouched;
|
|
927
|
+
private writeDepth;
|
|
1165
928
|
/**
|
|
1166
|
-
*
|
|
1167
|
-
*
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
*
|
|
1172
|
-
*
|
|
1173
|
-
|
|
1174
|
-
insertMany(dtos: DtoT[]): Observable<IBulkResponse<InterfaceT>>;
|
|
1175
|
-
/**
|
|
1176
|
-
* Find single item by ID (Observable)
|
|
1177
|
-
* POST /{resource}/get/:id
|
|
1178
|
-
*/
|
|
1179
|
-
findById(id: string, select?: string[]): Observable<ISingleResponse<InterfaceT>>;
|
|
1180
|
-
/**
|
|
1181
|
-
* Get all items with pagination (Observable)
|
|
1182
|
-
* POST /{resource}/get-all?q=search
|
|
1183
|
-
*/
|
|
1184
|
-
getAll(search: string, filter: IFilterData): Observable<IListResponse<InterfaceT>>;
|
|
1185
|
-
/**
|
|
1186
|
-
* Update single item (Observable)
|
|
1187
|
-
* POST /{resource}/update
|
|
1188
|
-
*/
|
|
1189
|
-
update(dto: DtoT): Observable<ISingleResponse<InterfaceT>>;
|
|
1190
|
-
/**
|
|
1191
|
-
* Update multiple items (Observable)
|
|
1192
|
-
* POST /{resource}/update-many
|
|
1193
|
-
*/
|
|
1194
|
-
updateMany(dtos: DtoT[]): Observable<IBulkResponse<InterfaceT>>;
|
|
1195
|
-
/**
|
|
1196
|
-
* Delete items (Observable)
|
|
1197
|
-
* POST /{resource}/delete
|
|
1198
|
-
* @param deleteDto - { id: string | string[], type: 'delete' | 'restore' | 'permanent' }
|
|
1199
|
-
*/
|
|
1200
|
-
delete(deleteDto: IDeleteData): Observable<IMessageResponse>;
|
|
1201
|
-
/**
|
|
1202
|
-
* Fetch paginated list (async)
|
|
1203
|
-
*/
|
|
1204
|
-
protected fetchAllAsync(search: string, filter: IFilterData): Promise<IListResponse<InterfaceT>>;
|
|
1205
|
-
/**
|
|
1206
|
-
* Find single item by ID (async)
|
|
1207
|
-
*/
|
|
1208
|
-
findByIdAsync(id: string, select?: string[]): Promise<ISingleResponse<InterfaceT>>;
|
|
1209
|
-
/**
|
|
1210
|
-
* Insert single item (async)
|
|
1211
|
-
*/
|
|
1212
|
-
insertAsync(dto: DtoT): Promise<ISingleResponse<InterfaceT>>;
|
|
1213
|
-
/**
|
|
1214
|
-
* Insert multiple items (async)
|
|
1215
|
-
*/
|
|
1216
|
-
insertManyAsync(dtos: DtoT[]): Promise<IBulkResponse<InterfaceT>>;
|
|
1217
|
-
/**
|
|
1218
|
-
* Update single item (async)
|
|
1219
|
-
*/
|
|
1220
|
-
updateAsync(dto: DtoT): Promise<ISingleResponse<InterfaceT>>;
|
|
1221
|
-
/**
|
|
1222
|
-
* Update multiple items (async)
|
|
1223
|
-
*/
|
|
1224
|
-
updateManyAsync(dtos: DtoT[]): Promise<IBulkResponse<InterfaceT>>;
|
|
1225
|
-
/**
|
|
1226
|
-
* Delete items (async)
|
|
929
|
+
* Wire up the ControlValueAccessor ↔ signal bridge.
|
|
930
|
+
* Call once at the end of the subclass constructor.
|
|
931
|
+
*
|
|
932
|
+
* Signal-form consumers ([formField]) don't need this — Angular's
|
|
933
|
+
* FormField directive binds directly to `value`.
|
|
934
|
+
*
|
|
935
|
+
* @example
|
|
936
|
+
* constructor() { super(); this.initializeFormControl(); }
|
|
1227
937
|
*/
|
|
1228
|
-
|
|
938
|
+
protected initializeFormControl(): void;
|
|
939
|
+
writeValue(value: T): void;
|
|
940
|
+
registerOnChange(fn: (value: T) => void): void;
|
|
941
|
+
registerOnTouched(fn: () => void): void;
|
|
942
|
+
setDisabledState(isDisabled: boolean): void;
|
|
943
|
+
/** Call on blur / panel-close to propagate touched state. */
|
|
944
|
+
protected markAsTouched(): void;
|
|
945
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseFormControl<any>, never>;
|
|
946
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseFormControl<any>, never, never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Factory function to provide NG_VALUE_ACCESSOR for a component.
|
|
950
|
+
* Use in component providers array.
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* ```typescript
|
|
954
|
+
* @Component({
|
|
955
|
+
* providers: [provideValueAccessor(LazySelectComponent)]
|
|
956
|
+
* })
|
|
957
|
+
* export class LazySelectComponent extends BaseFormControl<string | null> {}
|
|
958
|
+
* ```
|
|
959
|
+
*/
|
|
960
|
+
declare function provideValueAccessor<T extends new (...args: unknown[]) => ControlValueAccessor>(component: T): {
|
|
961
|
+
provide: _angular_core.InjectionToken<readonly ControlValueAccessor[]>;
|
|
962
|
+
useExisting: _angular_core.Type<any>;
|
|
963
|
+
multi: boolean;
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
declare class BaseFormTemplateDirective {
|
|
967
|
+
readonly key: _angular_core.InputSignal<string>;
|
|
968
|
+
readonly templateRef: TemplateRef<any>;
|
|
969
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseFormTemplateDirective, never>;
|
|
970
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseFormTemplateDirective, "ng-template[baseFormTemplate]", never, { "key": { "alias": "baseFormTemplate"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
type FormFieldType = 'text' | 'email' | 'password' | 'number' | 'textarea' | 'select' | 'multiselect' | 'date' | 'checkbox' | 'toggle' | 'custom';
|
|
974
|
+
interface IFormSelectOption {
|
|
975
|
+
label: string;
|
|
976
|
+
value: unknown;
|
|
977
|
+
}
|
|
978
|
+
interface IFormField {
|
|
979
|
+
key: string;
|
|
980
|
+
type: FormFieldType;
|
|
981
|
+
label: string;
|
|
982
|
+
placeholder?: string;
|
|
983
|
+
required?: boolean;
|
|
984
|
+
disabled?: boolean;
|
|
985
|
+
fullWidth?: boolean;
|
|
986
|
+
options?: IFormSelectOption[];
|
|
987
|
+
minDate?: Date;
|
|
988
|
+
maxDate?: Date;
|
|
989
|
+
rows?: number;
|
|
990
|
+
min?: number;
|
|
991
|
+
max?: number;
|
|
992
|
+
hint?: string;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
declare class BaseFormComponent {
|
|
996
|
+
private readonly translateAdapter;
|
|
997
|
+
private readonly router;
|
|
998
|
+
private readonly messageService;
|
|
999
|
+
readonly fields: _angular_core.InputSignal<IFormField[]>;
|
|
1000
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
1001
|
+
readonly createTitle: _angular_core.InputSignal<string>;
|
|
1002
|
+
readonly editTitle: _angular_core.InputSignal<string>;
|
|
1003
|
+
readonly columns: _angular_core.InputSignal<1 | 2 | 3>;
|
|
1004
|
+
readonly submitLabel: _angular_core.InputSignal<string>;
|
|
1005
|
+
readonly cancelLabel: _angular_core.InputSignal<string>;
|
|
1006
|
+
readonly isLoading: _angular_core.InputSignal<boolean>;
|
|
1007
|
+
readonly isEditMode: _angular_core.InputSignal<boolean>;
|
|
1008
|
+
readonly initialValue: _angular_core.InputSignal<Record<string, unknown>>;
|
|
1009
|
+
readonly service: _angular_core.InputSignal<ApiResourceService<unknown, unknown> | null>;
|
|
1010
|
+
readonly editId: _angular_core.InputSignal<string | null>;
|
|
1011
|
+
readonly cancelRoute: _angular_core.InputSignal<string | string[] | null>;
|
|
1012
|
+
readonly navigateOnSuccess: _angular_core.InputSignal<string | string[] | null>;
|
|
1013
|
+
readonly mapToRequest: _angular_core.InputSignal<((data: Record<string, unknown>, editId: string | null) => unknown) | null>;
|
|
1014
|
+
readonly mapFromEntity: _angular_core.InputSignal<((entity: unknown) => Record<string, unknown>) | null>;
|
|
1015
|
+
readonly onSubmit: _angular_core.OutputEmitterRef<Record<string, unknown>>;
|
|
1016
|
+
readonly onCancel: _angular_core.OutputEmitterRef<void>;
|
|
1017
|
+
readonly onValueChange: _angular_core.OutputEmitterRef<Record<string, unknown>>;
|
|
1018
|
+
readonly fieldTemplates: _angular_core.Signal<readonly BaseFormTemplateDirective[]>;
|
|
1019
|
+
private readonly _formData;
|
|
1020
|
+
private readonly _submitted;
|
|
1021
|
+
private readonly _isLoadingInternal;
|
|
1022
|
+
private readonly _touchedFields;
|
|
1023
|
+
private readonly _visiblePasswordFields;
|
|
1024
|
+
readonly formData: _angular_core.Signal<Record<string, unknown>>;
|
|
1025
|
+
readonly submitted: _angular_core.Signal<boolean>;
|
|
1026
|
+
readonly effectiveIsEditMode: _angular_core.Signal<boolean>;
|
|
1027
|
+
readonly effectiveIsLoading: _angular_core.Signal<boolean>;
|
|
1028
|
+
readonly isFormValid: _angular_core.Signal<boolean>;
|
|
1029
|
+
readonly resolvedTitle: _angular_core.Signal<string>;
|
|
1030
|
+
readonly gridClass: _angular_core.Signal<"grid-cols-1" | "grid-cols-1 md:grid-cols-3" | "grid-cols-1 md:grid-cols-2">;
|
|
1031
|
+
constructor();
|
|
1032
|
+
private loadEntity;
|
|
1033
|
+
getFieldValue(key: string): unknown;
|
|
1034
|
+
setFieldValue(key: string, value: unknown): void;
|
|
1035
|
+
markFieldTouched(key: string): void;
|
|
1036
|
+
isPasswordVisible(key: string): boolean;
|
|
1037
|
+
togglePasswordVisibility(key: string): void;
|
|
1038
|
+
isFieldInvalid(field: IFormField): boolean;
|
|
1039
|
+
getFieldTemplate(key: string): TemplateRef<unknown> | null;
|
|
1040
|
+
handleSubmit(): Promise<void>;
|
|
1041
|
+
handleCancel(): void;
|
|
1042
|
+
reset(): void;
|
|
1043
|
+
t(key: string, vars?: Record<string, string | number>): string;
|
|
1044
|
+
private managedSubmit;
|
|
1045
|
+
private checkValidity;
|
|
1046
|
+
private navigateTo;
|
|
1047
|
+
private getDefaultValue;
|
|
1048
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseFormComponent, never>;
|
|
1049
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseFormComponent, "lib-base-form", never, { "fields": { "alias": "fields"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "createTitle": { "alias": "createTitle"; "required": false; "isSignal": true; }; "editTitle": { "alias": "editTitle"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "submitLabel": { "alias": "submitLabel"; "required": false; "isSignal": true; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": false; "isSignal": true; }; "initialValue": { "alias": "initialValue"; "required": false; "isSignal": true; }; "service": { "alias": "service"; "required": false; "isSignal": true; }; "editId": { "alias": "editId"; "required": false; "isSignal": true; }; "cancelRoute": { "alias": "cancelRoute"; "required": false; "isSignal": true; }; "navigateOnSuccess": { "alias": "navigateOnSuccess"; "required": false; "isSignal": true; }; "mapToRequest": { "alias": "mapToRequest"; "required": false; "isSignal": true; }; "mapFromEntity": { "alias": "mapFromEntity"; "required": false; "isSignal": true; }; }, { "onSubmit": "onSubmit"; "onCancel": "onCancel"; "onValueChange": "onValueChange"; }, ["fieldTemplates"], never, true, never>;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
declare class BaseListTemplateDirective {
|
|
1053
|
+
readonly key: _angular_core.InputSignal<string>;
|
|
1054
|
+
readonly templateRef: TemplateRef<any>;
|
|
1055
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseListTemplateDirective, never>;
|
|
1056
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseListTemplateDirective, "ng-template[baseListTemplate]", never, { "key": { "alias": "baseListTemplate"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
type TableColumnType = 'text' | 'date' | 'tag' | 'boolean' | 'number' | 'custom';
|
|
1060
|
+
type ActionSeverity = 'success' | 'info' | 'warn' | 'danger' | 'secondary' | 'contrast';
|
|
1061
|
+
interface ITagConfig {
|
|
1062
|
+
label?: string;
|
|
1063
|
+
severity: 'success' | 'danger' | 'warn' | 'info' | 'secondary' | 'contrast';
|
|
1064
|
+
}
|
|
1065
|
+
interface ITableColumn {
|
|
1066
|
+
field: string;
|
|
1067
|
+
header: string;
|
|
1068
|
+
type?: TableColumnType;
|
|
1069
|
+
width?: string;
|
|
1070
|
+
minWidth?: string;
|
|
1071
|
+
align?: 'left' | 'center' | 'right';
|
|
1072
|
+
tagMap?: Record<string, ITagConfig>;
|
|
1073
|
+
dateFormat?: string;
|
|
1074
|
+
truncate?: number;
|
|
1075
|
+
hidden?: boolean;
|
|
1076
|
+
}
|
|
1077
|
+
interface ITableAction<T = unknown> {
|
|
1078
|
+
icon: string;
|
|
1079
|
+
tooltip?: string;
|
|
1080
|
+
severity?: ActionSeverity;
|
|
1081
|
+
show?: (item: T) => boolean;
|
|
1082
|
+
disabled?: (item: T) => boolean;
|
|
1083
|
+
handler: (item: T) => void;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
declare class BaseListComponent {
|
|
1087
|
+
private readonly translateAdapter;
|
|
1088
|
+
private readonly router;
|
|
1089
|
+
private readonly messageService;
|
|
1090
|
+
private readonly confirmationService;
|
|
1091
|
+
readonly columns: _angular_core.InputSignal<ITableColumn[]>;
|
|
1092
|
+
readonly actions: _angular_core.InputSignal<ITableAction<unknown>[]>;
|
|
1093
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
1094
|
+
readonly showCreateButton: _angular_core.InputSignal<boolean>;
|
|
1095
|
+
readonly searchable: _angular_core.InputSignal<boolean>;
|
|
1096
|
+
readonly pageSize: _angular_core.InputSignal<number>;
|
|
1097
|
+
readonly emptyMessage: _angular_core.InputSignal<string>;
|
|
1098
|
+
readonly createButtonLabel: _angular_core.InputSignal<string>;
|
|
1099
|
+
readonly createButtonIcon: _angular_core.InputSignal<string>;
|
|
1100
|
+
readonly data: _angular_core.InputSignal<unknown[]>;
|
|
1101
|
+
readonly total: _angular_core.InputSignal<number>;
|
|
1102
|
+
readonly isLoading: _angular_core.InputSignal<boolean>;
|
|
1103
|
+
readonly service: _angular_core.InputSignal<ApiResourceService<unknown, unknown> | null>;
|
|
1104
|
+
readonly filter: _angular_core.InputSignal<IFilter>;
|
|
1105
|
+
readonly createRoute: _angular_core.InputSignal<string | null>;
|
|
1106
|
+
readonly editRoute: _angular_core.InputSignal<string | null>;
|
|
1107
|
+
readonly deleteConfirmField: _angular_core.InputSignal<string | null>;
|
|
1108
|
+
readonly idField: _angular_core.InputSignal<string>;
|
|
1109
|
+
readonly canEdit: _angular_core.InputSignal<((item: unknown) => boolean) | null>;
|
|
1110
|
+
readonly canDelete: _angular_core.InputSignal<((item: unknown) => boolean) | null>;
|
|
1111
|
+
readonly onCreate: _angular_core.OutputEmitterRef<void>;
|
|
1112
|
+
readonly onLazyLoad: _angular_core.OutputEmitterRef<{
|
|
1113
|
+
first: number;
|
|
1114
|
+
rows: number;
|
|
1115
|
+
}>;
|
|
1116
|
+
readonly onSearch: _angular_core.OutputEmitterRef<string>;
|
|
1117
|
+
readonly columnTemplates: _angular_core.Signal<readonly BaseListTemplateDirective[]>;
|
|
1118
|
+
private readonly _first;
|
|
1119
|
+
private readonly _searchTerm;
|
|
1120
|
+
readonly first: _angular_core.Signal<number>;
|
|
1121
|
+
readonly searchTerm: _angular_core.Signal<string>;
|
|
1122
|
+
readonly effectiveData: _angular_core.Signal<unknown[]>;
|
|
1123
|
+
readonly effectiveTotal: _angular_core.Signal<number>;
|
|
1124
|
+
readonly effectiveIsLoading: _angular_core.Signal<boolean>;
|
|
1125
|
+
readonly effectiveActions: _angular_core.Signal<ITableAction<unknown>[]>;
|
|
1126
|
+
readonly visibleColumns: _angular_core.Signal<ITableColumn[]>;
|
|
1127
|
+
readonly columnCount: _angular_core.Signal<number>;
|
|
1128
|
+
readonly resolvedEmptyMessage: _angular_core.Signal<string>;
|
|
1129
|
+
readonly resolvedCreateLabel: _angular_core.Signal<string>;
|
|
1130
|
+
handleLazyLoad(event: {
|
|
1131
|
+
first?: number | null;
|
|
1132
|
+
rows?: number | null;
|
|
1133
|
+
}): void;
|
|
1134
|
+
onSearchChange(value: string): void;
|
|
1135
|
+
handleCreate(): void;
|
|
1136
|
+
private handleEditItem;
|
|
1137
|
+
private handleDeleteItem;
|
|
1138
|
+
getFieldValue(item: unknown, field: string): unknown;
|
|
1139
|
+
getFieldValueAsString(item: unknown, field: string): string;
|
|
1140
|
+
getTagConfig(col: ITableColumn, value: unknown): ITagConfig | null;
|
|
1141
|
+
getColumnTemplate(field: string): TemplateRef<unknown> | null;
|
|
1142
|
+
truncateText(value: unknown, limit?: number): string;
|
|
1143
|
+
getCellClass(col: ITableColumn): string;
|
|
1144
|
+
t(key: string, vars?: Record<string, string | number>): string;
|
|
1145
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseListComponent, never>;
|
|
1146
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseListComponent, "lib-base-list", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "showCreateButton": { "alias": "showCreateButton"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "createButtonLabel": { "alias": "createButtonLabel"; "required": false; "isSignal": true; }; "createButtonIcon": { "alias": "createButtonIcon"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": false; "isSignal": true; }; "service": { "alias": "service"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "createRoute": { "alias": "createRoute"; "required": false; "isSignal": true; }; "editRoute": { "alias": "editRoute"; "required": false; "isSignal": true; }; "deleteConfirmField": { "alias": "deleteConfirmField"; "required": false; "isSignal": true; }; "idField": { "alias": "idField"; "required": false; "isSignal": true; }; "canEdit": { "alias": "canEdit"; "required": false; "isSignal": true; }; "canDelete": { "alias": "canDelete"; "required": false; "isSignal": true; }; }, { "onCreate": "onCreate"; "onLazyLoad": "onLazyLoad"; "onSearch": "onSearch"; }, ["columnTemplates"], never, true, never>;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
declare class FileSelectorDialogComponent {
|
|
1150
|
+
private readonly destroyRef;
|
|
1151
|
+
private readonly translateAdapter;
|
|
1152
|
+
readonly fileProvider: _flusys_ng_shared.IFileProvider | null;
|
|
1153
|
+
private abortController;
|
|
1154
|
+
private searchDebounceTimer;
|
|
1155
|
+
readonly header: _angular_core.InputSignal<string | undefined>;
|
|
1156
|
+
readonly acceptTypes: _angular_core.InputSignal<string[]>;
|
|
1157
|
+
readonly multiple: _angular_core.InputSignal<boolean>;
|
|
1158
|
+
readonly dialogHeader: _angular_core.Signal<string>;
|
|
1159
|
+
readonly maxSelection: _angular_core.InputSignal<number>;
|
|
1160
|
+
readonly pageSize: _angular_core.InputSignal<number>;
|
|
1161
|
+
readonly folderId: _angular_core.InputSignal<string | undefined>;
|
|
1162
|
+
readonly withUploader: _angular_core.InputSignal<boolean>;
|
|
1163
|
+
readonly visible: _angular_core.ModelSignal<boolean>;
|
|
1164
|
+
readonly fileSelected: _angular_core.OutputEmitterRef<IFileBasicInfo>;
|
|
1165
|
+
readonly filesSelected: _angular_core.OutputEmitterRef<IFileBasicInfo[]>;
|
|
1166
|
+
readonly closed: _angular_core.OutputEmitterRef<void>;
|
|
1167
|
+
readonly onError: _angular_core.OutputEmitterRef<Error>;
|
|
1168
|
+
readonly isLoading: _angular_core.WritableSignal<boolean>;
|
|
1169
|
+
readonly files: _angular_core.WritableSignal<IFileBasicInfo[]>;
|
|
1170
|
+
readonly selectedFiles: _angular_core.WritableSignal<IFileBasicInfo[]>;
|
|
1171
|
+
readonly total: _angular_core.WritableSignal<number | undefined>;
|
|
1172
|
+
readonly pagination: _angular_core.WritableSignal<IPagination>;
|
|
1173
|
+
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1174
|
+
readonly folders: _angular_core.WritableSignal<IFolderBasicInfo[]>;
|
|
1175
|
+
readonly selectedFolderId: _angular_core.WritableSignal<string | null>;
|
|
1176
|
+
readonly foldersLoading: _angular_core.WritableSignal<boolean>;
|
|
1177
|
+
readonly foldersPagination: _angular_core.WritableSignal<IPagination>;
|
|
1178
|
+
readonly foldersTotal: _angular_core.WritableSignal<number | undefined>;
|
|
1179
|
+
readonly storageConfigs: _angular_core.WritableSignal<IStorageConfigBasicInfo[]>;
|
|
1180
|
+
readonly selectedStorageConfigId: _angular_core.WritableSignal<string | null>;
|
|
1181
|
+
readonly storageConfigsLoading: _angular_core.WritableSignal<boolean>;
|
|
1182
|
+
readonly storageConfigsPagination: _angular_core.WritableSignal<IPagination>;
|
|
1183
|
+
readonly storageConfigsTotal: _angular_core.WritableSignal<number | undefined>;
|
|
1184
|
+
readonly effectiveStorageConfigId: _angular_core.Signal<string | undefined>;
|
|
1185
|
+
readonly uploadFileFn: (file: File, options?: IFileUploadOptions) => rxjs.Observable<_flusys_ng_shared.ISingleResponse<IUploadedFile>>;
|
|
1186
|
+
readonly uploadMultipleFilesFn: ((files: File[], options?: IFileUploadOptions) => rxjs.Observable<_flusys_ng_shared.ISingleResponse<IUploadedFile[]>>) | undefined;
|
|
1187
|
+
constructor();
|
|
1188
|
+
onSearchChange(value: string): void;
|
|
1189
|
+
onScroll(event: Event): void;
|
|
1190
|
+
toggleSelection(file: IFileBasicInfo): void;
|
|
1191
|
+
isSelected(file: IFileBasicInfo): boolean;
|
|
1192
|
+
isFileAllowed(file: IFileBasicInfo): boolean;
|
|
1193
|
+
isImage(file: IFileBasicInfo): boolean;
|
|
1194
|
+
getFileIcon(file: IFileBasicInfo): string;
|
|
1195
|
+
formatSize(size: string): string;
|
|
1196
|
+
onCancel(): void;
|
|
1197
|
+
onConfirm(): void;
|
|
1198
|
+
onDialogHide(): void;
|
|
1199
|
+
onFolderChange(folderId: string | null): void;
|
|
1200
|
+
onFolderSearch(event: {
|
|
1201
|
+
filter: string;
|
|
1202
|
+
}): void;
|
|
1203
|
+
loadFolders(search?: string): Promise<void>;
|
|
1204
|
+
onStorageConfigChange(configId: string | null): void;
|
|
1205
|
+
onStorageConfigSearch(event: {
|
|
1206
|
+
filter: string;
|
|
1207
|
+
}): void;
|
|
1208
|
+
loadStorageConfigs(search?: string): Promise<void>;
|
|
1209
|
+
onFileUploaded(uploadedFile: IUploadedFile): void;
|
|
1210
|
+
private resetState;
|
|
1211
|
+
private fetchFiles;
|
|
1212
|
+
private t;
|
|
1213
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileSelectorDialogComponent, never>;
|
|
1214
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileSelectorDialogComponent, "lib-file-selector-dialog", never, { "header": { "alias": "header"; "required": false; "isSignal": true; }; "acceptTypes": { "alias": "acceptTypes"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "maxSelection": { "alias": "maxSelection"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "folderId": { "alias": "folderId"; "required": false; "isSignal": true; }; "withUploader": { "alias": "withUploader"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; }, { "visible": "visibleChange"; "fileSelected": "fileSelected"; "filesSelected": "filesSelected"; "closed": "closed"; "onError": "onError"; }, never, never, true, never>;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
declare class FileUploaderComponent {
|
|
1218
|
+
private readonly messageService;
|
|
1219
|
+
private readonly translateAdapter;
|
|
1220
|
+
private readonly fileProvider;
|
|
1221
|
+
readonly uploadFile: _angular_core.InputSignal<UploadFileFn | undefined>;
|
|
1222
|
+
readonly uploadMultipleFiles: _angular_core.InputSignal<UploadMultipleFilesFn | undefined>;
|
|
1223
|
+
readonly hasUploadCapability: _angular_core.Signal<boolean>;
|
|
1224
|
+
private getUploadFn;
|
|
1225
|
+
private getUploadMultipleFn;
|
|
1226
|
+
readonly acceptTypes: _angular_core.InputSignal<string[]>;
|
|
1227
|
+
readonly multiple: _angular_core.InputSignal<boolean>;
|
|
1228
|
+
readonly maxFiles: _angular_core.InputSignal<number>;
|
|
1229
|
+
readonly maxSizeMb: _angular_core.InputSignal<number>;
|
|
1230
|
+
readonly uploadOptions: _angular_core.InputSignal<IFileUploadOptions>;
|
|
1231
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
1232
|
+
readonly showPreview: _angular_core.InputSignal<boolean>;
|
|
1233
|
+
readonly autoUpload: _angular_core.InputSignal<boolean>;
|
|
1234
|
+
readonly fileUploaded: _angular_core.OutputEmitterRef<IUploadedFile>;
|
|
1235
|
+
readonly filesUploaded: _angular_core.OutputEmitterRef<IUploadedFile[]>;
|
|
1236
|
+
readonly onError: _angular_core.OutputEmitterRef<Error>;
|
|
1237
|
+
readonly fileSelected: _angular_core.OutputEmitterRef<File[]>;
|
|
1238
|
+
readonly isUploading: _angular_core.WritableSignal<boolean>;
|
|
1239
|
+
readonly isDragOver: _angular_core.WritableSignal<boolean>;
|
|
1240
|
+
readonly uploadProgress: _angular_core.WritableSignal<number>;
|
|
1241
|
+
readonly uploadingFileName: _angular_core.WritableSignal<string>;
|
|
1242
|
+
readonly selectedFiles: _angular_core.WritableSignal<File[]>;
|
|
1243
|
+
readonly acceptString: _angular_core.Signal<string>;
|
|
1244
|
+
readonly acceptTypesDisplay: _angular_core.Signal<string>;
|
|
1245
|
+
onDragOver(event: DragEvent): void;
|
|
1246
|
+
onDragLeave(event: DragEvent): void;
|
|
1247
|
+
onDrop(event: DragEvent): void;
|
|
1248
|
+
onFileSelected(event: Event): void;
|
|
1249
|
+
private handleFiles;
|
|
1250
|
+
removeFile(file: File): void;
|
|
1251
|
+
uploadFiles(files?: File[]): Promise<void>;
|
|
1252
|
+
private uploadBatch;
|
|
1253
|
+
private uploadSequential;
|
|
1254
|
+
getFileIcon(file: File): string;
|
|
1255
|
+
formatSize(bytes: number): string;
|
|
1256
|
+
private t;
|
|
1257
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUploaderComponent, never>;
|
|
1258
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileUploaderComponent, "lib-file-uploader", never, { "uploadFile": { "alias": "uploadFile"; "required": false; "isSignal": true; }; "uploadMultipleFiles": { "alias": "uploadMultipleFiles"; "required": false; "isSignal": true; }; "acceptTypes": { "alias": "acceptTypes"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "maxSizeMb": { "alias": "maxSizeMb"; "required": false; "isSignal": true; }; "uploadOptions": { "alias": "uploadOptions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showPreview": { "alias": "showPreview"; "required": false; "isSignal": true; }; "autoUpload": { "alias": "autoUpload"; "required": false; "isSignal": true; }; }, { "fileUploaded": "fileUploaded"; "filesUploaded": "filesUploaded"; "onError": "onError"; "fileSelected": "fileSelected"; }, never, never, true, never>;
|
|
1229
1259
|
}
|
|
1230
1260
|
|
|
1231
1261
|
declare class IconComponent {
|
|
@@ -1236,77 +1266,13 @@ declare class IconComponent {
|
|
|
1236
1266
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<IconComponent, "lib-icon", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "iconType": { "alias": "iconType"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1237
1267
|
}
|
|
1238
1268
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
* Implements both `ControlValueAccessor` (reactive forms) and `FormValueControl` (signal forms).
|
|
1247
|
-
*
|
|
1248
|
-
* @example
|
|
1249
|
-
* ```typescript
|
|
1250
|
-
* @Component({
|
|
1251
|
-
* providers: [provideValueAccessor(MySelectComponent)]
|
|
1252
|
-
* })
|
|
1253
|
-
* export class MySelectComponent extends BaseFormControl<string | null> {
|
|
1254
|
-
* override readonly value = model<string | null>(null);
|
|
1255
|
-
*
|
|
1256
|
-
* constructor() {
|
|
1257
|
-
* super();
|
|
1258
|
-
* this.initializeFormControl();
|
|
1259
|
-
* }
|
|
1260
|
-
* }
|
|
1261
|
-
*
|
|
1262
|
-
* // Usage:
|
|
1263
|
-
* // Template-driven: <my-select [(value)]="selectedId" />
|
|
1264
|
-
* // Reactive forms: <my-select [formControl]="myControl" />
|
|
1265
|
-
* // Signal forms: <my-select [formField]="formTree.myField" />
|
|
1266
|
-
* ```
|
|
1267
|
-
*/
|
|
1268
|
-
declare abstract class BaseFormControl<T> implements ControlValueAccessor, FormValueControl<T> {
|
|
1269
|
-
protected readonly injector: Injector;
|
|
1270
|
-
/**
|
|
1271
|
-
* The value model - must be overridden in subclass with model<T>().
|
|
1272
|
-
* This property satisfies both:
|
|
1273
|
-
* - FormValueControl interface (signal forms)
|
|
1274
|
-
* - Internal state for ControlValueAccessor (reactive forms)
|
|
1275
|
-
*/
|
|
1276
|
-
abstract readonly value: ReturnType<typeof model<T>>;
|
|
1277
|
-
/**
|
|
1278
|
-
* Disabled state model - bound to form control disabled state.
|
|
1279
|
-
* Using model() to satisfy FormValueControl interface requirements.
|
|
1280
|
-
*/
|
|
1281
|
-
readonly disabled: _angular_core.ModelSignal<boolean>;
|
|
1282
|
-
/**
|
|
1283
|
-
* Touched state model - for validation styling.
|
|
1284
|
-
* Using model() to satisfy FormValueControl interface requirements.
|
|
1285
|
-
*/
|
|
1286
|
-
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
1287
|
-
private onChange;
|
|
1288
|
-
private onTouched;
|
|
1289
|
-
private isWritingValue;
|
|
1290
|
-
/**
|
|
1291
|
-
* Initialize the form control synchronization for ControlValueAccessor.
|
|
1292
|
-
* Must be called in the subclass constructor after super().
|
|
1293
|
-
*
|
|
1294
|
-
* Note: For signal forms ([formField]), this is not needed as
|
|
1295
|
-
* the FormField directive binds directly to the value model.
|
|
1296
|
-
*/
|
|
1297
|
-
protected initializeFormControl(): void;
|
|
1298
|
-
/** ControlValueAccessor: Write value from form control to signal */
|
|
1299
|
-
writeValue(value: T): void;
|
|
1300
|
-
/** ControlValueAccessor: Register change callback */
|
|
1301
|
-
registerOnChange(fn: (value: T) => void): void;
|
|
1302
|
-
/** ControlValueAccessor: Register touched callback */
|
|
1303
|
-
registerOnTouched(fn: () => void): void;
|
|
1304
|
-
/** ControlValueAccessor: Set disabled state from form control */
|
|
1305
|
-
setDisabledState(isDisabled: boolean): void;
|
|
1306
|
-
/** Mark the control as touched (call on blur or panel close) */
|
|
1307
|
-
protected markAsTouched(): void;
|
|
1308
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseFormControl<any>, never>;
|
|
1309
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseFormControl<any>, never, never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
1269
|
+
declare class InlineSvgComponent {
|
|
1270
|
+
readonly src: _angular_core.InputSignal<string>;
|
|
1271
|
+
private readonly http;
|
|
1272
|
+
private readonly sanitizer;
|
|
1273
|
+
readonly svg: _angular_core.ResourceRef<_angular_platform_browser.SafeHtml | undefined>;
|
|
1274
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<InlineSvgComponent, never>;
|
|
1275
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<InlineSvgComponent, "inline-svg", never, { "src": { "alias": "src"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1310
1276
|
}
|
|
1311
1277
|
|
|
1312
1278
|
/**
|
|
@@ -1317,38 +1283,45 @@ declare abstract class BaseFormControl<T> implements ControlValueAccessor, FormV
|
|
|
1317
1283
|
* - Reactive forms: `[formControl]="ctrl"` or `formControlName="field"`
|
|
1318
1284
|
* - Signal forms: `[formField]="formTree.field"`
|
|
1319
1285
|
*/
|
|
1320
|
-
declare class LazyMultiSelectComponent extends BaseFormControl<string[] | null> {
|
|
1286
|
+
declare class LazyMultiSelectComponent extends BaseFormControl<string[] | null> implements OnDestroy {
|
|
1287
|
+
private readonly document;
|
|
1288
|
+
private readonly appRef;
|
|
1289
|
+
private readonly translateAdapter;
|
|
1290
|
+
private readonly onDocumentClickBound;
|
|
1291
|
+
readonly pSelectRef: _angular_core.Signal<ElementRef<HTMLDivElement>>;
|
|
1292
|
+
readonly overlayTemplate: _angular_core.Signal<TemplateRef<unknown>>;
|
|
1293
|
+
private overlayViewRef;
|
|
1321
1294
|
readonly placeHolder: _angular_core.InputSignal<string>;
|
|
1295
|
+
readonly showClear: _angular_core.InputSignal<boolean>;
|
|
1296
|
+
readonly displayPlaceholder: _angular_core.Signal<string>;
|
|
1322
1297
|
readonly isEditMode: _angular_core.InputSignal<boolean>;
|
|
1323
1298
|
readonly isLoading: _angular_core.InputSignal<boolean>;
|
|
1324
1299
|
readonly total: _angular_core.InputSignal<number | undefined>;
|
|
1325
1300
|
readonly pagination: _angular_core.InputSignal<IPagination>;
|
|
1326
1301
|
readonly selectDataList: _angular_core.InputSignal<IDropDown[]>;
|
|
1327
|
-
/** Two-way bound value using model() for signal forms compatibility */
|
|
1328
1302
|
readonly value: _angular_core.ModelSignal<string[] | null>;
|
|
1329
1303
|
readonly onSearch: _angular_core.OutputEmitterRef<string>;
|
|
1330
1304
|
readonly onPagination: _angular_core.OutputEmitterRef<IPagination>;
|
|
1331
1305
|
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1332
|
-
|
|
1306
|
+
readonly openOptions: _angular_core.WritableSignal<boolean>;
|
|
1333
1307
|
readonly selectedValueDisplay: _angular_core.Signal<string>;
|
|
1334
|
-
|
|
1308
|
+
readonly hasSelectedValues: _angular_core.Signal<boolean>;
|
|
1335
1309
|
readonly isSelectAll: _angular_core.Signal<boolean>;
|
|
1336
1310
|
constructor();
|
|
1337
|
-
|
|
1338
|
-
readonly multiScrollContainer: _angular_core.Signal<ElementRef<HTMLDivElement>>;
|
|
1311
|
+
ngOnDestroy(): void;
|
|
1339
1312
|
onScroll(event: Event): void;
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1313
|
+
onSelectClick(): void;
|
|
1314
|
+
private openOverlay;
|
|
1315
|
+
private closeOverlay;
|
|
1343
1316
|
onOverlayClick(event: Event): void;
|
|
1344
|
-
handleDocumentClick
|
|
1345
|
-
isSelected(data: IDropDown): boolean
|
|
1346
|
-
key(option: IDropDown): string;
|
|
1317
|
+
private handleDocumentClick;
|
|
1318
|
+
isSelected(data: IDropDown): boolean;
|
|
1347
1319
|
selectValue(event: CheckboxChangeEvent, option: IDropDown): void;
|
|
1348
1320
|
changeSelectAll(event: CheckboxChangeEvent): void;
|
|
1349
1321
|
clear(event: Event): void;
|
|
1322
|
+
private t;
|
|
1350
1323
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LazyMultiSelectComponent, never>;
|
|
1351
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LazyMultiSelectComponent, "lib-lazy-multi-select", never, { "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": true; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": true; "isSignal": true; }; "selectDataList": { "alias": "selectDataList"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onSearch": "onSearch"; "onPagination": "onPagination"; }, never, never, true, never>;
|
|
1324
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LazyMultiSelectComponent, "lib-lazy-multi-select", never, { "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": true; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": true; "isSignal": true; }; "selectDataList": { "alias": "selectDataList"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onSearch": "onSearch"; "onPagination": "onPagination"; }, never, never, true, never>;
|
|
1352
1325
|
}
|
|
1353
1326
|
|
|
1354
1327
|
/**
|
|
@@ -1360,7 +1333,15 @@ declare class LazyMultiSelectComponent extends BaseFormControl<string[] | null>
|
|
|
1360
1333
|
* - Signal forms: `[formField]="formTree.field"`
|
|
1361
1334
|
*/
|
|
1362
1335
|
declare class LazySelectComponent extends BaseFormControl<string | null> {
|
|
1336
|
+
private readonly destroyRef;
|
|
1337
|
+
private readonly translateAdapter;
|
|
1338
|
+
private readonly onScrollBound;
|
|
1339
|
+
private scrollTargetEl;
|
|
1340
|
+
private isDestroyed;
|
|
1341
|
+
readonly scrollContainer: _angular_core.Signal<ElementRef<HTMLDivElement>>;
|
|
1363
1342
|
readonly placeHolder: _angular_core.InputSignal<string>;
|
|
1343
|
+
readonly showClear: _angular_core.InputSignal<boolean>;
|
|
1344
|
+
readonly displayPlaceholder: _angular_core.Signal<string>;
|
|
1364
1345
|
readonly optionLabel: _angular_core.InputSignal<string>;
|
|
1365
1346
|
readonly optionValue: _angular_core.InputSignal<string>;
|
|
1366
1347
|
readonly isEditMode: _angular_core.InputSignal<boolean>;
|
|
@@ -1368,62 +1349,52 @@ declare class LazySelectComponent extends BaseFormControl<string | null> {
|
|
|
1368
1349
|
readonly total: _angular_core.InputSignal<number | undefined>;
|
|
1369
1350
|
readonly pagination: _angular_core.InputSignal<IPagination>;
|
|
1370
1351
|
readonly selectDataList: _angular_core.InputSignal<IDropDown[]>;
|
|
1371
|
-
/** Two-way bound value using model() for signal forms compatibility */
|
|
1372
1352
|
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1373
1353
|
readonly onSearch: _angular_core.OutputEmitterRef<string>;
|
|
1374
1354
|
readonly onPagination: _angular_core.OutputEmitterRef<IPagination>;
|
|
1375
1355
|
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1356
|
+
readonly isPanelShow: _angular_core.WritableSignal<boolean>;
|
|
1376
1357
|
constructor();
|
|
1377
|
-
isPanelShow: _angular_core.WritableSignal<boolean>;
|
|
1378
|
-
scrollTargetEl: HTMLElement | null;
|
|
1379
|
-
private readonly onScrollBound;
|
|
1380
|
-
readonly scrollContainer: _angular_core.Signal<ElementRef<HTMLDivElement>>;
|
|
1381
1358
|
onScroll(event: Event): void;
|
|
1382
1359
|
showPanel(): void;
|
|
1383
1360
|
onBlur(): void;
|
|
1361
|
+
private t;
|
|
1384
1362
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LazySelectComponent, never>;
|
|
1385
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LazySelectComponent, "lib-lazy-select", never, { "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": true; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": true; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": true; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": true; "isSignal": true; }; "selectDataList": { "alias": "selectDataList"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onSearch": "onSearch"; "onPagination": "onPagination"; }, never, never, true, never>;
|
|
1363
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LazySelectComponent, "lib-lazy-select", never, { "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": true; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": true; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": true; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": true; "isSignal": true; }; "selectDataList": { "alias": "selectDataList"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onSearch": "onSearch"; "onPagination": "onPagination"; }, never, never, true, never>;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
interface RouterTabItem {
|
|
1367
|
+
id: string | number;
|
|
1368
|
+
label: string;
|
|
1369
|
+
icon?: string;
|
|
1370
|
+
route: string | unknown[];
|
|
1371
|
+
routerLinkActiveExact?: boolean;
|
|
1372
|
+
}
|
|
1373
|
+
declare class RouterTabsComponent {
|
|
1374
|
+
readonly tabs: _angular_core.InputSignal<RouterTabItem[]>;
|
|
1375
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RouterTabsComponent, never>;
|
|
1376
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RouterTabsComponent, "lib-router-tabs", never, { "tabs": { "alias": "tabs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1386
1377
|
}
|
|
1387
1378
|
|
|
1388
1379
|
/**
|
|
1389
|
-
*
|
|
1390
|
-
*
|
|
1391
|
-
* Uses USER_PROVIDER internally by default, or accepts custom `loadUsers` function.
|
|
1392
|
-
*
|
|
1393
|
-
* Features:
|
|
1394
|
-
* - Search with debouncing (handled by lazy-select)
|
|
1395
|
-
* - Infinite scroll pagination
|
|
1396
|
-
* - Filter active users by default (configurable)
|
|
1397
|
-
* - Supports additional filters via `additionalFilters` input
|
|
1398
|
-
*
|
|
1399
|
-
* @example
|
|
1400
|
-
* ```html
|
|
1401
|
-
* <!-- Simple usage - uses USER_PROVIDER internally -->
|
|
1402
|
-
* <lib-user-select
|
|
1403
|
-
* [(value)]="selectedUserId"
|
|
1404
|
-
* [isEditMode]="true"
|
|
1405
|
-
* />
|
|
1380
|
+
* Base class for user selection components.
|
|
1381
|
+
* Provides shared user loading, pagination, and search functionality.
|
|
1406
1382
|
*
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1409
|
-
* [(value)]="selectedUserId"
|
|
1410
|
-
* [isEditMode]="true"
|
|
1411
|
-
* [loadUsers]="customLoadUsers"
|
|
1412
|
-
* />
|
|
1413
|
-
* ```
|
|
1383
|
+
* Subclasses must implement:
|
|
1384
|
+
* - `setupValueEffect()` to track value changes and emit selection events
|
|
1414
1385
|
*/
|
|
1415
|
-
declare class
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1386
|
+
declare abstract class BaseUserSelectComponent {
|
|
1387
|
+
protected readonly destroyRef: DestroyRef;
|
|
1388
|
+
protected readonly injector: Injector;
|
|
1389
|
+
protected readonly userProvider: IUserProvider;
|
|
1390
|
+
protected readonly translateAdapter: TranslateService;
|
|
1391
|
+
protected abortController: AbortController | null;
|
|
1419
1392
|
readonly loadUsers: _angular_core.InputSignal<LoadUsersFn | undefined>;
|
|
1420
1393
|
readonly placeHolder: _angular_core.InputSignal<string>;
|
|
1421
1394
|
readonly isEditMode: _angular_core.InputSignal<boolean>;
|
|
1422
1395
|
readonly filterActive: _angular_core.InputSignal<boolean>;
|
|
1423
1396
|
readonly additionalFilters: _angular_core.InputSignal<Record<string, unknown>>;
|
|
1424
1397
|
readonly pageSize: _angular_core.InputSignal<number>;
|
|
1425
|
-
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1426
|
-
readonly userSelected: _angular_core.OutputEmitterRef<IUserBasicInfo | null>;
|
|
1427
1398
|
readonly onError: _angular_core.OutputEmitterRef<Error>;
|
|
1428
1399
|
readonly isLoading: _angular_core.WritableSignal<boolean>;
|
|
1429
1400
|
readonly users: _angular_core.WritableSignal<IUserBasicInfo[]>;
|
|
@@ -1431,16 +1402,20 @@ declare class UserSelectComponent {
|
|
|
1431
1402
|
readonly pagination: _angular_core.WritableSignal<IPagination>;
|
|
1432
1403
|
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1433
1404
|
readonly dropdownUsers: _angular_core.Signal<IDropDown[]>;
|
|
1405
|
+
readonly displayPlaceholder: _angular_core.Signal<string>;
|
|
1434
1406
|
constructor();
|
|
1407
|
+
/** Setup effect to track value changes and emit selection events */
|
|
1408
|
+
protected abstract setupValueEffect(): void;
|
|
1435
1409
|
handleSearch(search: string): void;
|
|
1436
1410
|
handlePagination(pagination: IPagination): void;
|
|
1437
|
-
private fetchUsers;
|
|
1438
|
-
/** Load users from USER_PROVIDER with active filter */
|
|
1439
|
-
private loadUsersFromProvider;
|
|
1440
1411
|
/** Reload users (useful when filters change externally) */
|
|
1441
1412
|
reload(): void;
|
|
1442
|
-
|
|
1443
|
-
|
|
1413
|
+
protected fetchUsers(append?: boolean): Promise<void>;
|
|
1414
|
+
/** Load users from USER_PROVIDER with active filter */
|
|
1415
|
+
private loadUsersFromProvider;
|
|
1416
|
+
protected t(key: string, variables?: Record<string, string | number>): string;
|
|
1417
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseUserSelectComponent, never>;
|
|
1418
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseUserSelectComponent, never, never, { "loadUsers": { "alias": "loadUsers"; "required": false; "isSignal": true; }; "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "filterActive": { "alias": "filterActive"; "required": false; "isSignal": true; }; "additionalFilters": { "alias": "additionalFilters"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; }, { "onError": "onError"; }, never, never, true, never>;
|
|
1444
1419
|
}
|
|
1445
1420
|
|
|
1446
1421
|
/**
|
|
@@ -1471,195 +1446,49 @@ declare class UserSelectComponent {
|
|
|
1471
1446
|
* />
|
|
1472
1447
|
* ```
|
|
1473
1448
|
*/
|
|
1474
|
-
declare class UserMultiSelectComponent {
|
|
1475
|
-
|
|
1476
|
-
private readonly userProvider;
|
|
1477
|
-
private abortController;
|
|
1478
|
-
readonly loadUsers: _angular_core.InputSignal<LoadUsersFn | undefined>;
|
|
1479
|
-
readonly placeHolder: _angular_core.InputSignal<string>;
|
|
1480
|
-
readonly isEditMode: _angular_core.InputSignal<boolean>;
|
|
1481
|
-
readonly filterActive: _angular_core.InputSignal<boolean>;
|
|
1482
|
-
readonly additionalFilters: _angular_core.InputSignal<Record<string, unknown>>;
|
|
1483
|
-
readonly pageSize: _angular_core.InputSignal<number>;
|
|
1449
|
+
declare class UserMultiSelectComponent extends BaseUserSelectComponent {
|
|
1450
|
+
readonly showClear: _angular_core.InputSignal<boolean>;
|
|
1484
1451
|
readonly value: _angular_core.ModelSignal<string[] | null>;
|
|
1485
1452
|
readonly usersSelected: _angular_core.OutputEmitterRef<IUserBasicInfo[]>;
|
|
1486
|
-
|
|
1487
|
-
readonly isLoading: _angular_core.WritableSignal<boolean>;
|
|
1488
|
-
readonly users: _angular_core.WritableSignal<IUserBasicInfo[]>;
|
|
1489
|
-
readonly total: _angular_core.WritableSignal<number | undefined>;
|
|
1490
|
-
readonly pagination: _angular_core.WritableSignal<IPagination>;
|
|
1491
|
-
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1492
|
-
readonly dropdownUsers: _angular_core.Signal<IDropDown[]>;
|
|
1493
|
-
constructor();
|
|
1494
|
-
handleSearch(search: string): void;
|
|
1495
|
-
handlePagination(pagination: IPagination): void;
|
|
1496
|
-
private fetchUsers;
|
|
1497
|
-
/** Load users from USER_PROVIDER with active filter */
|
|
1498
|
-
private loadUsersFromProvider;
|
|
1499
|
-
/** Reload users (useful when filters change externally) */
|
|
1500
|
-
reload(): void;
|
|
1453
|
+
protected setupValueEffect(): void;
|
|
1501
1454
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserMultiSelectComponent, never>;
|
|
1502
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserMultiSelectComponent, "lib-user-multi-select", never, { "
|
|
1455
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserMultiSelectComponent, "lib-user-multi-select", never, { "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "usersSelected": "usersSelected"; }, never, never, true, never>;
|
|
1503
1456
|
}
|
|
1504
1457
|
|
|
1505
1458
|
/**
|
|
1506
|
-
*
|
|
1459
|
+
* User Select Component - Single user selection with lazy loading.
|
|
1507
1460
|
*
|
|
1508
|
-
*
|
|
1461
|
+
* Uses USER_PROVIDER internally by default, or accepts custom `loadUsers` function.
|
|
1509
1462
|
*
|
|
1510
1463
|
* Features:
|
|
1511
|
-
* -
|
|
1512
|
-
* -
|
|
1513
|
-
* -
|
|
1514
|
-
* -
|
|
1515
|
-
* - Image compression options
|
|
1464
|
+
* - Search with debouncing (handled by lazy-select)
|
|
1465
|
+
* - Infinite scroll pagination
|
|
1466
|
+
* - Filter active users by default (configurable)
|
|
1467
|
+
* - Supports additional filters via `additionalFilters` input
|
|
1516
1468
|
*
|
|
1517
1469
|
* @example
|
|
1518
|
-
* ```typescript
|
|
1519
|
-
* // In component
|
|
1520
|
-
* readonly uploadService = inject(UploadService);
|
|
1521
|
-
*
|
|
1522
|
-
* readonly uploadFile: UploadFileFn = (file, options) =>
|
|
1523
|
-
* this.uploadService.uploadSingleFile(file, options);
|
|
1524
|
-
* ```
|
|
1525
|
-
*
|
|
1526
1470
|
* ```html
|
|
1527
|
-
* <!--
|
|
1528
|
-
* <lib-
|
|
1529
|
-
* [
|
|
1530
|
-
* [
|
|
1531
|
-
* [multiple]="false"
|
|
1532
|
-
* (fileUploaded)="onFileUploaded($event)"
|
|
1533
|
-
* />
|
|
1534
|
-
*
|
|
1535
|
-
* <!-- Multiple document upload -->
|
|
1536
|
-
* <lib-file-uploader
|
|
1537
|
-
* [uploadFile]="uploadFile"
|
|
1538
|
-
* [acceptTypes]="FILE_TYPE_FILTERS.DOCUMENTS"
|
|
1539
|
-
* [multiple]="true"
|
|
1540
|
-
* [maxFiles]="5"
|
|
1541
|
-
* (filesUploaded)="onFilesUploaded($event)"
|
|
1471
|
+
* <!-- Simple usage - uses USER_PROVIDER internally -->
|
|
1472
|
+
* <lib-user-select
|
|
1473
|
+
* [(value)]="selectedUserId"
|
|
1474
|
+
* [isEditMode]="true"
|
|
1542
1475
|
* />
|
|
1543
|
-
* ```
|
|
1544
|
-
*/
|
|
1545
|
-
declare class FileUploaderComponent {
|
|
1546
|
-
private readonly messageService;
|
|
1547
|
-
readonly uploadFile: _angular_core.InputSignal<UploadFileFn>;
|
|
1548
|
-
readonly acceptTypes: _angular_core.InputSignal<string[]>;
|
|
1549
|
-
readonly multiple: _angular_core.InputSignal<boolean>;
|
|
1550
|
-
readonly maxFiles: _angular_core.InputSignal<number>;
|
|
1551
|
-
readonly maxSizeMb: _angular_core.InputSignal<number>;
|
|
1552
|
-
readonly uploadOptions: _angular_core.InputSignal<IFileUploadOptions>;
|
|
1553
|
-
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
1554
|
-
readonly showPreview: _angular_core.InputSignal<boolean>;
|
|
1555
|
-
readonly autoUpload: _angular_core.InputSignal<boolean>;
|
|
1556
|
-
readonly fileUploaded: _angular_core.OutputEmitterRef<IUploadedFile>;
|
|
1557
|
-
readonly filesUploaded: _angular_core.OutputEmitterRef<IUploadedFile[]>;
|
|
1558
|
-
readonly onError: _angular_core.OutputEmitterRef<Error>;
|
|
1559
|
-
readonly fileSelected: _angular_core.OutputEmitterRef<File[]>;
|
|
1560
|
-
readonly isUploading: _angular_core.WritableSignal<boolean>;
|
|
1561
|
-
readonly isDragOver: _angular_core.WritableSignal<boolean>;
|
|
1562
|
-
readonly uploadProgress: _angular_core.WritableSignal<number>;
|
|
1563
|
-
readonly uploadingFileName: _angular_core.WritableSignal<string>;
|
|
1564
|
-
readonly selectedFiles: _angular_core.WritableSignal<File[]>;
|
|
1565
|
-
readonly acceptString: _angular_core.Signal<string>;
|
|
1566
|
-
readonly acceptTypesDisplay: _angular_core.Signal<string>;
|
|
1567
|
-
onDragOver(event: DragEvent): void;
|
|
1568
|
-
onDragLeave(event: DragEvent): void;
|
|
1569
|
-
onDrop(event: DragEvent): void;
|
|
1570
|
-
onFileSelected(event: Event): void;
|
|
1571
|
-
private handleFiles;
|
|
1572
|
-
removeFile(file: File): void;
|
|
1573
|
-
uploadFiles(files?: File[]): Promise<void>;
|
|
1574
|
-
getFileIcon(file: File): string;
|
|
1575
|
-
formatSize(bytes: number): string;
|
|
1576
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUploaderComponent, never>;
|
|
1577
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileUploaderComponent, "lib-file-uploader", never, { "uploadFile": { "alias": "uploadFile"; "required": true; "isSignal": true; }; "acceptTypes": { "alias": "acceptTypes"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "maxSizeMb": { "alias": "maxSizeMb"; "required": false; "isSignal": true; }; "uploadOptions": { "alias": "uploadOptions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showPreview": { "alias": "showPreview"; "required": false; "isSignal": true; }; "autoUpload": { "alias": "autoUpload"; "required": false; "isSignal": true; }; }, { "fileUploaded": "fileUploaded"; "filesUploaded": "filesUploaded"; "onError": "onError"; "fileSelected": "fileSelected"; }, never, never, true, never>;
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
/**
|
|
1581
|
-
* File Selector Dialog - Browse and select existing files with filtering.
|
|
1582
|
-
*
|
|
1583
|
-
* Pass your own `loadFiles` function - works with any storage API.
|
|
1584
|
-
*
|
|
1585
|
-
* Features:
|
|
1586
|
-
* - Search with debouncing
|
|
1587
|
-
* - File type filtering
|
|
1588
|
-
* - Infinite scroll pagination
|
|
1589
|
-
* - Single or multiple selection
|
|
1590
|
-
* - File preview with icons
|
|
1591
|
-
*
|
|
1592
|
-
* @example
|
|
1593
|
-
* ```typescript
|
|
1594
|
-
* // In component
|
|
1595
|
-
* readonly fileService = inject(FileManagerApiService);
|
|
1596
|
-
*
|
|
1597
|
-
* readonly loadFiles: LoadFilesFn = (filter) =>
|
|
1598
|
-
* this.fileService.getAll(filter.search, {
|
|
1599
|
-
* pagination: { currentPage: filter.page, pageSize: filter.pageSize },
|
|
1600
|
-
* filter: { contentTypes: filter.contentTypes },
|
|
1601
|
-
* }).pipe(
|
|
1602
|
-
* map(res => ({
|
|
1603
|
-
* ...res,
|
|
1604
|
-
* data: res.data?.map(f => ({
|
|
1605
|
-
* id: f.id,
|
|
1606
|
-
* name: f.name,
|
|
1607
|
-
* contentType: f.contentType,
|
|
1608
|
-
* size: f.size,
|
|
1609
|
-
* url: f.url
|
|
1610
|
-
* }))
|
|
1611
|
-
* }))
|
|
1612
|
-
* );
|
|
1613
|
-
* ```
|
|
1614
1476
|
*
|
|
1615
|
-
*
|
|
1616
|
-
* <lib-
|
|
1617
|
-
* [(
|
|
1618
|
-
* [
|
|
1619
|
-
* [
|
|
1620
|
-
* [multiple]="false"
|
|
1621
|
-
* (fileSelected)="onFileSelected($event)"
|
|
1477
|
+
* <!-- With custom loadUsers function -->
|
|
1478
|
+
* <lib-user-select
|
|
1479
|
+
* [(value)]="selectedUserId"
|
|
1480
|
+
* [isEditMode]="true"
|
|
1481
|
+
* [loadUsers]="customLoadUsers"
|
|
1622
1482
|
* />
|
|
1623
1483
|
* ```
|
|
1624
1484
|
*/
|
|
1625
|
-
declare class
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
readonly multiple: _angular_core.InputSignal<boolean>;
|
|
1633
|
-
readonly maxSelection: _angular_core.InputSignal<number>;
|
|
1634
|
-
readonly pageSize: _angular_core.InputSignal<number>;
|
|
1635
|
-
readonly visible: _angular_core.ModelSignal<boolean>;
|
|
1636
|
-
readonly fileSelected: _angular_core.OutputEmitterRef<IFileBasicInfo>;
|
|
1637
|
-
readonly filesSelected: _angular_core.OutputEmitterRef<IFileBasicInfo[]>;
|
|
1638
|
-
readonly closed: _angular_core.OutputEmitterRef<void>;
|
|
1639
|
-
readonly onError: _angular_core.OutputEmitterRef<Error>;
|
|
1640
|
-
readonly isLoading: _angular_core.WritableSignal<boolean>;
|
|
1641
|
-
readonly files: _angular_core.WritableSignal<IFileBasicInfo[]>;
|
|
1642
|
-
readonly selectedFiles: _angular_core.WritableSignal<IFileBasicInfo[]>;
|
|
1643
|
-
readonly total: _angular_core.WritableSignal<number | undefined>;
|
|
1644
|
-
readonly pagination: _angular_core.WritableSignal<IPagination>;
|
|
1645
|
-
readonly searchTerm: _angular_core.WritableSignal<string>;
|
|
1646
|
-
readonly acceptString: _angular_core.Signal<string>;
|
|
1647
|
-
constructor();
|
|
1648
|
-
onSearchChange(value: string): void;
|
|
1649
|
-
onScroll(event: Event): void;
|
|
1650
|
-
toggleSelection(file: IFileBasicInfo): void;
|
|
1651
|
-
isSelected(file: IFileBasicInfo): boolean;
|
|
1652
|
-
isFileAllowed(file: IFileBasicInfo): boolean;
|
|
1653
|
-
isImage(file: IFileBasicInfo): boolean;
|
|
1654
|
-
getFileIcon(file: IFileBasicInfo): string;
|
|
1655
|
-
formatSize(size: string): string;
|
|
1656
|
-
onCancel(): void;
|
|
1657
|
-
onConfirm(): void;
|
|
1658
|
-
onDialogHide(): void;
|
|
1659
|
-
private resetState;
|
|
1660
|
-
private fetchFiles;
|
|
1661
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileSelectorDialogComponent, never>;
|
|
1662
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FileSelectorDialogComponent, "lib-file-selector-dialog", never, { "loadFiles": { "alias": "loadFiles"; "required": true; "isSignal": true; }; "header": { "alias": "header"; "required": false; "isSignal": true; }; "acceptTypes": { "alias": "acceptTypes"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "maxSelection": { "alias": "maxSelection"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; }, { "visible": "visibleChange"; "fileSelected": "fileSelected"; "filesSelected": "filesSelected"; "closed": "closed"; "onError": "onError"; }, never, never, true, never>;
|
|
1485
|
+
declare class UserSelectComponent extends BaseUserSelectComponent {
|
|
1486
|
+
readonly showClear: _angular_core.InputSignal<boolean>;
|
|
1487
|
+
readonly value: _angular_core.ModelSignal<string | null>;
|
|
1488
|
+
readonly userSelected: _angular_core.OutputEmitterRef<IUserBasicInfo | null>;
|
|
1489
|
+
protected setupValueEffect(): void;
|
|
1490
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserSelectComponent, never>;
|
|
1491
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserSelectComponent, "lib-user-select", never, { "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "userSelected": "userSelected"; }, never, never, true, never>;
|
|
1663
1492
|
}
|
|
1664
1493
|
|
|
1665
1494
|
/**
|
|
@@ -1716,86 +1545,66 @@ declare const AUTH_STATE_PROVIDER: InjectionToken<IAuthStateProvider>;
|
|
|
1716
1545
|
*/
|
|
1717
1546
|
declare const PROFILE_PERMISSION_PROVIDER: InjectionToken<IProfilePermissionProvider>;
|
|
1718
1547
|
/**
|
|
1719
|
-
*
|
|
1720
|
-
*
|
|
1721
|
-
* Provides file upload functionality for profile pictures.
|
|
1722
|
-
* Optional - if not configured or storage not enabled, upload section is hidden.
|
|
1723
|
-
* Use with `inject(PROFILE_UPLOAD_PROVIDER, { optional: true })`.
|
|
1724
|
-
*/
|
|
1725
|
-
declare const PROFILE_UPLOAD_PROVIDER: InjectionToken<IProfileUploadProvider>;
|
|
1726
|
-
/**
|
|
1727
|
-
* User List Provider Token
|
|
1548
|
+
* File Provider Token
|
|
1728
1549
|
*
|
|
1729
|
-
* Provides
|
|
1730
|
-
* Optional - if not configured,
|
|
1731
|
-
* Use with `inject(
|
|
1550
|
+
* Provides file loading and upload functionality for file selectors.
|
|
1551
|
+
* Optional - if not configured, file selector requires loadFiles/uploadFile inputs.
|
|
1552
|
+
* Use with `inject(FILE_PROVIDER, { optional: true })`.
|
|
1732
1553
|
*
|
|
1733
1554
|
* @example
|
|
1734
1555
|
* // In app.config.ts
|
|
1735
1556
|
* providers: [
|
|
1736
|
-
* { provide:
|
|
1557
|
+
* { provide: FILE_PROVIDER, useClass: StorageFileProvider },
|
|
1737
1558
|
* ]
|
|
1738
1559
|
*/
|
|
1739
|
-
declare const
|
|
1560
|
+
declare const FILE_PROVIDER: InjectionToken<IFileProvider>;
|
|
1740
1561
|
|
|
1741
1562
|
/**
|
|
1742
|
-
* Permission Guard
|
|
1743
|
-
*
|
|
1744
|
-
* Route-level guard for permission-based access control.
|
|
1745
|
-
* Validates permissions before allowing navigation.
|
|
1746
|
-
*
|
|
1747
|
-
* Features:
|
|
1748
|
-
* - Single permission check
|
|
1749
|
-
* - Complex ILogicNode logic trees
|
|
1750
|
-
* - Configurable redirect URL
|
|
1751
|
-
* - Debug logging for denied access
|
|
1563
|
+
* Permission Guard - Single permission or ILogicNode check.
|
|
1752
1564
|
*
|
|
1753
1565
|
* @example
|
|
1754
1566
|
* ```typescript
|
|
1755
|
-
* // Simple permission check
|
|
1756
1567
|
* { path: 'users', canActivate: [permissionGuard('user.view')] }
|
|
1757
|
-
*
|
|
1758
|
-
* // Complex logic
|
|
1759
|
-
* { path: 'admin', canActivate: [permissionGuard({
|
|
1760
|
-
* id: 'root',
|
|
1761
|
-
* type: 'group',
|
|
1762
|
-
* operator: 'AND',
|
|
1763
|
-
* children: [
|
|
1764
|
-
* { id: '1', type: 'action', actionId: 'admin.view' },
|
|
1765
|
-
* { id: '2', type: 'action', actionId: 'admin.manage' }
|
|
1766
|
-
* ]
|
|
1767
|
-
* })] }
|
|
1768
|
-
*
|
|
1769
|
-
* // With custom redirect
|
|
1770
|
-
* { path: 'users', canActivate: [permissionGuard('user.view', '/access-denied')] }
|
|
1568
|
+
* { path: 'admin', canActivate: [permissionGuard(logicNode, '/access-denied')] }
|
|
1771
1569
|
* ```
|
|
1772
1570
|
*/
|
|
1773
1571
|
declare function permissionGuard(permission: string | ILogicNode, redirectTo?: string): CanActivateFn;
|
|
1774
1572
|
/**
|
|
1775
|
-
* Any Permission Guard (OR logic)
|
|
1776
|
-
*
|
|
1777
|
-
* Allows access if user has ANY of the specified permissions.
|
|
1573
|
+
* Any Permission Guard (OR logic) - Access if user has ANY permission.
|
|
1778
1574
|
*
|
|
1779
1575
|
* @example
|
|
1780
1576
|
* ```typescript
|
|
1781
|
-
* // Allow if user has view OR create permission
|
|
1782
1577
|
* { path: 'users', canActivate: [anyPermissionGuard(['user.view', 'user.create'])] }
|
|
1783
1578
|
* ```
|
|
1784
1579
|
*/
|
|
1785
1580
|
declare function anyPermissionGuard(permissions: string[], redirectTo?: string): CanActivateFn;
|
|
1786
1581
|
/**
|
|
1787
|
-
* All Permissions Guard (AND logic)
|
|
1788
|
-
*
|
|
1789
|
-
* Allows access only if user has ALL of the specified permissions.
|
|
1582
|
+
* All Permissions Guard (AND logic) - Access only if user has ALL permissions.
|
|
1790
1583
|
*
|
|
1791
1584
|
* @example
|
|
1792
1585
|
* ```typescript
|
|
1793
|
-
* // Allow only if user has BOTH view AND create permissions
|
|
1794
1586
|
* { path: 'admin', canActivate: [allPermissionsGuard(['admin.view', 'admin.manage'])] }
|
|
1795
1587
|
* ```
|
|
1796
1588
|
*/
|
|
1797
1589
|
declare function allPermissionsGuard(permissions: string[], redirectTo?: string): CanActivateFn;
|
|
1798
1590
|
|
|
1591
|
+
declare function localToUtc(dateStr: string, timeStr: string, timezone: string): Date;
|
|
1592
|
+
declare function utcToLocal(utcDate: Date | string, timezone: string): {
|
|
1593
|
+
date: string;
|
|
1594
|
+
time: string;
|
|
1595
|
+
display: string;
|
|
1596
|
+
};
|
|
1597
|
+
declare function formatInTimezone(utcDate: Date | string, timezone: string, options?: Intl.DateTimeFormatOptions): string;
|
|
1598
|
+
declare function getUserTimezone(): string;
|
|
1599
|
+
|
|
1600
|
+
/**
|
|
1601
|
+
* Check if user has a specific permission using wildcard matching.
|
|
1602
|
+
* Supports:
|
|
1603
|
+
* - Exact match: 'user.create' matches 'user.create'
|
|
1604
|
+
* - Full wildcard: '*' matches everything
|
|
1605
|
+
* - Module wildcard: 'user.*' matches 'user.create', 'user.read', etc.
|
|
1606
|
+
*/
|
|
1607
|
+
declare function hasPermission(requiredPermission: string, userPermissions: string[]): boolean;
|
|
1799
1608
|
/** Evaluate permission logic (string or ILogicNode) against user permissions */
|
|
1800
1609
|
declare function evaluatePermission(logic: string | ILogicNode | null | undefined, permissions: string[]): boolean;
|
|
1801
1610
|
/** Recursively evaluate an ILogicNode tree */
|
|
@@ -1805,5 +1614,38 @@ declare function hasAnyPermission(permissionCodes: string[], permissions: string
|
|
|
1805
1614
|
/** Check if user has ALL of the specified permissions (AND logic) */
|
|
1806
1615
|
declare function hasAllPermissions(permissionCodes: string[], permissions: string[]): boolean;
|
|
1807
1616
|
|
|
1808
|
-
|
|
1809
|
-
|
|
1617
|
+
/**
|
|
1618
|
+
* Configuration for scroll pagination behavior
|
|
1619
|
+
*/
|
|
1620
|
+
interface ScrollPaginationConfig {
|
|
1621
|
+
/** Distance from bottom to trigger pagination (default: 50px) */
|
|
1622
|
+
threshold?: number;
|
|
1623
|
+
/** Current pagination state */
|
|
1624
|
+
pagination: IPagination;
|
|
1625
|
+
/** Total items available */
|
|
1626
|
+
total: number | undefined;
|
|
1627
|
+
/** Whether currently loading */
|
|
1628
|
+
isLoading: boolean;
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* Check if scroll has reached near bottom and calculate next page if available.
|
|
1632
|
+
* Returns next pagination if should load more, null otherwise.
|
|
1633
|
+
*
|
|
1634
|
+
* @example
|
|
1635
|
+
* ```typescript
|
|
1636
|
+
* onScroll(event: Event): void {
|
|
1637
|
+
* const nextPagination = checkScrollPagination(event, {
|
|
1638
|
+
* pagination: this.pagination(),
|
|
1639
|
+
* total: this.total(),
|
|
1640
|
+
* isLoading: this.isLoading(),
|
|
1641
|
+
* });
|
|
1642
|
+
* if (nextPagination) {
|
|
1643
|
+
* this.onPagination.emit(nextPagination);
|
|
1644
|
+
* }
|
|
1645
|
+
* }
|
|
1646
|
+
* ```
|
|
1647
|
+
*/
|
|
1648
|
+
declare function checkScrollPagination(event: Event, config: ScrollPaginationConfig): IPagination | null;
|
|
1649
|
+
|
|
1650
|
+
export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormComponent, BaseFormControl, BaseFormTemplateDirective, BaseListComponent, BaseListTemplateDirective, BaseUserSelectComponent, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, COMPANY_PERMISSIONS, CookieService, EMAIL_CONFIG_PERMISSIONS, EMAIL_TEMPLATE_PERMISSIONS, EVENT_PERMISSIONS, EditModeElementChangerDirective, FILE_PERMISSIONS, FILE_PROVIDER, FILE_TYPE_FILTERS, FOLDER_PERMISSIONS, FORM_PERMISSIONS, FORM_RESULT_PERMISSIONS, FaviconService, FileSelectorDialogComponent, FileUploaderComponent, FileUrlService, HasPermissionDirective, IconComponent, IconTypeEnum, InlineSvgComponent, IsEmptyImageDirective, LANGUAGE_PERMISSIONS, LazyMultiSelectComponent, LazySelectComponent, NOTIFICATION_PERMISSIONS, PERMISSIONS, PROFILE_PERMISSION_PROVIDER, PermissionValidatorService, PlatformService, PreventDefaultDirective, ROLE_ACTION_PERMISSIONS, ROLE_PERMISSIONS, RouterTabsComponent, SHARED_MESSAGES, SKIP_ERROR_TOAST, STORAGE_CONFIG_PERMISSIONS, TRANSLATION_KEY_PERMISSIONS, TRANSLATION_PERMISSIONS, TranslatePipe, TranslateService, UPLOAD_CONFIG_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_PERMISSIONS, USER_PERMISSION_PROVIDER, USER_PROVIDER, USER_ROLE_PERMISSIONS, UserMultiSelectComponent, UserSelectComponent, allPermissionsGuard, anyPermissionGuard, checkScrollPagination, errorCatchingInterceptor, evaluateLogicNode, evaluatePermission, formatFileSize, formatInTimezone, getAcceptString, getFileIconClass, getUserTimezone, hasAllPermissions, hasAnyPermission, hasPermission, isFileTypeAllowed, localToUtc, permissionGuard, provideValueAccessor, resolveTranslationModule, utcToLocal };
|
|
1651
|
+
export type { ActionSeverity, DeleteType, FilesResponseDto, FormFieldType, IActionNode, IActivatable, IApiService, IAuthStateProvider, IBaseEntity, IBulkMeta, IBulkResponse, ICompanyApiProvider, ICompanyBasicInfo, IDeleteData, IDropDown, IFileBasicInfo, IFileProvider, IFileSelectFilter, IFileUploadOptions, IFilter, IFilterData, IFolderBasicInfo, IFormField, IFormSelectOption, IGroupNode, IListResponse, ILoggedUserInfo, ILogicNode, IMessageResponse, IOrderable, IPagination, IPaginationMeta, IProfileActionInfo, IProfilePermissionProvider, IProfileRoleInfo, IRequestMeta, IResolverModuleConfig, ISelectFilter, ISingleResponse, ISoftDeletable, ISort, IStorageConfigBasicInfo, ITableAction, ITableColumn, ITagConfig, ITimestampable, IUploadedFile, IUserBasicInfo, IUserBranchPermission, IUserPermissionProvider, IUserProvider, IUserSelectFilter, LoadUsersFn, PermissionCode, RouterTabItem, ScrollPaginationConfig, TableColumnType, UploadFileFn, UploadMultipleFilesFn };
|