cat-documents-ng 0.2.32 → 0.2.35
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/Shared/components/table-primary/table-primary.component.d.ts +25 -0
- package/Shared/constant/ERROR.d.ts +1 -0
- package/Shared/constant/SHARED.d.ts +96 -5
- package/Shared/constant/URLS.d.ts +22 -0
- package/Shared/shared.module.d.ts +11 -0
- package/fesm2022/cat-documents-ng.mjs +2154 -524
- package/fesm2022/cat-documents-ng.mjs.map +1 -1
- package/lib/document/components/document-container/document-container.component.d.ts +36 -34
- package/lib/document/components/document-list/document-list.component.d.ts +63 -26
- package/lib/document/components/document-status/document-status.component.d.ts +22 -0
- package/lib/document/components/document-viewer/document-viewer.component.d.ts +6 -6
- package/lib/document/components/documents-menu/documents-menu.component.d.ts +40 -3
- package/lib/document/components/folder-container/folder-container.component.d.ts +33 -3
- package/lib/document/components/linked-document/linked-document.component.d.ts +5 -4
- package/lib/document/components/user-list/user-list.component.d.ts +29 -0
- package/lib/document/directives/document.directive.d.ts +2 -2
- package/lib/document/document.module.d.ts +25 -21
- package/lib/document/models/document-category.model.d.ts +19 -0
- package/lib/document/models/document-list-response.model.d.ts +24 -0
- package/lib/document/models/status-data.model.d.ts +27 -0
- package/lib/document/models/user-list.model.d.ts +8 -0
- package/lib/document/services/document-http.service.d.ts +35 -0
- package/lib/document/services/document-menu.service.d.ts +65 -0
- package/lib/document/services/document-table-builder.service.d.ts +56 -0
- package/lib/document/services/document.service.d.ts +83 -6
- package/lib/document/services/status-calculator.service.d.ts +20 -0
- package/lib/document/services/user-list.service.d.ts +36 -0
- package/lib/document/state/document.query.d.ts +94 -0
- package/lib/document/state/document.state.d.ts +13 -0
- package/lib/document/state/document.store.d.ts +15 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/src/assets/config/api.config.json +0 -20
|
@@ -1,46 +1,51 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable,
|
|
2
|
+
import { Injectable, EventEmitter, Output, Input, Component, ViewChild, ViewEncapsulation, Directive, NgModule, APP_INITIALIZER } from '@angular/core';
|
|
3
3
|
import * as i5 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
|
-
import { firstValueFrom, tap, EMPTY, catchError, throwError,
|
|
5
|
+
import { firstValueFrom, tap, EMPTY, catchError, throwError, combineLatest, Subscription } from 'rxjs';
|
|
6
6
|
import { __decorate } from 'tslib';
|
|
7
7
|
import { EntityStore, StoreConfig, QueryEntity } from '@datorama/akita';
|
|
8
8
|
import * as i2 from '@angular/common/http';
|
|
9
|
-
import { HttpClientModule } from '@angular/common/http';
|
|
9
|
+
import { HttpParams, HttpClientModule } from '@angular/common/http';
|
|
10
|
+
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
|
|
11
|
+
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
10
12
|
import * as i3 from 'primeng/api';
|
|
11
13
|
import { MessageService } from 'primeng/api';
|
|
12
|
-
import * as
|
|
13
|
-
import { AccordionModule } from 'primeng/accordion';
|
|
14
|
-
import * as i7 from 'primeng/button';
|
|
14
|
+
import * as i8 from 'primeng/button';
|
|
15
15
|
import { ButtonModule } from 'primeng/button';
|
|
16
|
-
import * as
|
|
16
|
+
import * as i9 from 'primeng/sidebar';
|
|
17
17
|
import { SidebarModule } from 'primeng/sidebar';
|
|
18
|
-
import * as
|
|
19
|
-
import * as
|
|
18
|
+
import * as i10 from 'primeng/messages';
|
|
19
|
+
import * as i11 from '@angular/forms';
|
|
20
20
|
import { FormsModule } from '@angular/forms';
|
|
21
|
-
import * as
|
|
21
|
+
import * as i12 from 'primeng/dialog';
|
|
22
22
|
import { DialogModule } from 'primeng/dialog';
|
|
23
|
-
import * as
|
|
23
|
+
import * as i13 from 'primeng/dropdown';
|
|
24
24
|
import { DropdownModule } from 'primeng/dropdown';
|
|
25
|
-
import * as
|
|
25
|
+
import * as i14 from 'primeng/inputtext';
|
|
26
26
|
import { InputTextModule } from 'primeng/inputtext';
|
|
27
|
-
import * as
|
|
27
|
+
import * as i2$1 from 'primeng/table';
|
|
28
|
+
import { TableModule } from 'primeng/table';
|
|
29
|
+
import * as i5$1 from 'primeng/ripple';
|
|
30
|
+
import { RippleModule } from 'primeng/ripple';
|
|
31
|
+
import * as i7 from 'primeng/fileupload';
|
|
28
32
|
import { FileUploadModule } from 'primeng/fileupload';
|
|
29
|
-
import * as i8 from 'primeng/progressbar';
|
|
33
|
+
import * as i8$1 from 'primeng/progressbar';
|
|
30
34
|
import { ProgressBarModule } from 'primeng/progressbar';
|
|
31
35
|
import * as i4 from 'ng2-pdf-viewer';
|
|
32
36
|
import { PdfViewerModule } from 'ng2-pdf-viewer';
|
|
33
|
-
import * as
|
|
34
|
-
import * as i3$1 from 'primeng/badge';
|
|
37
|
+
import * as i7$1 from 'primeng/badge';
|
|
35
38
|
import { BadgeModule } from 'primeng/badge';
|
|
36
|
-
import * as
|
|
39
|
+
import * as i8$2 from 'primeng/menu';
|
|
37
40
|
import { MenuModule } from 'primeng/menu';
|
|
38
|
-
import * as
|
|
41
|
+
import * as i9$1 from 'primeng/card';
|
|
39
42
|
import { CardModule } from 'primeng/card';
|
|
43
|
+
import { AccordionModule } from 'primeng/accordion';
|
|
40
44
|
import { ListboxModule } from 'primeng/listbox';
|
|
41
45
|
import { TimelineModule } from 'primeng/timeline';
|
|
42
46
|
import { CheckboxModule } from 'primeng/checkbox';
|
|
43
47
|
import { InputTextareaModule } from 'primeng/inputtextarea';
|
|
48
|
+
import * as i1 from '@angular/router';
|
|
44
49
|
import { PanelMenuModule } from 'primeng/panelmenu';
|
|
45
50
|
|
|
46
51
|
/**
|
|
@@ -48,6 +53,34 @@ import { PanelMenuModule } from 'primeng/panelmenu';
|
|
|
48
53
|
* These constants are related to document statuses and other shared data.
|
|
49
54
|
*/
|
|
50
55
|
class SHARED {
|
|
56
|
+
/**
|
|
57
|
+
* Represents the info.
|
|
58
|
+
*/
|
|
59
|
+
static VISIBLE = 'visible';
|
|
60
|
+
/**
|
|
61
|
+
* Represents the info.
|
|
62
|
+
*/
|
|
63
|
+
static HIDDEN = 'hidden';
|
|
64
|
+
/**
|
|
65
|
+
* Represents the info.
|
|
66
|
+
*/
|
|
67
|
+
static APPLICATION_DOCS = 'Application Docs';
|
|
68
|
+
/**
|
|
69
|
+
* Represents the info.
|
|
70
|
+
*/
|
|
71
|
+
static INFO = 'info';
|
|
72
|
+
/**
|
|
73
|
+
* Represents the success.
|
|
74
|
+
*/
|
|
75
|
+
static SUCCESS = 'success';
|
|
76
|
+
/**
|
|
77
|
+
* Represents the warning.
|
|
78
|
+
*/
|
|
79
|
+
static WARNING = 'warning';
|
|
80
|
+
/**
|
|
81
|
+
* Represents the warning.
|
|
82
|
+
*/
|
|
83
|
+
static DANGER = 'danger';
|
|
51
84
|
/**
|
|
52
85
|
* Represents the stores userData.
|
|
53
86
|
*/
|
|
@@ -108,6 +141,24 @@ class SHARED {
|
|
|
108
141
|
* @type {string}
|
|
109
142
|
*/
|
|
110
143
|
static FILE = 'file';
|
|
144
|
+
/**
|
|
145
|
+
* Query parameter for menu item filter.
|
|
146
|
+
* @static
|
|
147
|
+
* @type {string}
|
|
148
|
+
*/
|
|
149
|
+
static MENU_ITEM_PARAM = 'menuItem';
|
|
150
|
+
/**
|
|
151
|
+
* Query parameter for user ID filter.
|
|
152
|
+
* @static
|
|
153
|
+
* @type {string}
|
|
154
|
+
*/
|
|
155
|
+
static USER_ID_PARAM = 'userId';
|
|
156
|
+
/**
|
|
157
|
+
* Query parameter for status filter.
|
|
158
|
+
* @static
|
|
159
|
+
* @type {string}
|
|
160
|
+
*/
|
|
161
|
+
static STATUS_PARAM = 'status';
|
|
111
162
|
/**
|
|
112
163
|
* Represents the array of file size units ('B', 'KB', 'MB') used for file size formatting.
|
|
113
164
|
* @static
|
|
@@ -150,6 +201,12 @@ class SHARED {
|
|
|
150
201
|
* @type {string}
|
|
151
202
|
*/
|
|
152
203
|
static CONTEXT_ID = 'contextId';
|
|
204
|
+
/**
|
|
205
|
+
* Represent contextId.
|
|
206
|
+
* @static
|
|
207
|
+
* @type {string}
|
|
208
|
+
*/
|
|
209
|
+
static CATEGORY = 'category';
|
|
153
210
|
/**
|
|
154
211
|
* Represent fileSize.
|
|
155
212
|
* @static
|
|
@@ -278,6 +335,21 @@ class SHARED {
|
|
|
278
335
|
]
|
|
279
336
|
}
|
|
280
337
|
];
|
|
338
|
+
static APPLICATION = 'Application';
|
|
339
|
+
static APPLICANTS = 'Applicants';
|
|
340
|
+
static EMPTY_SPACE = ' ';
|
|
341
|
+
static COLORS = ['orange', 'blue', 'green', 'grey', 'purple'];
|
|
342
|
+
static COLOR_MAP = {
|
|
343
|
+
'orange': '#f97316',
|
|
344
|
+
'blue': '#3b82f6',
|
|
345
|
+
'green': '#10b981',
|
|
346
|
+
'grey': '#6b7280',
|
|
347
|
+
'purple': '#8b5cf6'
|
|
348
|
+
};
|
|
349
|
+
static DEFAULT_COLOR = '#3b82f6';
|
|
350
|
+
static STATUS_WITH_DASH = 'status-';
|
|
351
|
+
static ICON_WITH_DASH = 'icon-';
|
|
352
|
+
static SEARCH_KEY = 'searchKey';
|
|
281
353
|
}
|
|
282
354
|
/**
|
|
283
355
|
* `DUMMYDOCUMENTLIST` is a mock list of document objects used for testing and development purposes.
|
|
@@ -313,41 +385,62 @@ const DUMMYDOCUMENTLIST = [
|
|
|
313
385
|
* `FOLDERPANEL` is a mock list of folder data representing various folders in the application.
|
|
314
386
|
* Each folder contains an ID, file count, text description, missing files count, and pending files count.
|
|
315
387
|
*/
|
|
316
|
-
const
|
|
388
|
+
const USERLIST = [
|
|
389
|
+
{
|
|
390
|
+
_id: "1",
|
|
391
|
+
username: "John Smith",
|
|
392
|
+
approveDocumentCount: 15,
|
|
393
|
+
pendingDocumentCount: 3
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
_id: "2",
|
|
397
|
+
username: "Sarah Johnson",
|
|
398
|
+
approveDocumentCount: 8,
|
|
399
|
+
pendingDocumentCount: 7
|
|
400
|
+
},
|
|
317
401
|
{
|
|
318
|
-
_id:
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
pendingFiles: 2,
|
|
402
|
+
_id: "3",
|
|
403
|
+
username: "Michael Brown",
|
|
404
|
+
approveDocumentCount: 22,
|
|
405
|
+
pendingDocumentCount: 1
|
|
323
406
|
},
|
|
324
407
|
{
|
|
325
|
-
_id:
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
408
|
+
_id: "4",
|
|
409
|
+
username: "Emily Davis",
|
|
410
|
+
approveDocumentCount: 12,
|
|
411
|
+
pendingDocumentCount: 5
|
|
412
|
+
}
|
|
413
|
+
];
|
|
414
|
+
const SAMPLE_STATUS_DATA = [
|
|
415
|
+
{
|
|
416
|
+
status: "Approved",
|
|
417
|
+
count: 4,
|
|
418
|
+
color: "#10b981",
|
|
419
|
+
icon: "pi pi-check"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
status: "Pending",
|
|
423
|
+
count: 5,
|
|
424
|
+
color: "#6b7280",
|
|
425
|
+
icon: "pi pi-clock"
|
|
330
426
|
},
|
|
331
427
|
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
pendingFiles: 0,
|
|
428
|
+
status: "Reviewing",
|
|
429
|
+
count: 1,
|
|
430
|
+
color: "#f59e0b",
|
|
431
|
+
icon: "pi pi-search"
|
|
337
432
|
},
|
|
338
433
|
{
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
pendingFiles: 0,
|
|
434
|
+
status: "Rejected",
|
|
435
|
+
count: 2,
|
|
436
|
+
color: "#ef4444",
|
|
437
|
+
icon: "pi pi-times"
|
|
344
438
|
},
|
|
345
439
|
{
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
pendingFiles: 3,
|
|
440
|
+
status: "Alert",
|
|
441
|
+
count: 12,
|
|
442
|
+
color: "#dc2626",
|
|
443
|
+
icon: "pi pi-exclamation-circle"
|
|
351
444
|
}
|
|
352
445
|
];
|
|
353
446
|
/**
|
|
@@ -418,43 +511,125 @@ const DocumentAlertList = [
|
|
|
418
511
|
{ status: 'Pending', isAlert: true, alertMessage: 'The name on the payslip does not match either the driver name or the policyholder name.' },
|
|
419
512
|
{ status: 'Verified', isAlert: false, alertMessage: 'Document is verified successfully.' },
|
|
420
513
|
];
|
|
421
|
-
|
|
422
514
|
/**
|
|
423
|
-
*
|
|
424
|
-
*
|
|
515
|
+
* Dummy data for document sections with detailed document lists.
|
|
516
|
+
* Based on the document management interface structure.
|
|
517
|
+
* @type {Array<{header: string, description: string, pendingDocument: number, approvedDocument: number, list: Array<{documentName: string, documentType: string, documentUrl: string, status: string, applicantName: string, uploadedTime: string}>}>}
|
|
425
518
|
*/
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
519
|
+
const DUMMY_DOCUMENT_SECTIONS = [
|
|
520
|
+
{
|
|
521
|
+
header: "Identity",
|
|
522
|
+
description: "Personal identification documents required for verification",
|
|
523
|
+
pendingDocument: 1,
|
|
524
|
+
approvedDocument: 1,
|
|
525
|
+
list: [
|
|
526
|
+
{
|
|
527
|
+
documentName: "passport_emilia_wilson_2025.pdf",
|
|
528
|
+
documentType: "Passport",
|
|
529
|
+
documentUrl: "https://example.com/documents/passport_emilia_wilson_2025.pdf",
|
|
530
|
+
status: "Pending",
|
|
531
|
+
applicantName: "Charlotte Anderson",
|
|
532
|
+
uploadedTime: "28 May 2025"
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
documentName: "driving_license_benjamin_mitchell_2025.jpg",
|
|
536
|
+
documentType: "Driving License",
|
|
537
|
+
documentUrl: "https://example.com/documents/driving_license_benjamin_mitchell_2025.jpg",
|
|
538
|
+
status: "Approved",
|
|
539
|
+
applicantName: "Benjamin Mitchell",
|
|
540
|
+
uploadedTime: "27 May 2025"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
documentName: "british_gas_bill_may_2025.pdf",
|
|
544
|
+
documentType: "Utility Bill",
|
|
545
|
+
documentUrl: "https://example.com/documents/british_gas_bill_may_2025.pdf",
|
|
546
|
+
status: "Alert",
|
|
547
|
+
applicantName: "Sophia Reynolds",
|
|
548
|
+
uploadedTime: "26 May 2025"
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
documentName: "council_tax_oliver_thompson_2025_2026.pdf",
|
|
552
|
+
documentType: "Council Tax Bill",
|
|
553
|
+
documentUrl: "https://example.com/documents/council_tax_oliver_thompson_2025_2026.pdf",
|
|
554
|
+
status: "Uploaded",
|
|
555
|
+
applicantName: "Oliver Thompson",
|
|
556
|
+
uploadedTime: "30 May 2025"
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
documentName: "certified_id_oliver_thompson_2025.pdf",
|
|
560
|
+
documentType: "Certified ID",
|
|
561
|
+
documentUrl: "https://example.com/documents/certified_id_oliver_thompson_2025.pdf",
|
|
562
|
+
status: "Reviewing",
|
|
563
|
+
applicantName: "Oliver Thompson",
|
|
564
|
+
uploadedTime: "02 Jun 2025"
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
documentName: "proof_of_address_oliver_thompson_2025.pdf",
|
|
568
|
+
documentType: "Proof of Address",
|
|
569
|
+
documentUrl: "https://example.com/documents/proof_of_address_oliver_thompson_2025.pdf",
|
|
570
|
+
status: "Rejected",
|
|
571
|
+
applicantName: "Oliver Thompson",
|
|
572
|
+
uploadedTime: "02 Jun 2025"
|
|
573
|
+
}
|
|
574
|
+
]
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
header: "Income",
|
|
578
|
+
description: "Personal Income documents required for verification",
|
|
579
|
+
pendingDocument: 1,
|
|
580
|
+
approvedDocument: 1,
|
|
581
|
+
list: [
|
|
582
|
+
{
|
|
583
|
+
documentName: "passport_emilia_wilson_2025.pdf",
|
|
584
|
+
documentType: "Passport",
|
|
585
|
+
documentUrl: "https://example.com/documents/passport_emilia_wilson_2025.pdf",
|
|
586
|
+
status: "Pending",
|
|
587
|
+
applicantName: "Charlotte Anderson",
|
|
588
|
+
uploadedTime: "28 May 2025"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
documentName: "driving_license_benjamin_mitchell_2025.jpg",
|
|
592
|
+
documentType: "Driving License",
|
|
593
|
+
documentUrl: "https://example.com/documents/driving_license_benjamin_mitchell_2025.jpg",
|
|
594
|
+
status: "Approved",
|
|
595
|
+
applicantName: "Benjamin Mitchell",
|
|
596
|
+
uploadedTime: "27 May 2025"
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
documentName: "british_gas_bill_may_2025.pdf",
|
|
600
|
+
documentType: "Utility Bill",
|
|
601
|
+
documentUrl: "https://example.com/documents/british_gas_bill_may_2025.pdf",
|
|
602
|
+
status: "Alert",
|
|
603
|
+
applicantName: "Sophia Reynolds",
|
|
604
|
+
uploadedTime: "26 May 2025"
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
documentName: "council_tax_oliver_thompson_2025_2026.pdf",
|
|
608
|
+
documentType: "Council Tax Bill",
|
|
609
|
+
documentUrl: "https://example.com/documents/council_tax_oliver_thompson_2025_2026.pdf",
|
|
610
|
+
status: "Uploaded",
|
|
611
|
+
applicantName: "Oliver Thompson",
|
|
612
|
+
uploadedTime: "30 May 2025"
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
documentName: "certified_id_oliver_thompson_2025.pdf",
|
|
616
|
+
documentType: "Certified ID",
|
|
617
|
+
documentUrl: "https://example.com/documents/certified_id_oliver_thompson_2025.pdf",
|
|
618
|
+
status: "Reviewing",
|
|
619
|
+
applicantName: "Oliver Thompson",
|
|
620
|
+
uploadedTime: "02 Jun 2025"
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
documentName: "proof_of_address_oliver_thompson_2025.pdf",
|
|
624
|
+
documentType: "Proof of Address",
|
|
625
|
+
documentUrl: "https://example.com/documents/proof_of_address_oliver_thompson_2025.pdf",
|
|
626
|
+
status: "Rejected",
|
|
627
|
+
applicantName: "Oliver Thompson",
|
|
628
|
+
uploadedTime: "02 Jun 2025"
|
|
629
|
+
}
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
];
|
|
458
633
|
|
|
459
634
|
/**
|
|
460
635
|
* Creates the initial state for the `DocumentState` store.
|
|
@@ -474,7 +649,16 @@ function createInitialState() {
|
|
|
474
649
|
documentAlert: { _id: '' },
|
|
475
650
|
folders: [],
|
|
476
651
|
messages: [],
|
|
477
|
-
documentList: []
|
|
652
|
+
documentList: [],
|
|
653
|
+
documentCategories: [],
|
|
654
|
+
selectedMenuItem: null,
|
|
655
|
+
selectedUserId: null,
|
|
656
|
+
selectedStatus: null,
|
|
657
|
+
showUserList: true,
|
|
658
|
+
currentDocument: null,
|
|
659
|
+
userList: [],
|
|
660
|
+
statusData: [],
|
|
661
|
+
documentListResponse: null
|
|
478
662
|
};
|
|
479
663
|
}
|
|
480
664
|
|
|
@@ -513,13 +697,63 @@ let DocumentStore = class DocumentStore extends EntityStore {
|
|
|
513
697
|
setDocumentList(documents) {
|
|
514
698
|
this.update({ documents: documents });
|
|
515
699
|
}
|
|
516
|
-
|
|
517
|
-
|
|
700
|
+
setDocumentCategories(categories) {
|
|
701
|
+
this.update({ documentCategories: categories });
|
|
702
|
+
}
|
|
703
|
+
// New methods for selection state management
|
|
704
|
+
setSelectedMenuItem(menuItem) {
|
|
705
|
+
this.update({ selectedMenuItem: menuItem });
|
|
706
|
+
}
|
|
707
|
+
setSelectedUserId(userId) {
|
|
708
|
+
this.update({ selectedUserId: userId });
|
|
709
|
+
}
|
|
710
|
+
setSelectedStatus(status) {
|
|
711
|
+
this.update({ selectedStatus: status });
|
|
712
|
+
}
|
|
713
|
+
// Method to update all selection properties at once
|
|
714
|
+
setSelectionState(menuItem, userId, status) {
|
|
715
|
+
this.update({
|
|
716
|
+
selectedMenuItem: menuItem,
|
|
717
|
+
selectedUserId: userId,
|
|
718
|
+
selectedStatus: status
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
// Method to clear all selection state
|
|
722
|
+
clearSelectionState() {
|
|
723
|
+
this.update({
|
|
724
|
+
selectedMenuItem: null,
|
|
725
|
+
selectedUserId: null,
|
|
726
|
+
selectedStatus: null,
|
|
727
|
+
showUserList: true
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
// Method to control user list visibility
|
|
731
|
+
setShowUserList(show) {
|
|
732
|
+
this.update({ showUserList: show });
|
|
733
|
+
}
|
|
734
|
+
// Method to set the current document
|
|
735
|
+
setCurrentDocument(document) {
|
|
736
|
+
this.update({ currentDocument: document });
|
|
737
|
+
}
|
|
738
|
+
// Method to set the user list
|
|
739
|
+
setUserList(userList) {
|
|
740
|
+
this.update({ userList: userList });
|
|
741
|
+
}
|
|
742
|
+
// Method to set the status data
|
|
743
|
+
setStatusData(statusData) {
|
|
744
|
+
this.update({ statusData: statusData });
|
|
745
|
+
}
|
|
746
|
+
// Method to set the document list response
|
|
747
|
+
setDocumentListResponse(response) {
|
|
748
|
+
this.update({ documentListResponse: response });
|
|
749
|
+
}
|
|
750
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
751
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStore, providedIn: 'root' });
|
|
518
752
|
};
|
|
519
753
|
DocumentStore = __decorate([
|
|
520
754
|
StoreConfig({ name: 'documents' })
|
|
521
755
|
], DocumentStore);
|
|
522
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
756
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStore, decorators: [{
|
|
523
757
|
type: Injectable,
|
|
524
758
|
args: [{ providedIn: 'root' }]
|
|
525
759
|
}], ctorParameters: () => [] });
|
|
@@ -545,6 +779,13 @@ class URLS {
|
|
|
545
779
|
* @type {string}
|
|
546
780
|
*/
|
|
547
781
|
static DOCUMENT_UPLOAD = "Documents";
|
|
782
|
+
/**
|
|
783
|
+
* The URL endpoint for document uploads.
|
|
784
|
+
* Used to send documents to the server for storage or processing.
|
|
785
|
+
* @static
|
|
786
|
+
* @type {string}
|
|
787
|
+
*/
|
|
788
|
+
static DOCUMENTS_CATAGORIES = "documents/getAllCategoriesByApplicationId";
|
|
548
789
|
/**
|
|
549
790
|
* The query parameter to pass a context ID in API requests.
|
|
550
791
|
* Used to specify the context for certain API calls, such as filtering or scoping the request.
|
|
@@ -576,6 +817,19 @@ class URLS {
|
|
|
576
817
|
* @type {string}
|
|
577
818
|
*/
|
|
578
819
|
static PARENT_DOCUMENT_TYPE_ID = "parentDocumentType?parentDocumentTypeId=";
|
|
820
|
+
/**
|
|
821
|
+
* The query parameter to pass a document ID in API requests.
|
|
822
|
+
* @static
|
|
823
|
+
* @type {string}
|
|
824
|
+
*/
|
|
825
|
+
static USERLIST = "documents/getContextIdListByApplicationId/";
|
|
826
|
+
/**
|
|
827
|
+
* The URL endpoint for getting document status count by context ID.
|
|
828
|
+
* Used to fetch status data with applicationId, contextId, and category parameters.
|
|
829
|
+
* @static
|
|
830
|
+
* @type {string}
|
|
831
|
+
*/
|
|
832
|
+
static STATUS_DOCUMENT_COUNT = "documents/getStatusDocumentCountByContextId/";
|
|
579
833
|
/**
|
|
580
834
|
* The query parameter to pass a context ID in API requests.
|
|
581
835
|
* Used to specify the context for certain API calls, such as filtering or scoping the request.
|
|
@@ -583,6 +837,8 @@ class URLS {
|
|
|
583
837
|
* @type {string}
|
|
584
838
|
*/
|
|
585
839
|
static CONTEXT_ID = "&contextId=";
|
|
840
|
+
static GETALL = "documents/getAllByContextId";
|
|
841
|
+
static DOCUMENT_LIST = "list";
|
|
586
842
|
}
|
|
587
843
|
|
|
588
844
|
/**
|
|
@@ -646,10 +902,10 @@ class AppConfigService {
|
|
|
646
902
|
get visibilityOptions() {
|
|
647
903
|
return this.appConfig?.visibilityOption;
|
|
648
904
|
}
|
|
649
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
650
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
905
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AppConfigService, deps: [{ token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
906
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AppConfigService, providedIn: 'root' });
|
|
651
907
|
}
|
|
652
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
908
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AppConfigService, decorators: [{
|
|
653
909
|
type: Injectable,
|
|
654
910
|
args: [{
|
|
655
911
|
providedIn: 'root'
|
|
@@ -664,7 +920,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
664
920
|
* @param {DocumentStore} documentStore - The store that manages the state of documents.
|
|
665
921
|
* @param {HttpClient} http - The Angular HTTP client for making API requests.
|
|
666
922
|
*/
|
|
667
|
-
|
|
923
|
+
class DocumentService {
|
|
668
924
|
documentStore;
|
|
669
925
|
http;
|
|
670
926
|
appConfigService;
|
|
@@ -727,10 +983,10 @@ let DocumentService$1 = class DocumentService {
|
|
|
727
983
|
delete(id) {
|
|
728
984
|
return this.http.delete(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD}/${id}`).pipe(tap(() => this.documentStore.remove(id)));
|
|
729
985
|
}
|
|
730
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
731
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
732
|
-
}
|
|
733
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
986
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentService, deps: [{ token: DocumentStore }, { token: i2.HttpClient }, { token: AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
987
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentService, providedIn: 'root' });
|
|
988
|
+
}
|
|
989
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentService, decorators: [{
|
|
734
990
|
type: Injectable,
|
|
735
991
|
args: [{ providedIn: 'root' }]
|
|
736
992
|
}], ctorParameters: () => [{ type: DocumentStore }, { type: i2.HttpClient }, { type: AppConfigService }] });
|
|
@@ -776,10 +1032,134 @@ class DocumentQuery extends QueryEntity {
|
|
|
776
1032
|
selectDocumets() {
|
|
777
1033
|
return this.select((state) => state.documentList);
|
|
778
1034
|
}
|
|
779
|
-
|
|
780
|
-
|
|
1035
|
+
/**
|
|
1036
|
+
* Selects the document categories.
|
|
1037
|
+
* @returns {Observable<DocumentCategory[]>} Observable that emits the document categories.
|
|
1038
|
+
*/
|
|
1039
|
+
selectDocumentCategories() {
|
|
1040
|
+
return this.select((state) => state.documentCategories);
|
|
1041
|
+
}
|
|
1042
|
+
// New query methods for selection state
|
|
1043
|
+
/**
|
|
1044
|
+
* Selects the currently selected menu item.
|
|
1045
|
+
* @returns {Observable<string | null>} Observable that emits the currently selected menu item _id (not the label).
|
|
1046
|
+
*/
|
|
1047
|
+
selectSelectedMenuItem() {
|
|
1048
|
+
return this.select((state) => state.selectedMenuItem);
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Selects the currently selected user ID.
|
|
1052
|
+
* @returns {Observable<string | null>} Observable that emits the currently selected user ID.
|
|
1053
|
+
*/
|
|
1054
|
+
selectSelectedUserId() {
|
|
1055
|
+
return this.select((state) => state.selectedUserId);
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* Selects the currently selected status.
|
|
1059
|
+
* @returns {Observable<string | null>} Observable that emits the currently selected status.
|
|
1060
|
+
*/
|
|
1061
|
+
selectSelectedStatus() {
|
|
1062
|
+
return this.select((state) => state.selectedStatus);
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Selects all selection state properties (menu item, user ID, status).
|
|
1066
|
+
* @returns {Observable<{menuItem: string | null, userId: string | null, status: string | null}>} Observable that emits the current selection state.
|
|
1067
|
+
* Note: menuItem is the _id of the selected menu item, not the label.
|
|
1068
|
+
*/
|
|
1069
|
+
selectSelectionState() {
|
|
1070
|
+
return this.select((state) => ({
|
|
1071
|
+
menuItem: state.selectedMenuItem,
|
|
1072
|
+
userId: state.selectedUserId,
|
|
1073
|
+
status: state.selectedStatus
|
|
1074
|
+
}));
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Gets the current selection state values (synchronous).
|
|
1078
|
+
* @returns {Object} The current selection state values.
|
|
1079
|
+
* Note: menuItem is the _id of the selected menu item, not the label.
|
|
1080
|
+
*/
|
|
1081
|
+
getSelectionState() {
|
|
1082
|
+
const state = this.getValue();
|
|
1083
|
+
return {
|
|
1084
|
+
menuItem: state.selectedMenuItem,
|
|
1085
|
+
userId: state.selectedUserId,
|
|
1086
|
+
status: state.selectedStatus
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Selects the user list visibility state.
|
|
1091
|
+
* @returns {Observable<boolean>} Observable that emits the current user list visibility.
|
|
1092
|
+
*/
|
|
1093
|
+
selectShowUserList() {
|
|
1094
|
+
return this.select((state) => state.showUserList);
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Gets the current user list visibility value (synchronous).
|
|
1098
|
+
* @returns {boolean} The current user list visibility.
|
|
1099
|
+
*/
|
|
1100
|
+
getShowUserList() {
|
|
1101
|
+
return this.getValue().showUserList;
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Selects the current document.
|
|
1105
|
+
* @returns {Observable<DocumentModel | null>} Observable that emits the current document.
|
|
1106
|
+
*/
|
|
1107
|
+
selectCurrentDocument() {
|
|
1108
|
+
return this.select((state) => state.currentDocument);
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Gets the current document value (synchronous).
|
|
1112
|
+
* @returns {DocumentModel | null} The current document.
|
|
1113
|
+
*/
|
|
1114
|
+
getCurrentDocument() {
|
|
1115
|
+
return this.getValue().currentDocument;
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Selects the user list.
|
|
1119
|
+
* @returns {Observable<UserListModel[]>} Observable that emits the user list.
|
|
1120
|
+
*/
|
|
1121
|
+
selectUserList() {
|
|
1122
|
+
return this.select((state) => state.userList);
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Gets the current user list value (synchronous).
|
|
1126
|
+
* @returns {UserListModel[]} The current user list.
|
|
1127
|
+
*/
|
|
1128
|
+
getUserList() {
|
|
1129
|
+
return this.getValue().userList;
|
|
1130
|
+
}
|
|
1131
|
+
/**
|
|
1132
|
+
* Selects the status data.
|
|
1133
|
+
* @returns {Observable<StatusDataModel[]>} Observable that emits the status data.
|
|
1134
|
+
*/
|
|
1135
|
+
selectStatusData() {
|
|
1136
|
+
return this.select((state) => state.statusData);
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Gets the current status data value (synchronous).
|
|
1140
|
+
* @returns {StatusDataModel[]} The current status data.
|
|
1141
|
+
*/
|
|
1142
|
+
getStatusData() {
|
|
1143
|
+
return this.getValue().statusData;
|
|
1144
|
+
}
|
|
1145
|
+
/**
|
|
1146
|
+
* Selects the document list response.
|
|
1147
|
+
* @returns {Observable<DocumentListResponse[] | null>} Observable that emits the document list response.
|
|
1148
|
+
*/
|
|
1149
|
+
selectDocumentListResponse() {
|
|
1150
|
+
return this.select((state) => state.documentListResponse);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Gets the current document list response value (synchronous).
|
|
1154
|
+
* @returns {DocumentListResponse[] | null} The current document list response.
|
|
1155
|
+
*/
|
|
1156
|
+
getDocumentListResponse() {
|
|
1157
|
+
return this.getValue().documentListResponse;
|
|
1158
|
+
}
|
|
1159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentQuery, deps: [{ token: DocumentStore }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1160
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentQuery, providedIn: 'root' });
|
|
781
1161
|
}
|
|
782
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentQuery, decorators: [{
|
|
783
1163
|
type: Injectable,
|
|
784
1164
|
args: [{ providedIn: 'root' }]
|
|
785
1165
|
}], ctorParameters: () => [{ type: DocumentStore }] });
|
|
@@ -827,6 +1207,21 @@ class DocumentHttpService {
|
|
|
827
1207
|
return throwError(() => new Error(error));
|
|
828
1208
|
}));
|
|
829
1209
|
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Fetches a document catagories by its path name.
|
|
1212
|
+
* Includes error handling for failed API requests.
|
|
1213
|
+
* @param {string} contextId - The context ID to fetch the document.
|
|
1214
|
+
* @returns {Observable<any>} Observable that emits the transformed data for dropdown options.
|
|
1215
|
+
*/
|
|
1216
|
+
getDocumentCatagories(contextId) {
|
|
1217
|
+
if (!contextId)
|
|
1218
|
+
return EMPTY;
|
|
1219
|
+
return this.http.get(`${this.apiUrl}${URLS.DOCUMENTS_CATAGORIES}/${contextId}`).pipe(tap((categories) => {
|
|
1220
|
+
this.documentStore.setDocumentCategories(categories);
|
|
1221
|
+
}), catchError((error) => {
|
|
1222
|
+
return throwError(() => new Error(error));
|
|
1223
|
+
}));
|
|
1224
|
+
}
|
|
830
1225
|
/**
|
|
831
1226
|
* Fetches a document by its path name and transforms the response for dropdown options.
|
|
832
1227
|
* Includes error handling for failed API requests.
|
|
@@ -877,10 +1272,79 @@ class DocumentHttpService {
|
|
|
877
1272
|
return throwError(() => new Error(error));
|
|
878
1273
|
}));
|
|
879
1274
|
}
|
|
880
|
-
|
|
881
|
-
|
|
1275
|
+
/**
|
|
1276
|
+
* Fetches a userlist by its path name.
|
|
1277
|
+
* @param {string} contextId - The document ID to fetch the document.
|
|
1278
|
+
* @returns {Observable<UserListModel[]>} Observable that emits the user list data.
|
|
1279
|
+
*/
|
|
1280
|
+
getUserListByContextId(contextId) {
|
|
1281
|
+
if (!contextId)
|
|
1282
|
+
return EMPTY;
|
|
1283
|
+
return this.http.get(`${this.apiUrl}${URLS.USERLIST}${contextId}`).pipe(tap((userList) => {
|
|
1284
|
+
this.documentStore.setUserList(userList);
|
|
1285
|
+
}), catchError((error) => {
|
|
1286
|
+
return throwError(() => new Error(error));
|
|
1287
|
+
}));
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Fetches document status count data by application ID with optional context ID and category parameters.
|
|
1291
|
+
* @param {string} applicationId - The application ID to fetch status data.
|
|
1292
|
+
* @param {string | null} contextId - The context ID (applicant ID) to filter by. If null, uses applicationId.
|
|
1293
|
+
* @param {string | null} categoryId - The category ID to filter by.
|
|
1294
|
+
* @returns {Observable<StatusDataModel[]>} Observable that emits the status data.
|
|
1295
|
+
*/
|
|
1296
|
+
getStatusDocumentCount(applicationId, contextId = null, categoryId = null) {
|
|
1297
|
+
if (!applicationId)
|
|
1298
|
+
return EMPTY;
|
|
1299
|
+
let url = `${this.apiUrl}${URLS.STATUS_DOCUMENT_COUNT}${applicationId}`;
|
|
1300
|
+
let params = new HttpParams();
|
|
1301
|
+
const contextParam = contextId || applicationId;
|
|
1302
|
+
params = params.set(SHARED.CONTEXT_ID, contextParam);
|
|
1303
|
+
if (categoryId) {
|
|
1304
|
+
params = params.set(SHARED.CATEGORY, categoryId);
|
|
1305
|
+
}
|
|
1306
|
+
return this.http.get(url, { params }).pipe(tap((statusData) => {
|
|
1307
|
+
this.documentStore.setStatusData(statusData);
|
|
1308
|
+
}), catchError((error) => {
|
|
1309
|
+
return throwError(() => new Error(error));
|
|
1310
|
+
}));
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Fetches documents based on selection criteria (menu item, user ID, status, and search key).
|
|
1314
|
+
* This method sends an HTTP GET request with query parameters for the selected filters.
|
|
1315
|
+
* @param {string} contextId - The context ID (applicationId or applicantId).
|
|
1316
|
+
* @param {string | null} menuItem - The selected menu item filter.
|
|
1317
|
+
* @param {string | null} userId - The selected user ID filter.
|
|
1318
|
+
* @param {string | null} status - The selected status filter.
|
|
1319
|
+
* @param {string | null} searchKey - The search key filter.
|
|
1320
|
+
* @returns {Observable<any>} An observable that emits the filtered document data.
|
|
1321
|
+
*/
|
|
1322
|
+
getDocumentsBySelection(contextId, menuItem, userId, status, searchKey = null) {
|
|
1323
|
+
let params = new HttpParams();
|
|
1324
|
+
if (menuItem) {
|
|
1325
|
+
params = params.set(SHARED.CATEGORY, menuItem);
|
|
1326
|
+
}
|
|
1327
|
+
if (userId) {
|
|
1328
|
+
params = params.set(SHARED.CONTEXT_ID, userId);
|
|
1329
|
+
}
|
|
1330
|
+
if (status) {
|
|
1331
|
+
params = params.set(SHARED.STATUS_PARAM, status);
|
|
1332
|
+
}
|
|
1333
|
+
if (searchKey) {
|
|
1334
|
+
params = params.set(SHARED.SEARCH_KEY, searchKey);
|
|
1335
|
+
}
|
|
1336
|
+
return this.http.get(`${this.apiUrl}${URLS.GETALL}/${contextId}`, { params }).pipe(tap((response) => {
|
|
1337
|
+
if (response.documents) {
|
|
1338
|
+
this.documentStore.setDocumentList(response.documents);
|
|
1339
|
+
}
|
|
1340
|
+
}), catchError((error) => {
|
|
1341
|
+
return throwError(() => new Error(error));
|
|
1342
|
+
}));
|
|
1343
|
+
}
|
|
1344
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHttpService, deps: [{ token: DocumentStore }, { token: i2.HttpClient }, { token: AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1345
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHttpService, providedIn: 'root' });
|
|
882
1346
|
}
|
|
883
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1347
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHttpService, decorators: [{
|
|
884
1348
|
type: Injectable,
|
|
885
1349
|
args: [{
|
|
886
1350
|
providedIn: 'root'
|
|
@@ -888,62 +1352,520 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
888
1352
|
}], ctorParameters: () => [{ type: DocumentStore }, { type: i2.HttpClient }, { type: AppConfigService }] });
|
|
889
1353
|
|
|
890
1354
|
/**
|
|
891
|
-
*
|
|
892
|
-
* providing filtering functionality based on folder IDs.
|
|
893
|
-
*
|
|
894
|
-
* It uses data from the `DocumentStore` and constants from the `SHARED` configuration
|
|
895
|
-
* to display missing and pending file counts.
|
|
1355
|
+
* Service to manage the document data and selection state
|
|
896
1356
|
*/
|
|
897
|
-
class
|
|
1357
|
+
class DocumentHelperService {
|
|
898
1358
|
documentStore;
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
*/
|
|
903
|
-
folderList = SHARED.EMPTY_ARRAY;
|
|
904
|
-
/** Number of missing files, sourced from the `SHARED` constants. */
|
|
905
|
-
missingFileCount = SHARED.MISSINGCOUNT;
|
|
906
|
-
/** Number of pending files, sourced from the `SHARED` constants. */
|
|
907
|
-
pendingFileCount = SHARED.PENDINGCOUNT;
|
|
908
|
-
/**
|
|
909
|
-
* Injects the `DocumentStore` service to manage and access document-related state.
|
|
910
|
-
* @param {DocumentStore} documentStore - The state management store for documents.
|
|
911
|
-
*/
|
|
912
|
-
constructor(documentStore) {
|
|
1359
|
+
documentQuery;
|
|
1360
|
+
documentHttpService;
|
|
1361
|
+
constructor(documentStore, documentQuery, documentHttpService) {
|
|
913
1362
|
this.documentStore = documentStore;
|
|
1363
|
+
this.documentQuery = documentQuery;
|
|
1364
|
+
this.documentHttpService = documentHttpService;
|
|
1365
|
+
// Note: initializeSelectionWatcher now requires contextId
|
|
1366
|
+
// This should be called from the component that has access to contextId
|
|
914
1367
|
}
|
|
915
1368
|
/**
|
|
916
|
-
*
|
|
917
|
-
*
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1369
|
+
* Initialize watcher for selection state changes
|
|
1370
|
+
* @param contextId - The context ID to use for API calls
|
|
1371
|
+
*/
|
|
1372
|
+
initializeSelectionWatcher(contextId) {
|
|
1373
|
+
combineLatest([
|
|
1374
|
+
this.documentQuery.selectSelectedMenuItem(),
|
|
1375
|
+
this.documentQuery.selectSelectedUserId(),
|
|
1376
|
+
this.documentQuery.selectSelectedStatus()
|
|
1377
|
+
]).pipe(debounceTime(300), distinctUntilChanged((prev, curr) => {
|
|
1378
|
+
const isSame = prev[0] === curr[0] && prev[1] === curr[1] && prev[2] === curr[2];
|
|
1379
|
+
console.log('Selection state changed:', { prev, curr, isSame });
|
|
1380
|
+
return isSame;
|
|
1381
|
+
}), switchMap(([menuItem, userId, status]) => {
|
|
1382
|
+
// Always call the API, even when filters are cleared
|
|
1383
|
+
return this.documentHttpService.getDocumentsBySelection(contextId, menuItem, userId, status);
|
|
1384
|
+
})).subscribe({
|
|
1385
|
+
next: (response) => {
|
|
1386
|
+
const currentState = this.documentQuery.getSelectionState();
|
|
1387
|
+
console.log('API called with filters:', {
|
|
1388
|
+
menuItem: currentState.menuItem,
|
|
1389
|
+
userId: currentState.userId,
|
|
1390
|
+
status: currentState.status
|
|
1391
|
+
});
|
|
1392
|
+
console.log('API response:', response);
|
|
1393
|
+
this.documentStore.setDocumentListResponse(response);
|
|
1394
|
+
},
|
|
1395
|
+
error: (error) => {
|
|
1396
|
+
console.error('Error calling API with selection:', error);
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Initialize watcher for selection state changes with initial load
|
|
1402
|
+
* @param contextId - The context ID to use for API calls
|
|
1403
|
+
*/
|
|
1404
|
+
initializeSelectionWatcherWithInitialLoad(contextId) {
|
|
1405
|
+
// First, load initial data without filters
|
|
1406
|
+
this.documentHttpService.getDocumentsBySelection(contextId, null, null, null).subscribe({
|
|
1407
|
+
next: (response) => {
|
|
1408
|
+
console.log('Initial API call:', response);
|
|
1409
|
+
this.documentStore.setDocumentListResponse(response);
|
|
1410
|
+
},
|
|
1411
|
+
error: (error) => {
|
|
1412
|
+
console.error('Error calling initial API:', error);
|
|
1413
|
+
}
|
|
1414
|
+
});
|
|
1415
|
+
// Then set up the watcher for filter changes
|
|
1416
|
+
this.initializeSelectionWatcher(contextId);
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Set the document data
|
|
1420
|
+
* @param document the document data
|
|
1421
|
+
*/
|
|
1422
|
+
set(document) {
|
|
1423
|
+
this.documentStore.setCurrentDocument(document);
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Get the document data
|
|
1427
|
+
* @returns the document data
|
|
1428
|
+
*/
|
|
1429
|
+
get() {
|
|
1430
|
+
return this.documentQuery.selectCurrentDocument();
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Get the current document value synchronously
|
|
1434
|
+
* @returns the current document value
|
|
1435
|
+
*/
|
|
1436
|
+
getValue() {
|
|
1437
|
+
return this.documentQuery.getCurrentDocument();
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Set the selected menu item
|
|
1441
|
+
* @param menuItem the selected menu item _id (not the label)
|
|
1442
|
+
*/
|
|
1443
|
+
setSelectedMenuItem(menuItem) {
|
|
1444
|
+
this.documentStore.setSelectedMenuItem(menuItem);
|
|
1445
|
+
}
|
|
1446
|
+
/**
|
|
1447
|
+
* Set the selected user ID
|
|
1448
|
+
* @param userId the selected user ID
|
|
1449
|
+
*/
|
|
1450
|
+
setSelectedUserId(userId) {
|
|
1451
|
+
this.documentStore.setSelectedUserId(userId);
|
|
1452
|
+
}
|
|
1453
|
+
/**
|
|
1454
|
+
* Set the selected status
|
|
1455
|
+
* @param status the selected status
|
|
1456
|
+
*/
|
|
1457
|
+
setSelectedStatus(status) {
|
|
1458
|
+
this.documentStore.setSelectedStatus(status);
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Set all selection state at once
|
|
1462
|
+
* @param menuItem the selected menu item _id (not the label)
|
|
1463
|
+
* @param userId the selected user ID
|
|
1464
|
+
* @param status the selected status
|
|
1465
|
+
*/
|
|
1466
|
+
setSelectionState(menuItem, userId, status) {
|
|
1467
|
+
this.documentStore.setSelectionState(menuItem, userId, status);
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Clear all selection state
|
|
1471
|
+
*/
|
|
1472
|
+
clearSelectionState() {
|
|
1473
|
+
this.documentStore.clearSelectionState();
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* Set user list visibility
|
|
1477
|
+
* @param show whether to show the user list
|
|
1478
|
+
*/
|
|
1479
|
+
setShowUserList(show) {
|
|
1480
|
+
this.documentStore.setShowUserList(show);
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Get the current selection state
|
|
1484
|
+
* @returns observable of the current selection state
|
|
1485
|
+
*/
|
|
1486
|
+
getSelectionState() {
|
|
1487
|
+
return this.documentQuery.selectSelectionState();
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Get observable for filtered documents
|
|
1491
|
+
* @returns Observable that emits filtered document responses
|
|
1492
|
+
*/
|
|
1493
|
+
getFilteredDocuments() {
|
|
1494
|
+
return this.documentQuery.selectDocumentListResponse();
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Manually trigger API call with current selection state
|
|
1498
|
+
* @param contextId - The context ID to use for the API call
|
|
1499
|
+
*/
|
|
1500
|
+
refreshDocumentsWithCurrentSelection(contextId) {
|
|
1501
|
+
const currentState = this.documentQuery.getSelectionState();
|
|
1502
|
+
console.log('Manual API refresh with state:', currentState);
|
|
1503
|
+
this.documentHttpService.getDocumentsBySelection(contextId, currentState.menuItem, currentState.userId, currentState.status).subscribe({
|
|
1504
|
+
next: (response) => {
|
|
1505
|
+
console.log('Manual API refresh response:', response);
|
|
1506
|
+
this.documentStore.setDocumentListResponse(response);
|
|
1507
|
+
},
|
|
1508
|
+
error: (error) => {
|
|
1509
|
+
throw new Error(error);
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Force refresh documents with no filters
|
|
1515
|
+
* @param contextId - The context ID to use for the API call
|
|
1516
|
+
*/
|
|
1517
|
+
refreshDocumentsWithoutFilters(contextId) {
|
|
1518
|
+
console.log('Force refreshing documents without filters');
|
|
1519
|
+
this.documentHttpService.getDocumentsBySelection(contextId, null, null, null).subscribe({
|
|
1520
|
+
next: (response) => {
|
|
1521
|
+
console.log('Force refresh response:', response);
|
|
1522
|
+
this.documentStore.setDocumentListResponse(response);
|
|
1523
|
+
},
|
|
1524
|
+
error: (error) => {
|
|
1525
|
+
console.error('Error in force refresh:', error);
|
|
1526
|
+
}
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1529
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHelperService, deps: [{ token: DocumentStore }, { token: DocumentQuery }, { token: DocumentHttpService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1530
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHelperService, providedIn: 'root' });
|
|
1531
|
+
}
|
|
1532
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHelperService, decorators: [{
|
|
1533
|
+
type: Injectable,
|
|
1534
|
+
args: [{
|
|
1535
|
+
providedIn: 'root',
|
|
1536
|
+
}]
|
|
1537
|
+
}], ctorParameters: () => [{ type: DocumentStore }, { type: DocumentQuery }, { type: DocumentHttpService }] });
|
|
1538
|
+
|
|
1539
|
+
class UserListService {
|
|
1540
|
+
documentStore;
|
|
1541
|
+
documentQuery;
|
|
1542
|
+
constructor(documentStore, documentQuery) {
|
|
1543
|
+
this.documentStore = documentStore;
|
|
1544
|
+
this.documentQuery = documentQuery;
|
|
1545
|
+
}
|
|
1546
|
+
getInitials(name) {
|
|
1547
|
+
return name.split(SHARED.EMPTY_SPACE).map(name => name.charAt(0)).join(SHARED.EMPTY).toUpperCase();
|
|
1548
|
+
}
|
|
1549
|
+
getColorByIndex(index) {
|
|
1550
|
+
const colors = SHARED.COLORS;
|
|
1551
|
+
return colors[index % colors.length];
|
|
1552
|
+
}
|
|
1553
|
+
getColorValue(colorName) {
|
|
1554
|
+
const colorMap = SHARED.COLOR_MAP;
|
|
1555
|
+
return colorMap[colorName] || SHARED.DEFAULT_COLOR;
|
|
1556
|
+
}
|
|
1557
|
+
processUserData(userList) {
|
|
1558
|
+
return userList.map((user, index) => ({
|
|
1559
|
+
...user,
|
|
1560
|
+
initials: this.getInitials(user.name),
|
|
1561
|
+
color: this.getColorByIndex(index)
|
|
1562
|
+
}));
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Finds the selected menu item from categories
|
|
1566
|
+
* @param selectedMenuItemId - The ID of the selected menu item
|
|
1567
|
+
* @param categories - The document categories
|
|
1568
|
+
* @returns The selected menu item or null
|
|
1569
|
+
*/
|
|
1570
|
+
findSelectedMenuItem(selectedMenuItemId, categories) {
|
|
1571
|
+
for (const category of categories) {
|
|
1572
|
+
if (category.items) {
|
|
1573
|
+
const item = category.items.find(item => item._id === selectedMenuItemId);
|
|
1574
|
+
if (item) {
|
|
1575
|
+
return item;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
return null;
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Filters user list based on selected menu item category
|
|
1583
|
+
* @param userList - The complete user list
|
|
1584
|
+
* @param categories - The document categories
|
|
1585
|
+
* @returns Filtered user list
|
|
1586
|
+
*/
|
|
1587
|
+
filterUsersByCategory(userList, categories) {
|
|
1588
|
+
const selectedMenuItemId = this.documentQuery.getSelectionState().menuItem;
|
|
1589
|
+
if (!selectedMenuItemId) {
|
|
1590
|
+
return userList;
|
|
1591
|
+
}
|
|
1592
|
+
const selectedMenuItem = this.findSelectedMenuItem(selectedMenuItemId, categories);
|
|
1593
|
+
if (!selectedMenuItem) {
|
|
1594
|
+
return userList;
|
|
1595
|
+
}
|
|
1596
|
+
const selectedCategory = categories.find(category => category.items?.some(item => item._id === selectedMenuItemId));
|
|
1597
|
+
if (!selectedCategory) {
|
|
1598
|
+
return userList;
|
|
1599
|
+
}
|
|
1600
|
+
if (selectedCategory.label === SHARED.APPLICATION) {
|
|
1601
|
+
return userList.filter(user => user.name === SHARED.APPLICATION_DOCS);
|
|
1602
|
+
}
|
|
1603
|
+
return userList;
|
|
1604
|
+
}
|
|
1605
|
+
selectUser(userId, userData) {
|
|
1606
|
+
const user = userData.find(u => u._id === userId);
|
|
1607
|
+
if (user) {
|
|
1608
|
+
this.documentStore.setSelectedUserId(userId);
|
|
1609
|
+
return { selectedUser: user.name, name: user.name };
|
|
1610
|
+
}
|
|
1611
|
+
return { selectedUser: undefined, name: undefined };
|
|
1612
|
+
}
|
|
1613
|
+
unselectUser() {
|
|
1614
|
+
this.documentStore.setSelectedUserId(null);
|
|
1615
|
+
}
|
|
1616
|
+
isUserSelected(userId, userData, selectedUser) {
|
|
1617
|
+
return selectedUser === userData.find(u => u._id === userId)?.name;
|
|
1618
|
+
}
|
|
1619
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserListService, deps: [{ token: DocumentStore }, { token: DocumentQuery }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1620
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserListService, providedIn: 'root' });
|
|
1621
|
+
}
|
|
1622
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserListService, decorators: [{
|
|
1623
|
+
type: Injectable,
|
|
1624
|
+
args: [{
|
|
1625
|
+
providedIn: 'root'
|
|
1626
|
+
}]
|
|
1627
|
+
}], ctorParameters: () => [{ type: DocumentStore }, { type: DocumentQuery }] });
|
|
1628
|
+
|
|
1629
|
+
class UserListComponent {
|
|
1630
|
+
documentService;
|
|
1631
|
+
documentStore;
|
|
1632
|
+
documentQuery;
|
|
1633
|
+
userListService;
|
|
1634
|
+
userList = SHARED.EMPTY_ARRAY;
|
|
1635
|
+
categories = SHARED.EMPTY_ARRAY;
|
|
1636
|
+
userSelected = new EventEmitter();
|
|
1637
|
+
userData = SHARED.EMPTY_ARRAY;
|
|
1638
|
+
filteredUserData = SHARED.EMPTY_ARRAY;
|
|
1639
|
+
selectedUser;
|
|
1640
|
+
shouldShowContainer = true;
|
|
1641
|
+
constructor(documentService, documentStore, documentQuery, userListService) {
|
|
1642
|
+
this.documentService = documentService;
|
|
1643
|
+
this.documentStore = documentStore;
|
|
1644
|
+
this.documentQuery = documentQuery;
|
|
1645
|
+
this.userListService = userListService;
|
|
1646
|
+
}
|
|
1647
|
+
ngOnChanges(changes) {
|
|
1648
|
+
if (changes['userList'] && !changes['userList'].firstChange) {
|
|
1649
|
+
this.initializeUserData();
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
initializeUserData() {
|
|
1653
|
+
if (this.userList && this.userList.length > 0) {
|
|
1654
|
+
this.userData = this.userListService.processUserData(this.userList);
|
|
1655
|
+
this.updateFilteredUserData();
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
updateFilteredUserData() {
|
|
1659
|
+
if (this.userData.length > 0 && this.categories.length > 0) {
|
|
1660
|
+
this.filteredUserData = this.userListService.filterUsersByCategory(this.userData, this.categories);
|
|
1661
|
+
this.shouldShowContainer = true;
|
|
1662
|
+
if (this.selectedUser) {
|
|
1663
|
+
const selectedUserInFiltered = this.filteredUserData.find(user => user.name === this.selectedUser);
|
|
1664
|
+
if (!selectedUserInFiltered) {
|
|
1665
|
+
this.selectedUser = undefined;
|
|
1666
|
+
this.documentStore.setSelectedUserId(null);
|
|
1667
|
+
this.userSelected.emit(SHARED.EMPTY);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
else {
|
|
1672
|
+
this.filteredUserData = this.userData;
|
|
1673
|
+
this.shouldShowContainer = true;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
ngOnInit() {
|
|
1677
|
+
this.initializeUserData();
|
|
1678
|
+
this.documentQuery.selectSelectedUserId().subscribe(userId => {
|
|
1679
|
+
if (userId) {
|
|
1680
|
+
const user = this.userData.find(u => u._id === userId);
|
|
1681
|
+
this.selectedUser = user ? user.name : undefined;
|
|
1682
|
+
}
|
|
1683
|
+
else {
|
|
1684
|
+
this.selectedUser = undefined;
|
|
1685
|
+
}
|
|
1686
|
+
});
|
|
1687
|
+
this.documentQuery.selectSelectedMenuItem().subscribe(menuItemId => {
|
|
1688
|
+
this.updateFilteredUserData();
|
|
1689
|
+
if (this.selectedUser) {
|
|
1690
|
+
const selectedUserInFiltered = this.filteredUserData.find(user => user.name === this.selectedUser);
|
|
1691
|
+
if (!selectedUserInFiltered) {
|
|
1692
|
+
this.selectedUser = undefined;
|
|
1693
|
+
this.documentStore.setSelectedUserId(null);
|
|
1694
|
+
this.userSelected.emit(SHARED.EMPTY);
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
});
|
|
1698
|
+
this.documentQuery.selectShowUserList().subscribe(show => {
|
|
1699
|
+
if (!show && this.selectedUser) {
|
|
1700
|
+
this.selectedUser = undefined;
|
|
1701
|
+
this.userSelected.emit(SHARED.EMPTY);
|
|
1702
|
+
}
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
onUserSelect(username, id) {
|
|
1706
|
+
if (this.selectedUser === username) {
|
|
1707
|
+
this.selectedUser = undefined;
|
|
1708
|
+
this.userListService.unselectUser();
|
|
1709
|
+
this.userSelected.emit(SHARED.EMPTY);
|
|
1710
|
+
}
|
|
1711
|
+
else {
|
|
1712
|
+
this.selectedUser = username;
|
|
1713
|
+
this.documentStore.setSelectedUserId(id);
|
|
1714
|
+
this.userSelected.emit(username);
|
|
925
1715
|
}
|
|
926
|
-
this.documentStore.setParentDocumentTypeId(folderBlockId);
|
|
927
|
-
return folderBlockId;
|
|
928
1716
|
}
|
|
929
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
930
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
1717
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserListComponent, deps: [{ token: DocumentHelperService }, { token: DocumentStore }, { token: DocumentQuery }, { token: UserListService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1718
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UserListComponent, isStandalone: false, selector: "lib-user-list", inputs: { userList: "userList", categories: "categories" }, outputs: { userSelected: "userSelected" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"user-list-container\" [@slideInFromTop]>\r\n <div class=\"user-cards\">\r\n <div \r\n *ngFor=\"let user of filteredUserData\" \r\n class=\"user-card\"\r\n [class.selected]=\"selectedUser === user.name\"\r\n [style.border-color]=\"selectedUser === user.name ? '#f97316' : 'transparent'\"\r\n (click)=\"onUserSelect(user.name, user._id)\"\r\n >\r\n <div class=\"user-avatar\" [ngClass]=\"'avatar-' + user.color\">\r\n <span class=\"initials\">{{ user.initials }}</span>\r\n </div>\r\n <div class=\"user-info\">\r\n <div class=\"username\">{{ user.name }}</div>\r\n <div class=\"document-counts\">\r\n {{ user.approved }} approved / {{ user.pending }} pending\r\n </div>\r\n </div>\r\n <div class=\"selection-indicator\" *ngIf=\"selectedUser === user.name\" [@fadeIn]>\r\n <i class=\"ri-check-line\"></i>\r\n </div>\r\n </div>\r\n \r\n <div *ngIf=\"filteredUserData.length === 0 && shouldShowContainer\" class=\"no-users-message\" [@slideInFromTop]>\r\n <p>No users available for this category.</p>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".user-list-container{padding:1rem}.user-cards{display:flex;flex-wrap:wrap;gap:1rem;transition:all .3s ease-in-out}.user-card{display:flex;align-items:center;gap:.75rem;padding:1rem;border:2px solid transparent;border-radius:8px;cursor:pointer;transition:all .2s ease;background:#fff;box-shadow:0 2px 4px #0000001a;min-width:330px;position:relative}.user-card:hover{box-shadow:0 4px 8px #00000026}.user-card.selected{background-color:#f8fafc;box-shadow:0 4px 8px #00000026;border-width:2px}.user-avatar{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;color:#fff;font-size:14px}.avatar-orange{background-color:#f97316}.avatar-blue{background-color:#3b82f6}.avatar-green{background-color:#10b981}.avatar-grey{background-color:#6b7280}.avatar-purple{background-color:#8b5cf6}.user-info{flex:1}.username{font-weight:600;color:#1f2937;margin-bottom:.25rem}.document-counts{font-size:.875rem;color:#6b7280}.selection-indicator{position:absolute;top:8px;right:8px;width:20px;height:20px;background-color:#10b981;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:12px}.no-users-message{display:flex;justify-content:center;align-items:center;padding:2rem;background:#f8fafc;border-radius:8px;border:2px dashed #d1d5db;margin:1rem 0}.no-users-message p{color:#6b7280;font-size:.875rem;font-weight:500;margin:0;text-align:center}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], animations: [
|
|
1719
|
+
trigger('slideInFromTop', [
|
|
1720
|
+
state('void', style({
|
|
1721
|
+
opacity: 0,
|
|
1722
|
+
transform: 'translateY(-10px)'
|
|
1723
|
+
})),
|
|
1724
|
+
state('*', style({
|
|
1725
|
+
opacity: 1,
|
|
1726
|
+
transform: 'translateY(0)'
|
|
1727
|
+
})),
|
|
1728
|
+
transition('void => *', [
|
|
1729
|
+
animate('300ms ease-out')
|
|
1730
|
+
])
|
|
1731
|
+
]),
|
|
1732
|
+
trigger('fadeIn', [
|
|
1733
|
+
state('void', style({
|
|
1734
|
+
opacity: 0,
|
|
1735
|
+
transform: 'scale(0.8)'
|
|
1736
|
+
})),
|
|
1737
|
+
state('*', style({
|
|
1738
|
+
opacity: 1,
|
|
1739
|
+
transform: 'scale(1)'
|
|
1740
|
+
})),
|
|
1741
|
+
transition('void => *', [
|
|
1742
|
+
animate('200ms ease-in-out')
|
|
1743
|
+
])
|
|
1744
|
+
])
|
|
1745
|
+
] });
|
|
931
1746
|
}
|
|
932
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1747
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UserListComponent, decorators: [{
|
|
933
1748
|
type: Component,
|
|
934
|
-
args: [{ selector: 'lib-
|
|
935
|
-
|
|
1749
|
+
args: [{ selector: 'lib-user-list', standalone: false, animations: [
|
|
1750
|
+
trigger('slideInFromTop', [
|
|
1751
|
+
state('void', style({
|
|
1752
|
+
opacity: 0,
|
|
1753
|
+
transform: 'translateY(-10px)'
|
|
1754
|
+
})),
|
|
1755
|
+
state('*', style({
|
|
1756
|
+
opacity: 1,
|
|
1757
|
+
transform: 'translateY(0)'
|
|
1758
|
+
})),
|
|
1759
|
+
transition('void => *', [
|
|
1760
|
+
animate('300ms ease-out')
|
|
1761
|
+
])
|
|
1762
|
+
]),
|
|
1763
|
+
trigger('fadeIn', [
|
|
1764
|
+
state('void', style({
|
|
1765
|
+
opacity: 0,
|
|
1766
|
+
transform: 'scale(0.8)'
|
|
1767
|
+
})),
|
|
1768
|
+
state('*', style({
|
|
1769
|
+
opacity: 1,
|
|
1770
|
+
transform: 'scale(1)'
|
|
1771
|
+
})),
|
|
1772
|
+
transition('void => *', [
|
|
1773
|
+
animate('200ms ease-in-out')
|
|
1774
|
+
])
|
|
1775
|
+
])
|
|
1776
|
+
], template: "<div class=\"user-list-container\" [@slideInFromTop]>\r\n <div class=\"user-cards\">\r\n <div \r\n *ngFor=\"let user of filteredUserData\" \r\n class=\"user-card\"\r\n [class.selected]=\"selectedUser === user.name\"\r\n [style.border-color]=\"selectedUser === user.name ? '#f97316' : 'transparent'\"\r\n (click)=\"onUserSelect(user.name, user._id)\"\r\n >\r\n <div class=\"user-avatar\" [ngClass]=\"'avatar-' + user.color\">\r\n <span class=\"initials\">{{ user.initials }}</span>\r\n </div>\r\n <div class=\"user-info\">\r\n <div class=\"username\">{{ user.name }}</div>\r\n <div class=\"document-counts\">\r\n {{ user.approved }} approved / {{ user.pending }} pending\r\n </div>\r\n </div>\r\n <div class=\"selection-indicator\" *ngIf=\"selectedUser === user.name\" [@fadeIn]>\r\n <i class=\"ri-check-line\"></i>\r\n </div>\r\n </div>\r\n \r\n <div *ngIf=\"filteredUserData.length === 0 && shouldShowContainer\" class=\"no-users-message\" [@slideInFromTop]>\r\n <p>No users available for this category.</p>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".user-list-container{padding:1rem}.user-cards{display:flex;flex-wrap:wrap;gap:1rem;transition:all .3s ease-in-out}.user-card{display:flex;align-items:center;gap:.75rem;padding:1rem;border:2px solid transparent;border-radius:8px;cursor:pointer;transition:all .2s ease;background:#fff;box-shadow:0 2px 4px #0000001a;min-width:330px;position:relative}.user-card:hover{box-shadow:0 4px 8px #00000026}.user-card.selected{background-color:#f8fafc;box-shadow:0 4px 8px #00000026;border-width:2px}.user-avatar{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;color:#fff;font-size:14px}.avatar-orange{background-color:#f97316}.avatar-blue{background-color:#3b82f6}.avatar-green{background-color:#10b981}.avatar-grey{background-color:#6b7280}.avatar-purple{background-color:#8b5cf6}.user-info{flex:1}.username{font-weight:600;color:#1f2937;margin-bottom:.25rem}.document-counts{font-size:.875rem;color:#6b7280}.selection-indicator{position:absolute;top:8px;right:8px;width:20px;height:20px;background-color:#10b981;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:12px}.no-users-message{display:flex;justify-content:center;align-items:center;padding:2rem;background:#f8fafc;border-radius:8px;border:2px dashed #d1d5db;margin:1rem 0}.no-users-message p{color:#6b7280;font-size:.875rem;font-weight:500;margin:0;text-align:center}\n"] }]
|
|
1777
|
+
}], ctorParameters: () => [{ type: DocumentHelperService }, { type: DocumentStore }, { type: DocumentQuery }, { type: UserListService }], propDecorators: { userList: [{
|
|
1778
|
+
type: Input
|
|
1779
|
+
}], categories: [{
|
|
1780
|
+
type: Input
|
|
1781
|
+
}], userSelected: [{
|
|
1782
|
+
type: Output
|
|
1783
|
+
}] } });
|
|
1784
|
+
|
|
1785
|
+
class StatusCalculatorService {
|
|
1786
|
+
calculateTotalCount(statusData) {
|
|
1787
|
+
return statusData?.reduce((total, status) => total + (status.count ?? 0), 0) || 0;
|
|
1788
|
+
}
|
|
1789
|
+
calculateStatusDataWithPercentages(statusData, selectedStatusId) {
|
|
1790
|
+
if (!statusData)
|
|
1791
|
+
return [];
|
|
1792
|
+
const totalCount = this.calculateTotalCount(statusData);
|
|
1793
|
+
return statusData.map((status) => ({
|
|
1794
|
+
...status,
|
|
1795
|
+
percentage: totalCount > 0 ? (status.count ?? 0) / totalCount * 100 : 0,
|
|
1796
|
+
isSelected: selectedStatusId === status._id,
|
|
1797
|
+
statusClass: status.status ? SHARED.STATUS_WITH_DASH + status.status.toLowerCase() : SHARED.EMPTY,
|
|
1798
|
+
iconClass: SHARED.ICON_WITH_DASH + (status?.status?.toLowerCase() || SHARED.EMPTY)
|
|
1799
|
+
}));
|
|
1800
|
+
}
|
|
1801
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StatusCalculatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1802
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StatusCalculatorService, providedIn: 'root' });
|
|
1803
|
+
}
|
|
1804
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: StatusCalculatorService, decorators: [{
|
|
1805
|
+
type: Injectable,
|
|
1806
|
+
args: [{
|
|
1807
|
+
providedIn: 'root'
|
|
1808
|
+
}]
|
|
1809
|
+
}] });
|
|
1810
|
+
|
|
1811
|
+
class DocumentStatusComponent {
|
|
1812
|
+
documentQuery;
|
|
1813
|
+
documentService;
|
|
1814
|
+
statusCalculatorService;
|
|
1815
|
+
contextId = SHARED.EMPTY;
|
|
1816
|
+
statusData;
|
|
1817
|
+
selectedStatusId = null;
|
|
1818
|
+
statusDataWithPercentages = [];
|
|
1819
|
+
subscription = new Subscription();
|
|
1820
|
+
constructor(documentQuery, documentService, statusCalculatorService) {
|
|
1821
|
+
this.documentQuery = documentQuery;
|
|
1822
|
+
this.documentService = documentService;
|
|
1823
|
+
this.statusCalculatorService = statusCalculatorService;
|
|
1824
|
+
}
|
|
1825
|
+
ngOnInit() {
|
|
1826
|
+
// Retrieve data from services
|
|
1827
|
+
this.subscription.add(this.documentQuery.selectSelectedStatus().subscribe(statusId => {
|
|
1828
|
+
this.selectedStatusId = statusId;
|
|
1829
|
+
this.updateCalculatedStatusData();
|
|
1830
|
+
}));
|
|
1831
|
+
this.subscription.add(this.documentQuery.selectStatusData().subscribe(statusData => {
|
|
1832
|
+
if (statusData && statusData.length > 0) {
|
|
1833
|
+
this.statusData = statusData;
|
|
1834
|
+
this.updateCalculatedStatusData();
|
|
1835
|
+
}
|
|
1836
|
+
}));
|
|
1837
|
+
}
|
|
1838
|
+
ngOnDestroy() {
|
|
1839
|
+
this.subscription.unsubscribe();
|
|
1840
|
+
}
|
|
1841
|
+
// Handle event from template
|
|
1842
|
+
selectStatus(statusId) {
|
|
1843
|
+
const newStatusId = this.selectedStatusId === statusId ? null : statusId;
|
|
1844
|
+
this.documentService.setSelectedStatus(newStatusId);
|
|
1845
|
+
}
|
|
1846
|
+
updateCalculatedStatusData() {
|
|
1847
|
+
this.statusDataWithPercentages = this.statusCalculatorService.calculateStatusDataWithPercentages(this.statusData, this.selectedStatusId);
|
|
1848
|
+
}
|
|
1849
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStatusComponent, deps: [{ token: DocumentQuery }, { token: DocumentHelperService }, { token: StatusCalculatorService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1850
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentStatusComponent, isStandalone: false, selector: "lib-document-status", inputs: { contextId: "contextId", statusData: "statusData" }, ngImport: i0, template: "<div class=\"status-summary-container\">\r\n <div class=\"status-cards\">\r\n \r\n <div \r\n *ngFor=\"let status of statusDataWithPercentages\" \r\n class=\"status-card {{ status.statusClass }}\"\r\n [class.selected]=\"status.isSelected\"\r\n (click)=\"selectStatus(status._id || '')\"\r\n >\r\n <div class=\"status-icon {{ status.iconClass }}\">\r\n <i [class]=\"status.icon\"></i>\r\n </div>\r\n <div class=\"status-info\">\r\n <div class=\"status-count\">{{ status.count }}</div>\r\n <div class=\"status-name\">{{ status.status }}</div>\r\n \r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"progress-bar-container\">\r\n <div class=\"progress-bar\">\r\n <div \r\n *ngFor=\"let status of statusDataWithPercentages\" \r\n class=\"progress-segment\"\r\n [style.width.%]=\"status.percentage\"\r\n [style.background-color]=\"status.color\"\r\n ></div>\r\n </div>\r\n </div>\r\n</div>", styles: [".status-summary-container{padding:1rem}.status-cards{display:flex;flex-wrap:wrap;gap:1rem;margin-bottom:1.5rem}.status-card{display:flex;align-items:center;gap:.75rem;padding:1rem;border-radius:8px;background:#fff;box-shadow:0 2px 4px #0000001a;min-width:150px;flex:1;cursor:pointer;transition:all .2s ease;border:2px solid transparent}.status-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.status-card.selected{border-width:3px!important;border-style:solid!important;box-shadow:0 4px 12px #0003}.status-card.selected.status-approved{border-color:#10b981!important;background:#ecfdf5!important}.status-card.selected.status-pending{border-color:#6b7280!important;background:#f8fafc!important}.status-card.selected.status-reviewing{border-color:#f59e0b!important;background:#fffbeb!important}.status-card.selected.status-rejected{border-color:#ef4444!important;background:#fff1f2!important}.status-card.selected.status-alert{border-color:#dc2626!important;background:#ef4444!important}.status-icon{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:18px;color:#fff}.icon-approved{background-color:#10b981}.icon-pending{background-color:#6b7280}.icon-reviewing{background-color:#f59e0b}.icon-rejected{background-color:#ef4444}.icon-alert{background-color:#dc2626}.status-info{flex:1}.status-name{font-weight:600;color:#1f2937;margin-bottom:.25rem}.status-count{font-size:1.5rem;font-weight:700;color:#374151}.progress-bar-container{margin-top:1rem}.progress-bar{height:8px;background-color:#e5e7eb;border-radius:4px;overflow:hidden;display:flex}.progress-segment{height:100%;transition:width .3s ease}\n"], dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
1851
|
+
}
|
|
1852
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStatusComponent, decorators: [{
|
|
1853
|
+
type: Component,
|
|
1854
|
+
args: [{ selector: 'lib-document-status', standalone: false, template: "<div class=\"status-summary-container\">\r\n <div class=\"status-cards\">\r\n \r\n <div \r\n *ngFor=\"let status of statusDataWithPercentages\" \r\n class=\"status-card {{ status.statusClass }}\"\r\n [class.selected]=\"status.isSelected\"\r\n (click)=\"selectStatus(status._id || '')\"\r\n >\r\n <div class=\"status-icon {{ status.iconClass }}\">\r\n <i [class]=\"status.icon\"></i>\r\n </div>\r\n <div class=\"status-info\">\r\n <div class=\"status-count\">{{ status.count }}</div>\r\n <div class=\"status-name\">{{ status.status }}</div>\r\n \r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"progress-bar-container\">\r\n <div class=\"progress-bar\">\r\n <div \r\n *ngFor=\"let status of statusDataWithPercentages\" \r\n class=\"progress-segment\"\r\n [style.width.%]=\"status.percentage\"\r\n [style.background-color]=\"status.color\"\r\n ></div>\r\n </div>\r\n </div>\r\n</div>", styles: [".status-summary-container{padding:1rem}.status-cards{display:flex;flex-wrap:wrap;gap:1rem;margin-bottom:1.5rem}.status-card{display:flex;align-items:center;gap:.75rem;padding:1rem;border-radius:8px;background:#fff;box-shadow:0 2px 4px #0000001a;min-width:150px;flex:1;cursor:pointer;transition:all .2s ease;border:2px solid transparent}.status-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.status-card.selected{border-width:3px!important;border-style:solid!important;box-shadow:0 4px 12px #0003}.status-card.selected.status-approved{border-color:#10b981!important;background:#ecfdf5!important}.status-card.selected.status-pending{border-color:#6b7280!important;background:#f8fafc!important}.status-card.selected.status-reviewing{border-color:#f59e0b!important;background:#fffbeb!important}.status-card.selected.status-rejected{border-color:#ef4444!important;background:#fff1f2!important}.status-card.selected.status-alert{border-color:#dc2626!important;background:#ef4444!important}.status-icon{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:18px;color:#fff}.icon-approved{background-color:#10b981}.icon-pending{background-color:#6b7280}.icon-reviewing{background-color:#f59e0b}.icon-rejected{background-color:#ef4444}.icon-alert{background-color:#dc2626}.status-info{flex:1}.status-name{font-weight:600;color:#1f2937;margin-bottom:.25rem}.status-count{font-size:1.5rem;font-weight:700;color:#374151}.progress-bar-container{margin-top:1rem}.progress-bar{height:8px;background-color:#e5e7eb;border-radius:4px;overflow:hidden;display:flex}.progress-segment{height:100%;transition:width .3s ease}\n"] }]
|
|
1855
|
+
}], ctorParameters: () => [{ type: DocumentQuery }, { type: DocumentHelperService }, { type: StatusCalculatorService }], propDecorators: { contextId: [{
|
|
1856
|
+
type: Input
|
|
1857
|
+
}], statusData: [{
|
|
936
1858
|
type: Input
|
|
937
1859
|
}] } });
|
|
938
1860
|
|
|
939
1861
|
/**
|
|
940
1862
|
* The `FolderContainerComponent` is responsible for rendering a container
|
|
941
1863
|
* that displays a list of documents and associated folder panel data.
|
|
942
|
-
*
|
|
943
1864
|
* This component utilizes the `FOLDERPANEL` constant for folder panel data
|
|
944
1865
|
* and accepts a document list input of type `DocumentModel`.
|
|
945
1866
|
*/
|
|
946
1867
|
class FolderContainerComponent {
|
|
1868
|
+
documentQuery;
|
|
947
1869
|
/**
|
|
948
1870
|
* A list of documents passed as input to the component.
|
|
949
1871
|
* Represents the document data to be displayed in the folder container.
|
|
@@ -959,20 +1881,146 @@ class FolderContainerComponent {
|
|
|
959
1881
|
* @type {string}
|
|
960
1882
|
*/
|
|
961
1883
|
contextId = SHARED.EMPTY;
|
|
962
|
-
|
|
963
|
-
|
|
1884
|
+
/**
|
|
1885
|
+
* The list of users passed as input to the component.
|
|
1886
|
+
* @type {UserListModel[]}
|
|
1887
|
+
*/
|
|
1888
|
+
userList = [];
|
|
1889
|
+
/**
|
|
1890
|
+
* The status data passed as input to the component.
|
|
1891
|
+
* @type {StatusDataModel[]}
|
|
1892
|
+
*/
|
|
1893
|
+
statusData = [];
|
|
1894
|
+
/**
|
|
1895
|
+
* The document categories passed as input to the component.
|
|
1896
|
+
* @type {DocumentCategory[]}
|
|
1897
|
+
*/
|
|
1898
|
+
categories = [];
|
|
1899
|
+
/**
|
|
1900
|
+
* Flag to control user list visibility
|
|
1901
|
+
*/
|
|
1902
|
+
showUserList = true;
|
|
1903
|
+
/**
|
|
1904
|
+
* Animation state for user list visibility
|
|
1905
|
+
*/
|
|
1906
|
+
userListAnimationState = SHARED.VISIBLE;
|
|
1907
|
+
constructor(documentQuery) {
|
|
1908
|
+
this.documentQuery = documentQuery;
|
|
1909
|
+
}
|
|
1910
|
+
ngOnInit() {
|
|
1911
|
+
this.documentQuery.selectShowUserList().subscribe(show => {
|
|
1912
|
+
this.showUserList = show;
|
|
1913
|
+
this.userListAnimationState = show ? SHARED.VISIBLE : SHARED.HIDDEN;
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1916
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderContainerComponent, deps: [{ token: DocumentQuery }], target: i0.ɵɵFactoryTarget.Component });
|
|
1917
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FolderContainerComponent, isStandalone: false, selector: "lib-folder-container", inputs: { documentList: "documentList", folderList: "folderList", contextId: "contextId", userList: "userList", statusData: "statusData", categories: "categories" }, ngImport: i0, template: "\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"], dependencies: [{ kind: "component", type: UserListComponent, selector: "lib-user-list", inputs: ["userList", "categories"], outputs: ["userSelected"] }, { kind: "component", type: DocumentStatusComponent, selector: "lib-document-status", inputs: ["contextId", "statusData"] }], animations: [
|
|
1918
|
+
trigger('slideInOut', [
|
|
1919
|
+
state('visible', style({
|
|
1920
|
+
height: '*',
|
|
1921
|
+
opacity: 1,
|
|
1922
|
+
transform: 'translateY(0)',
|
|
1923
|
+
overflow: 'hidden',
|
|
1924
|
+
marginBottom: '1rem',
|
|
1925
|
+
visibility: 'visible'
|
|
1926
|
+
})),
|
|
1927
|
+
state('hidden', style({
|
|
1928
|
+
height: '0px',
|
|
1929
|
+
opacity: 0,
|
|
1930
|
+
transform: 'translateY(-20px)',
|
|
1931
|
+
overflow: 'hidden',
|
|
1932
|
+
marginBottom: '0px',
|
|
1933
|
+
visibility: 'hidden'
|
|
1934
|
+
})),
|
|
1935
|
+
transition('visible => hidden', [
|
|
1936
|
+
animate('250ms cubic-bezier(0.4, 0.0, 0.2, 1)')
|
|
1937
|
+
]),
|
|
1938
|
+
transition('hidden => visible', [
|
|
1939
|
+
animate('300ms cubic-bezier(0.0, 0.0, 0.2, 1)')
|
|
1940
|
+
])
|
|
1941
|
+
])
|
|
1942
|
+
] });
|
|
964
1943
|
}
|
|
965
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
1944
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderContainerComponent, decorators: [{
|
|
966
1945
|
type: Component,
|
|
967
|
-
args: [{ selector: 'lib-folder-container', standalone: false,
|
|
968
|
-
|
|
1946
|
+
args: [{ selector: 'lib-folder-container', standalone: false, animations: [
|
|
1947
|
+
trigger('slideInOut', [
|
|
1948
|
+
state('visible', style({
|
|
1949
|
+
height: '*',
|
|
1950
|
+
opacity: 1,
|
|
1951
|
+
transform: 'translateY(0)',
|
|
1952
|
+
overflow: 'hidden',
|
|
1953
|
+
marginBottom: '1rem',
|
|
1954
|
+
visibility: 'visible'
|
|
1955
|
+
})),
|
|
1956
|
+
state('hidden', style({
|
|
1957
|
+
height: '0px',
|
|
1958
|
+
opacity: 0,
|
|
1959
|
+
transform: 'translateY(-20px)',
|
|
1960
|
+
overflow: 'hidden',
|
|
1961
|
+
marginBottom: '0px',
|
|
1962
|
+
visibility: 'hidden'
|
|
1963
|
+
})),
|
|
1964
|
+
transition('visible => hidden', [
|
|
1965
|
+
animate('250ms cubic-bezier(0.4, 0.0, 0.2, 1)')
|
|
1966
|
+
]),
|
|
1967
|
+
transition('hidden => visible', [
|
|
1968
|
+
animate('300ms cubic-bezier(0.0, 0.0, 0.2, 1)')
|
|
1969
|
+
])
|
|
1970
|
+
])
|
|
1971
|
+
], template: "\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"] }]
|
|
1972
|
+
}], ctorParameters: () => [{ type: DocumentQuery }], propDecorators: { documentList: [{
|
|
969
1973
|
type: Input
|
|
970
1974
|
}], folderList: [{
|
|
971
1975
|
type: Input
|
|
972
1976
|
}], contextId: [{
|
|
973
1977
|
type: Input
|
|
1978
|
+
}], userList: [{
|
|
1979
|
+
type: Input
|
|
1980
|
+
}], statusData: [{
|
|
1981
|
+
type: Input
|
|
1982
|
+
}], categories: [{
|
|
1983
|
+
type: Input
|
|
974
1984
|
}] } });
|
|
975
1985
|
|
|
1986
|
+
/**
|
|
1987
|
+
* A utility class containing common error messages.
|
|
1988
|
+
* @class ERRORS
|
|
1989
|
+
*/
|
|
1990
|
+
class ERRORS {
|
|
1991
|
+
/**
|
|
1992
|
+
* Error message for invalid recipient.
|
|
1993
|
+
* @static
|
|
1994
|
+
* @type {string}
|
|
1995
|
+
*/
|
|
1996
|
+
static INVALID_RECIPIENT = "Invalid recipient: The recipient cannot be empty.";
|
|
1997
|
+
/**
|
|
1998
|
+
* Error message for invalid document.
|
|
1999
|
+
* @static
|
|
2000
|
+
* @type {string}
|
|
2001
|
+
*/
|
|
2002
|
+
static ERROR_FETCHING_DOCUMENTS = "Error fetching documents:";
|
|
2003
|
+
/**
|
|
2004
|
+
* Error message for invalid document.
|
|
2005
|
+
* @static
|
|
2006
|
+
* @type {string}
|
|
2007
|
+
*/
|
|
2008
|
+
static ERROR_FETCHING_FOLDERS = "Error fetching folders:";
|
|
2009
|
+
/**
|
|
2010
|
+
* Error message for invalid document.
|
|
2011
|
+
* @static
|
|
2012
|
+
* @type {string}
|
|
2013
|
+
*/
|
|
2014
|
+
static ERROR_ALLDOCUMENT_MISSING = "allDocumentTypes is missing in the response:";
|
|
2015
|
+
/**
|
|
2016
|
+
* Error message for invalid document.
|
|
2017
|
+
* @static
|
|
2018
|
+
* @type {string}
|
|
2019
|
+
*/
|
|
2020
|
+
static ERROR_DOCUMENT_TYPES = "Error fetching document types:";
|
|
2021
|
+
static ERROR_DOCUMENT_CATAGORY = 'Error fetching document categories:';
|
|
2022
|
+
}
|
|
2023
|
+
|
|
976
2024
|
/**
|
|
977
2025
|
* Storing all permission properties.
|
|
978
2026
|
* @export
|
|
@@ -1101,54 +2149,244 @@ class DocumentUploadService {
|
|
|
1101
2149
|
return null;
|
|
1102
2150
|
}
|
|
1103
2151
|
}
|
|
1104
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1105
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
2152
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, deps: [{ token: DocumentService }, { token: DocumentStore }, { token: i3.MessageService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2153
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, providedIn: 'root' });
|
|
1106
2154
|
}
|
|
1107
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2155
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, decorators: [{
|
|
1108
2156
|
type: Injectable,
|
|
1109
2157
|
args: [{
|
|
1110
2158
|
providedIn: 'root'
|
|
1111
2159
|
}]
|
|
1112
|
-
}], ctorParameters: () => [{ type: DocumentService
|
|
2160
|
+
}], ctorParameters: () => [{ type: DocumentService }, { type: DocumentStore }, { type: i3.MessageService }] });
|
|
1113
2161
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
*
|
|
1117
|
-
* This component displays individual document items within a list.
|
|
1118
|
-
* It accepts a list of documents as input and handles interactions with documents.
|
|
1119
|
-
*/
|
|
1120
|
-
class DocumentListItemComponent {
|
|
2162
|
+
class DocumentTableBuilderService {
|
|
2163
|
+
constructor() { }
|
|
1121
2164
|
/**
|
|
1122
|
-
*
|
|
1123
|
-
* @
|
|
2165
|
+
* Gets document type from file name extension
|
|
2166
|
+
* @param fileName File name with extension
|
|
2167
|
+
* @returns Document type string
|
|
1124
2168
|
*/
|
|
1125
|
-
|
|
2169
|
+
getDocumentTypeFromFileName(fileName) {
|
|
2170
|
+
if (!fileName)
|
|
2171
|
+
return '';
|
|
2172
|
+
const extension = fileName.split('.').pop()?.toUpperCase();
|
|
2173
|
+
return extension || '';
|
|
2174
|
+
}
|
|
1126
2175
|
/**
|
|
1127
|
-
*
|
|
1128
|
-
* @
|
|
2176
|
+
* Builds table data for document categories
|
|
2177
|
+
* @param categories Array of document categories
|
|
2178
|
+
* @returns Array of TableData objects
|
|
1129
2179
|
*/
|
|
1130
|
-
|
|
2180
|
+
buildDocumentCategoriesTables(categories) {
|
|
2181
|
+
return categories.map(category => this.buildTableForCategory(category));
|
|
2182
|
+
}
|
|
1131
2183
|
/**
|
|
1132
|
-
*
|
|
1133
|
-
* @param
|
|
2184
|
+
* Builds table data for a single document category
|
|
2185
|
+
* @param category Document category
|
|
2186
|
+
* @returns TableData object
|
|
1134
2187
|
*/
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
2188
|
+
buildTableForCategory(category) {
|
|
2189
|
+
const columns = [
|
|
2190
|
+
{
|
|
2191
|
+
field: 'docName',
|
|
2192
|
+
header: 'Document',
|
|
2193
|
+
type: 'document',
|
|
2194
|
+
width: '35%'
|
|
2195
|
+
},
|
|
2196
|
+
{
|
|
2197
|
+
field: 'status',
|
|
2198
|
+
header: 'Status',
|
|
2199
|
+
type: 'status',
|
|
2200
|
+
width: '15%'
|
|
2201
|
+
},
|
|
2202
|
+
{
|
|
2203
|
+
field: 'ownerName',
|
|
2204
|
+
header: 'Owner',
|
|
2205
|
+
type: 'text',
|
|
2206
|
+
width: '20%'
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
field: 'uploadedOn',
|
|
2210
|
+
header: 'Uploaded',
|
|
2211
|
+
type: 'text',
|
|
2212
|
+
width: '15%'
|
|
2213
|
+
},
|
|
2214
|
+
{
|
|
2215
|
+
field: 'actions',
|
|
2216
|
+
header: 'Actions',
|
|
2217
|
+
type: 'actions',
|
|
2218
|
+
width: '15%'
|
|
2219
|
+
}
|
|
2220
|
+
];
|
|
2221
|
+
return {
|
|
2222
|
+
columns: columns,
|
|
2223
|
+
data: category.list
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Builds a single table from document list items
|
|
2228
|
+
* @param documents Array of document list items
|
|
2229
|
+
* @returns TableData object
|
|
2230
|
+
*/
|
|
2231
|
+
buildDocumentTable(documents) {
|
|
2232
|
+
const columns = [
|
|
2233
|
+
{
|
|
2234
|
+
field: 'docName',
|
|
2235
|
+
header: 'Document',
|
|
2236
|
+
type: 'document',
|
|
2237
|
+
width: '35%'
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
field: 'status',
|
|
2241
|
+
header: 'Status',
|
|
2242
|
+
type: 'status',
|
|
2243
|
+
width: '15%'
|
|
2244
|
+
},
|
|
2245
|
+
{
|
|
2246
|
+
field: 'ownerName',
|
|
2247
|
+
header: 'Owner',
|
|
2248
|
+
type: 'text',
|
|
2249
|
+
width: '20%'
|
|
2250
|
+
},
|
|
2251
|
+
{
|
|
2252
|
+
field: 'uploadedOn',
|
|
2253
|
+
header: 'Uploaded',
|
|
2254
|
+
type: 'text',
|
|
2255
|
+
width: '15%'
|
|
2256
|
+
},
|
|
2257
|
+
{
|
|
2258
|
+
field: 'actions',
|
|
2259
|
+
header: 'Actions',
|
|
2260
|
+
type: 'actions',
|
|
2261
|
+
width: '15%'
|
|
2262
|
+
}
|
|
2263
|
+
];
|
|
2264
|
+
return {
|
|
2265
|
+
columns: columns,
|
|
2266
|
+
data: documents
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
/**
|
|
2270
|
+
* Gets completion count for a category
|
|
2271
|
+
* @param category Document category
|
|
2272
|
+
* @returns Completion string (e.g., "2/4")
|
|
2273
|
+
*/
|
|
2274
|
+
getCompletionCount(category) {
|
|
2275
|
+
const total = category.list.length;
|
|
2276
|
+
const completed = category.list.filter(doc => doc.status.toLowerCase() === 'approved' ||
|
|
2277
|
+
doc.status.toLowerCase() === 'uploaded').length;
|
|
2278
|
+
return `${completed}/${total}`;
|
|
2279
|
+
}
|
|
2280
|
+
/**
|
|
2281
|
+
* Gets pending document count for a category
|
|
2282
|
+
* @param category Document category
|
|
2283
|
+
* @returns Number of pending documents
|
|
2284
|
+
*/
|
|
2285
|
+
getPendingDocumentCount(category) {
|
|
2286
|
+
return category.totalDocs - category.acceptedDocs;
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Gets approved document count for a category
|
|
2290
|
+
* @param category Document category
|
|
2291
|
+
* @returns Number of approved documents
|
|
2292
|
+
*/
|
|
2293
|
+
getApprovedDocumentCount(category) {
|
|
2294
|
+
return category.acceptedDocs;
|
|
1141
2295
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
2296
|
+
/**
|
|
2297
|
+
* Transforms document model to document list item
|
|
2298
|
+
* @param documents Array of DocumentModel
|
|
2299
|
+
* @returns Array of DocumentListItem
|
|
2300
|
+
*/
|
|
2301
|
+
transformDocumentModelToListItem(documents) {
|
|
2302
|
+
return documents.map(doc => ({
|
|
2303
|
+
_id: doc._id || '',
|
|
2304
|
+
fileName: doc.fileName || '',
|
|
2305
|
+
docName: doc.docName || doc.documentName || '',
|
|
2306
|
+
fileSize: doc.fileSize || '',
|
|
2307
|
+
documentUrl: doc.documentUrl || doc.url || '',
|
|
2308
|
+
status: doc.status || 'Pending',
|
|
2309
|
+
uploadedOn: doc.uploadedOn || doc.uploadDate || '',
|
|
2310
|
+
ownerName: doc.ownerName || doc.applicantName || ''
|
|
2311
|
+
}));
|
|
2312
|
+
}
|
|
2313
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2314
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, providedIn: 'root' });
|
|
2315
|
+
}
|
|
2316
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, decorators: [{
|
|
2317
|
+
type: Injectable,
|
|
2318
|
+
args: [{
|
|
2319
|
+
providedIn: 'root'
|
|
2320
|
+
}]
|
|
2321
|
+
}], ctorParameters: () => [] });
|
|
2322
|
+
|
|
2323
|
+
class TablePrimaryComponent {
|
|
2324
|
+
tableData = { columns: [], data: [] };
|
|
2325
|
+
showHeader = true;
|
|
2326
|
+
tableStyle = { 'min-width': '100%' };
|
|
2327
|
+
rowClick = new EventEmitter();
|
|
2328
|
+
// Helper methods for document table
|
|
2329
|
+
getStatusClass(status) {
|
|
2330
|
+
switch (status.toLowerCase()) {
|
|
2331
|
+
case 'pending':
|
|
2332
|
+
return 'status-pending';
|
|
2333
|
+
case 'approved':
|
|
2334
|
+
return 'status-approved';
|
|
2335
|
+
case 'alert':
|
|
2336
|
+
return 'status-alert';
|
|
2337
|
+
case 'uploaded':
|
|
2338
|
+
return 'status-uploaded';
|
|
2339
|
+
case 'reviewing':
|
|
2340
|
+
return 'status-reviewing';
|
|
2341
|
+
case 'rejected':
|
|
2342
|
+
return 'status-rejected';
|
|
2343
|
+
default:
|
|
2344
|
+
return 'status-pending';
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
getStatusIcon(status) {
|
|
2348
|
+
switch (status.toLowerCase()) {
|
|
2349
|
+
case 'pending':
|
|
2350
|
+
return 'pi pi-clock';
|
|
2351
|
+
case 'approved':
|
|
2352
|
+
return 'pi pi-check';
|
|
2353
|
+
case 'alert':
|
|
2354
|
+
return 'pi pi-exclamation-triangle';
|
|
2355
|
+
case 'uploaded':
|
|
2356
|
+
return 'pi pi-cloud-upload';
|
|
2357
|
+
case 'reviewing':
|
|
2358
|
+
return 'pi pi-eye';
|
|
2359
|
+
case 'rejected':
|
|
2360
|
+
return 'pi pi-times';
|
|
2361
|
+
default:
|
|
2362
|
+
return 'pi pi-clock';
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
getFileExtension(fileName) {
|
|
2366
|
+
return fileName.split('.').pop()?.toUpperCase() || 'PDF';
|
|
2367
|
+
}
|
|
2368
|
+
onActionClick(event, rowData) {
|
|
2369
|
+
event.stopPropagation();
|
|
2370
|
+
// Handle action menu click - can be extended with menu functionality
|
|
2371
|
+
console.log('Action clicked for document:', rowData);
|
|
2372
|
+
}
|
|
2373
|
+
onRowClick(rowData) {
|
|
2374
|
+
this.rowClick.emit(rowData);
|
|
2375
|
+
}
|
|
2376
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TablePrimaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2377
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: TablePrimaryComponent, isStandalone: false, selector: "lib-table-primary", inputs: { tableData: "tableData", showHeader: "showHeader", tableStyle: "tableStyle" }, outputs: { rowClick: "rowClick" }, ngImport: i0, template: "<div class=\"card\">\n <p-table [value]=\"tableData.data\" [tableStyle]=\"tableStyle\">\n <ng-template pTemplate=\"header\" *ngIf=\"showHeader\">\n <tr>\n <th *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\n {{ col.header }}\n </th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowData>\n <tr (click)=\"onRowClick(rowData)\" class=\"clickable-row\">\n <td *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\n <!-- Document Cell -->\n <div *ngIf=\"col.type === 'document'\" class=\"document-cell\">\n <div class=\"document-info\">\n <div class=\"document-icon\">\n <i class=\"pi pi-file-pdf\" *ngIf=\"getFileExtension(rowData.fileName) === 'PDF'\"></i>\n <i class=\"pi pi-image\" *ngIf=\"getFileExtension(rowData.fileName) === 'JPG' || getFileExtension(rowData.fileName) === 'PNG'\"></i>\n <i class=\"pi pi-file-excel\" *ngIf=\"getFileExtension(rowData.fileName) === 'XLSX'\"></i>\n <i class=\"pi pi-file\" *ngIf=\"getFileExtension(rowData.fileName) !== 'PDF' && getFileExtension(rowData.fileName) !== 'JPG' && getFileExtension(rowData.fileName) !== 'PNG' && getFileExtension(rowData.fileName) !== 'XLSX'\"></i>\n </div>\n <div class=\"document-details\">\n <div class=\"document-name\">{{ rowData.docName }}</div>\n <div class=\"file-info\">{{ rowData.fileName }} - {{ rowData.fileSize }}</div>\n </div>\n </div>\n </div>\n\n <!-- Status Cell -->\n \n <div *ngIf=\"col.type === 'status'\" class=\"status-cell\">\n <span class=\"status-pill\" [ngClass]=\"getStatusClass(rowData[col.field])\">\n <i [class]=\"getStatusIcon(rowData[col.field])\"></i>\n {{ rowData[col.field] }}\n </span>\n </div>\n\n <!-- Actions Cell -->\n <div *ngIf=\"col.type === 'actions'\" class=\"actions-cell\">\n <button pButton pRipple type=\"button\" icon=\"ri-delete-bin-6-line\" \n class=\"p-button-text p-button-rounded\" \n (click)=\"onActionClick($event, rowData)\">\n </button>\n </div>\n\n <!-- Default Text Cell -->\n <div *ngIf=\"!col.type || col.type === 'text'\" class=\"text-cell\">\n {{ rowData[col.field] }}\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n</div>", styles: [".document-cell .document-info{display:flex;align-items:center;gap:.75rem;text-align:left}.document-cell .document-info .document-icon{width:40px;height:40px;background-color:#e3f2fd;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#1976d2;font-size:1.25rem;flex-shrink:0}.document-cell .document-info .document-details{flex:1;min-width:0}.document-cell .document-info .document-details .document-name{font-weight:400;color:#334155;line-height:20px;font-size:14px;margin-bottom:.25rem;text-align:left}.document-cell .document-info .document-details .file-info{font-size:.75rem;color:#6c757d;text-align:left}.status-cell .status-pill{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;padding:.375rem .75rem;border-radius:20px;font-size:.75rem;font-weight:500;white-space:nowrap;min-width:80px}.status-cell .status-pill i{font-size:.875rem}.status-cell .status-pill.status-pending{background-color:#f3f4f6;color:#6b7280}.status-cell .status-pill.status-approved{background-color:#d1fae5;color:#065f46}.status-cell .status-pill.status-alert{background-color:#fee2e2;color:#dc2626}.status-cell .status-pill.status-uploaded{background-color:#dbeafe;color:#1d4ed8}.status-cell .status-pill.status-reviewing{background-color:#fef3c7;color:#d97706}.status-cell .status-pill.status-rejected{background-color:#fee2e2;color:#dc2626}.actions-cell{text-align:left}.actions-cell .p-button{width:2rem;height:2rem;border-radius:50%;background-color:transparent;border:none;color:#6c757d}.actions-cell .p-button:hover{background-color:#f8f9fa;color:#495057}.text-cell{font-weight:500;color:#475569;font-size:14px;line-height:20px;text-align:left}.clickable-row{cursor:pointer;transition:background-color .2s ease}.clickable-row:hover{background-color:#f8f9fa!important}.clickable-row:active{background-color:#e9ecef!important}::ng-deep .p-datatable .p-datatable-wrapper{border:1px solid #E2E8F0;border-radius:10px}::ng-deep .p-datatable .p-datatable-thead>tr>th{background-color:#f8f9fa;border:none;border-bottom:1px solid #dee2e6;padding:1rem 1.5rem;font-weight:600;color:#64748b;font-size:.875rem;text-transform:capitalize;letter-spacing:.5px;text-align:left;border-radius:8px 8px 0 0}::ng-deep .p-datatable .p-datatable-thead>tr>th:first-child{border-top-left-radius:8px}::ng-deep .p-datatable .p-datatable-thead>tr>th:last-child{border-top-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr{border-bottom:1px solid #f1f3f4}::ng-deep .p-datatable .p-datatable-tbody>tr:hover{background-color:#f8f9fa}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:first-child{border-bottom-left-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:last-child{border-bottom-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr>td{border:none;padding:1rem 1.5rem;vertical-align:middle;text-align:left}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i8.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5$1.Ripple, selector: "[pRipple]" }] });
|
|
1144
2378
|
}
|
|
1145
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2379
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TablePrimaryComponent, decorators: [{
|
|
1146
2380
|
type: Component,
|
|
1147
|
-
args: [{ selector: 'lib-
|
|
1148
|
-
}], propDecorators: {
|
|
1149
|
-
type:
|
|
1150
|
-
}],
|
|
2381
|
+
args: [{ selector: 'lib-table-primary', standalone: false, template: "<div class=\"card\">\n <p-table [value]=\"tableData.data\" [tableStyle]=\"tableStyle\">\n <ng-template pTemplate=\"header\" *ngIf=\"showHeader\">\n <tr>\n <th *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\n {{ col.header }}\n </th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowData>\n <tr (click)=\"onRowClick(rowData)\" class=\"clickable-row\">\n <td *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\n <!-- Document Cell -->\n <div *ngIf=\"col.type === 'document'\" class=\"document-cell\">\n <div class=\"document-info\">\n <div class=\"document-icon\">\n <i class=\"pi pi-file-pdf\" *ngIf=\"getFileExtension(rowData.fileName) === 'PDF'\"></i>\n <i class=\"pi pi-image\" *ngIf=\"getFileExtension(rowData.fileName) === 'JPG' || getFileExtension(rowData.fileName) === 'PNG'\"></i>\n <i class=\"pi pi-file-excel\" *ngIf=\"getFileExtension(rowData.fileName) === 'XLSX'\"></i>\n <i class=\"pi pi-file\" *ngIf=\"getFileExtension(rowData.fileName) !== 'PDF' && getFileExtension(rowData.fileName) !== 'JPG' && getFileExtension(rowData.fileName) !== 'PNG' && getFileExtension(rowData.fileName) !== 'XLSX'\"></i>\n </div>\n <div class=\"document-details\">\n <div class=\"document-name\">{{ rowData.docName }}</div>\n <div class=\"file-info\">{{ rowData.fileName }} - {{ rowData.fileSize }}</div>\n </div>\n </div>\n </div>\n\n <!-- Status Cell -->\n \n <div *ngIf=\"col.type === 'status'\" class=\"status-cell\">\n <span class=\"status-pill\" [ngClass]=\"getStatusClass(rowData[col.field])\">\n <i [class]=\"getStatusIcon(rowData[col.field])\"></i>\n {{ rowData[col.field] }}\n </span>\n </div>\n\n <!-- Actions Cell -->\n <div *ngIf=\"col.type === 'actions'\" class=\"actions-cell\">\n <button pButton pRipple type=\"button\" icon=\"ri-delete-bin-6-line\" \n class=\"p-button-text p-button-rounded\" \n (click)=\"onActionClick($event, rowData)\">\n </button>\n </div>\n\n <!-- Default Text Cell -->\n <div *ngIf=\"!col.type || col.type === 'text'\" class=\"text-cell\">\n {{ rowData[col.field] }}\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n</div>", styles: [".document-cell .document-info{display:flex;align-items:center;gap:.75rem;text-align:left}.document-cell .document-info .document-icon{width:40px;height:40px;background-color:#e3f2fd;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#1976d2;font-size:1.25rem;flex-shrink:0}.document-cell .document-info .document-details{flex:1;min-width:0}.document-cell .document-info .document-details .document-name{font-weight:400;color:#334155;line-height:20px;font-size:14px;margin-bottom:.25rem;text-align:left}.document-cell .document-info .document-details .file-info{font-size:.75rem;color:#6c757d;text-align:left}.status-cell .status-pill{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;padding:.375rem .75rem;border-radius:20px;font-size:.75rem;font-weight:500;white-space:nowrap;min-width:80px}.status-cell .status-pill i{font-size:.875rem}.status-cell .status-pill.status-pending{background-color:#f3f4f6;color:#6b7280}.status-cell .status-pill.status-approved{background-color:#d1fae5;color:#065f46}.status-cell .status-pill.status-alert{background-color:#fee2e2;color:#dc2626}.status-cell .status-pill.status-uploaded{background-color:#dbeafe;color:#1d4ed8}.status-cell .status-pill.status-reviewing{background-color:#fef3c7;color:#d97706}.status-cell .status-pill.status-rejected{background-color:#fee2e2;color:#dc2626}.actions-cell{text-align:left}.actions-cell .p-button{width:2rem;height:2rem;border-radius:50%;background-color:transparent;border:none;color:#6c757d}.actions-cell .p-button:hover{background-color:#f8f9fa;color:#495057}.text-cell{font-weight:500;color:#475569;font-size:14px;line-height:20px;text-align:left}.clickable-row{cursor:pointer;transition:background-color .2s ease}.clickable-row:hover{background-color:#f8f9fa!important}.clickable-row:active{background-color:#e9ecef!important}::ng-deep .p-datatable .p-datatable-wrapper{border:1px solid #E2E8F0;border-radius:10px}::ng-deep .p-datatable .p-datatable-thead>tr>th{background-color:#f8f9fa;border:none;border-bottom:1px solid #dee2e6;padding:1rem 1.5rem;font-weight:600;color:#64748b;font-size:.875rem;text-transform:capitalize;letter-spacing:.5px;text-align:left;border-radius:8px 8px 0 0}::ng-deep .p-datatable .p-datatable-thead>tr>th:first-child{border-top-left-radius:8px}::ng-deep .p-datatable .p-datatable-thead>tr>th:last-child{border-top-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr{border-bottom:1px solid #f1f3f4}::ng-deep .p-datatable .p-datatable-tbody>tr:hover{background-color:#f8f9fa}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:first-child{border-bottom-left-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:last-child{border-bottom-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr>td{border:none;padding:1rem 1.5rem;vertical-align:middle;text-align:left}\n"] }]
|
|
2382
|
+
}], propDecorators: { tableData: [{
|
|
2383
|
+
type: Input
|
|
2384
|
+
}], showHeader: [{
|
|
2385
|
+
type: Input
|
|
2386
|
+
}], tableStyle: [{
|
|
1151
2387
|
type: Input
|
|
2388
|
+
}], rowClick: [{
|
|
2389
|
+
type: Output
|
|
1152
2390
|
}] } });
|
|
1153
2391
|
|
|
1154
2392
|
/**
|
|
@@ -1184,10 +2422,10 @@ class FileFormatService {
|
|
|
1184
2422
|
return `${parseFloat(mbSize.toFixed(decimalPlaces))} ${sizes[SHARED.TWO]}`;
|
|
1185
2423
|
}
|
|
1186
2424
|
}
|
|
1187
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1188
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
2425
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileFormatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2426
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileFormatService, providedIn: 'root' });
|
|
1189
2427
|
}
|
|
1190
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2428
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileFormatService, decorators: [{
|
|
1191
2429
|
type: Injectable,
|
|
1192
2430
|
args: [{
|
|
1193
2431
|
providedIn: 'root'
|
|
@@ -1333,48 +2571,19 @@ class DocumentUploadComponent {
|
|
|
1333
2571
|
triggerFileUpload() {
|
|
1334
2572
|
this.fileUploader.choose();
|
|
1335
2573
|
}
|
|
1336
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1337
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.
|
|
2574
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, deps: [{ token: DocumentUploadService }, { token: DocumentService }, { token: i3.PrimeNGConfig }, { token: FileFormatService }, { token: i3.MessageService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2575
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentUploadComponent, isStandalone: false, selector: "lib-document-upload", inputs: { contextId: "contextId" }, viewQueries: [{ propertyName: "fileUploader", first: true, predicate: ["fileUploader"], descendants: true }], ngImport: i0, template: "<div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload #fileUploader [multiple]=\"true\" auto=\"true\" accept=\"image/png,application/pdf\" maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\">\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button (onClick)=\"choose($event, chooseCallback)\" icon=\"pi pi-images\" [rounded]=\"true\"\r\n [outlined]=\"true\" />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\" font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified \"> {{ uploadedFile.formattedSize }}</div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> {{ uploadedFile.progress }} %</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar [value]=\"totalSizePercent\" [showValue]=\"false\" styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': totalSizePercent > 100 }\">\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i8.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i7.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "component", type: i8$1.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
1338
2576
|
}
|
|
1339
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2577
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, decorators: [{
|
|
1340
2578
|
type: Component,
|
|
1341
2579
|
args: [{ selector: 'lib-document-upload', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload #fileUploader [multiple]=\"true\" auto=\"true\" accept=\"image/png,application/pdf\" maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\">\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button (onClick)=\"choose($event, chooseCallback)\" icon=\"pi pi-images\" [rounded]=\"true\"\r\n [outlined]=\"true\" />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\" font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified \"> {{ uploadedFile.formattedSize }}</div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> {{ uploadedFile.progress }} %</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar [value]=\"totalSizePercent\" [showValue]=\"false\" styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': totalSizePercent > 100 }\">\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}\n"] }]
|
|
1342
|
-
}], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService
|
|
2580
|
+
}], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }], propDecorators: { contextId: [{
|
|
1343
2581
|
type: Input
|
|
1344
2582
|
}], fileUploader: [{
|
|
1345
2583
|
type: ViewChild,
|
|
1346
2584
|
args: ['fileUploader']
|
|
1347
2585
|
}] } });
|
|
1348
2586
|
|
|
1349
|
-
/**
|
|
1350
|
-
* Service to manage the document data
|
|
1351
|
-
*/
|
|
1352
|
-
class DocumentService {
|
|
1353
|
-
documentSubject$ = new BehaviorSubject(null);
|
|
1354
|
-
/**
|
|
1355
|
-
* Set the document data
|
|
1356
|
-
* @param document the document data
|
|
1357
|
-
*/
|
|
1358
|
-
set(document) {
|
|
1359
|
-
this.documentSubject$.next(document);
|
|
1360
|
-
}
|
|
1361
|
-
/**
|
|
1362
|
-
* Get the document data
|
|
1363
|
-
* @returns the document data
|
|
1364
|
-
*/
|
|
1365
|
-
get() {
|
|
1366
|
-
return this.documentSubject$.asObservable();
|
|
1367
|
-
}
|
|
1368
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: DocumentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1369
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: DocumentService, providedIn: 'root' });
|
|
1370
|
-
}
|
|
1371
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: DocumentService, decorators: [{
|
|
1372
|
-
type: Injectable,
|
|
1373
|
-
args: [{
|
|
1374
|
-
providedIn: 'root',
|
|
1375
|
-
}]
|
|
1376
|
-
}] });
|
|
1377
|
-
|
|
1378
2587
|
/**
|
|
1379
2588
|
* Description placeholder
|
|
1380
2589
|
* @class LinkedDocumentComponent
|
|
@@ -1410,10 +2619,10 @@ class LinkedDocumentComponent {
|
|
|
1410
2619
|
this.selectedDocument = document;
|
|
1411
2620
|
this.selectedDocumentChange.emit(this.selectedDocument);
|
|
1412
2621
|
}
|
|
1413
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1414
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.
|
|
2622
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: LinkedDocumentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2623
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: LinkedDocumentComponent, isStandalone: false, selector: "app-linked-document", inputs: { selectedDocument: "selectedDocument", documentList: "documentList" }, outputs: { selectedDocumentChange: "selectedDocumentChange" }, ngImport: i0, template: "<div class=\"summary-card mb-4 pb-1\">\r\n <div class=\"card p-0 mb-0\"\r\n style=\"border-bottom: 1px solid;border-color: rgba(68, 72, 109, 0.2); border-bottom-right-radius: 0px;border-bottom-left-radius: 0px; background-color: #F9fafb;\">\r\n <div class=\"p-0\">\r\n <h4 class=\"m-0 pt-3 pl-3 mb-3\" style=\"font-size: 21px; font-weight: bold; \">Linked Documents</h4>\r\n </div>\r\n </div>\r\n <div class=\"card mb-0\" style=\"border-top-right-radius: 0px;border-top-left-radius: 0px;\">\r\n @for(document of documentList; track document){\r\n <div class=\"linkedDocument documentName m-2\">\r\n <div class=\"documentName\" [class.selected]=\"document._id === selectedDocument?._id\"\r\n (click)=\"handleDocumentClick(document)\">\r\n <span class=\"pi pi-link\"></span>\r\n {{document.fileName}}\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n \r\n \r\n </div>\r\n ", styles: [".documentName{font-family:inherit;text-decoration:underline;cursor:pointer;width:max-content}.selected{color:var(--primary-color)}\n"] });
|
|
1415
2624
|
}
|
|
1416
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2625
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: LinkedDocumentComponent, decorators: [{
|
|
1417
2626
|
type: Component,
|
|
1418
2627
|
args: [{ selector: 'app-linked-document', standalone: false, template: "<div class=\"summary-card mb-4 pb-1\">\r\n <div class=\"card p-0 mb-0\"\r\n style=\"border-bottom: 1px solid;border-color: rgba(68, 72, 109, 0.2); border-bottom-right-radius: 0px;border-bottom-left-radius: 0px; background-color: #F9fafb;\">\r\n <div class=\"p-0\">\r\n <h4 class=\"m-0 pt-3 pl-3 mb-3\" style=\"font-size: 21px; font-weight: bold; \">Linked Documents</h4>\r\n </div>\r\n </div>\r\n <div class=\"card mb-0\" style=\"border-top-right-radius: 0px;border-top-left-radius: 0px;\">\r\n @for(document of documentList; track document){\r\n <div class=\"linkedDocument documentName m-2\">\r\n <div class=\"documentName\" [class.selected]=\"document._id === selectedDocument?._id\"\r\n (click)=\"handleDocumentClick(document)\">\r\n <span class=\"pi pi-link\"></span>\r\n {{document.fileName}}\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n \r\n \r\n </div>\r\n ", styles: [".documentName{font-family:inherit;text-decoration:underline;cursor:pointer;width:max-content}.selected{color:var(--primary-color)}\n"] }]
|
|
1419
2628
|
}], propDecorators: { selectedDocument: [{
|
|
@@ -1502,158 +2711,18 @@ class DocumentViewerComponent {
|
|
|
1502
2711
|
ngOnDestroy() {
|
|
1503
2712
|
this.subscription.unsubscribe();
|
|
1504
2713
|
}
|
|
1505
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
1506
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.
|
|
2714
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerComponent, deps: [{ token: DocumentHttpService }, { token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2715
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentViewerComponent, isStandalone: false, selector: "document-viewer", inputs: { selectedDocument: "selectedDocument", documentList: "documentList" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"grid\">\r\n <div class=\"col-12\">\r\n <div class=\"p-fluid p-formgrid grid m-0\">\r\n <div class=\"col-12 md:col-12 md:flex justify-content-evenly\">\r\n @if(selectedDocument){\r\n <div id=\"outerContainer col-12 md:col-7\">\r\n <div\r\n class=\"img-container\"\r\n >\r\n <img\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n class=\"uploadedImages\"\r\n alt=\"Document Image\"\r\n />\r\n </div>\r\n <div class=\"pdf-container\">\r\n <pdf-viewer\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n [rotation]=\"0\"\r\n [original-size]=\"false\"\r\n [show-all]=\"true\"\r\n [fit-to-page]=\"false\"\r\n [zoom]=\"1\"\r\n [zoom-scale]=\"'page-width'\"\r\n [stick-to-page]=\"false\"\r\n [render-text]=\"true\"\r\n [external-link-target]=\"'blank'\"\r\n [autoresize]=\"true\"\r\n [show-borders]=\"false\"\r\n style=\"width: 50vw; height: 75vh\"\r\n ></pdf-viewer>\r\n </div>\r\n <div class=\"incorrect-docType\">\r\n ContentType is incorrect.\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"left-part col-12 md:col-3 pt-0\">\r\n <div class=\"alerts mb-4 pb-1\">\r\n <button\r\n type=\"button\"\r\n *ngIf=\"\r\n (alertData?.status !== 'Pending' && !!alertData?.status) ||\r\n alertData?.isAlert === false\r\n \"\r\n class=\"bg-green-500 border-none border-round-md flex align-items-center mb-3 p-2 px-3\"\r\n >\r\n <i\r\n class=\"pi pi-verified mr-2 cursor-pointer\"\r\n [ngStyle]=\"{\r\n color:\r\n alertData?.status === 'Pending' &&\r\n alertData?.isAlert !== false\r\n ? '#FFFFFF'\r\n : '#8A8EA6'\r\n }\"\r\n style=\"font-size: 20px\"\r\n ></i>\r\n <span class=\"font-semibold text-white\">Verified</span>\r\n </button>\r\n <div\r\n class=\"card mb-0\"\r\n [ngClass]=\"\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? 'alert-card'\r\n : 'success-alert'\r\n \"\r\n >\r\n <div class=\"flex align-items-center mb-2 pb-1\" *ngIf=\"alertData?.status !== 'Verified'\">\r\n <h4 class=\"mr-3 mt-0 mb-0 text-color font-bold\" style=\"font-size: 21px; font-weight: bold; border-color: rgba(68, 72, 109, 0.2) ;\" >Alerts</h4>\r\n <i\r\n class=\"pi pi-exclamation-triangle\"\r\n style=\"font-size: 20px\"\r\n [ngStyle]=\"{\r\n color:\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? '#FB392D'\r\n : '#8A8EA6'\r\n }\"\r\n ></i>\r\n </div>\r\n <p class=\"text-color mb-0\">{{ alertData?.alertMessage }}</p>\r\n </div>\r\n </div>\r\n <ng-content></ng-content>\r\n <app-linked-document (selectedDocumentChange)=\"handleSelectedDocument($event)\" [selectedDocument]=\"selectedDocument\" [documentList]=\"documentList\"></app-linked-document>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".alert-card{background-color:#fb392d1a}.success-alert{border-radius:10px;border:1px solid rgba(251,57,45,.1);background:linear-gradient(0deg,#dedede 0% 100%),#fff}.p-timeline-event-opposite{display:none}.decription{color:#676b89}.textAreaControl textarea{width:100%;resize:vertical;max-width:100%}.document-btn-wrapper .p-button-outlined{color:#f57c00}.document-viewer .p-dialog{width:100%;height:100%;max-height:100%!important;box-shadow:none!important}.document-viewer .p-dialog-header-close-icon{height:20px;width:20px}.document-viewer .p-dialog-header,.document-viewer .p-dialog-content{background-color:#fff;border-radius:0}.uploadedImages{width:95%;height:100%;object-fit:contain}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.PdfViewerComponent, selector: "pdf-viewer", inputs: ["src", "c-maps-url", "page", "render-text", "render-text-mode", "original-size", "show-all", "stick-to-page", "zoom", "zoom-scale", "rotation", "external-link-target", "autoresize", "fit-to-page", "show-borders"], outputs: ["after-load-complete", "page-rendered", "pages-initialized", "text-layer-rendered", "error", "on-progress", "pageChange"] }, { kind: "component", type: LinkedDocumentComponent, selector: "app-linked-document", inputs: ["selectedDocument", "documentList"], outputs: ["selectedDocumentChange"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
1507
2716
|
}
|
|
1508
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
2717
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerComponent, decorators: [{
|
|
1509
2718
|
type: Component,
|
|
1510
|
-
args: [{ selector: 'document-viewer', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"grid\">\r\n <div class=\"col-12\">\r\n <div class=\"p-fluid p-formgrid grid m-0\">\r\n <div class=\"col-12 md:col-12 md:flex justify-content-evenly\">\r\n @if(selectedDocument){\r\n <div id=\"outerContainer col-12 md:col-7\">\r\n <div\r\n
|
|
1511
|
-
}], ctorParameters: () => [{ type: DocumentHttpService }, { type:
|
|
2719
|
+
args: [{ selector: 'document-viewer', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"grid\">\r\n <div class=\"col-12\">\r\n <div class=\"p-fluid p-formgrid grid m-0\">\r\n <div class=\"col-12 md:col-12 md:flex justify-content-evenly\">\r\n @if(selectedDocument){\r\n <div id=\"outerContainer col-12 md:col-7\">\r\n <div\r\n class=\"img-container\"\r\n >\r\n <img\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n class=\"uploadedImages\"\r\n alt=\"Document Image\"\r\n />\r\n </div>\r\n <div class=\"pdf-container\">\r\n <pdf-viewer\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n [rotation]=\"0\"\r\n [original-size]=\"false\"\r\n [show-all]=\"true\"\r\n [fit-to-page]=\"false\"\r\n [zoom]=\"1\"\r\n [zoom-scale]=\"'page-width'\"\r\n [stick-to-page]=\"false\"\r\n [render-text]=\"true\"\r\n [external-link-target]=\"'blank'\"\r\n [autoresize]=\"true\"\r\n [show-borders]=\"false\"\r\n style=\"width: 50vw; height: 75vh\"\r\n ></pdf-viewer>\r\n </div>\r\n <div class=\"incorrect-docType\">\r\n ContentType is incorrect.\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"left-part col-12 md:col-3 pt-0\">\r\n <div class=\"alerts mb-4 pb-1\">\r\n <button\r\n type=\"button\"\r\n *ngIf=\"\r\n (alertData?.status !== 'Pending' && !!alertData?.status) ||\r\n alertData?.isAlert === false\r\n \"\r\n class=\"bg-green-500 border-none border-round-md flex align-items-center mb-3 p-2 px-3\"\r\n >\r\n <i\r\n class=\"pi pi-verified mr-2 cursor-pointer\"\r\n [ngStyle]=\"{\r\n color:\r\n alertData?.status === 'Pending' &&\r\n alertData?.isAlert !== false\r\n ? '#FFFFFF'\r\n : '#8A8EA6'\r\n }\"\r\n style=\"font-size: 20px\"\r\n ></i>\r\n <span class=\"font-semibold text-white\">Verified</span>\r\n </button>\r\n <div\r\n class=\"card mb-0\"\r\n [ngClass]=\"\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? 'alert-card'\r\n : 'success-alert'\r\n \"\r\n >\r\n <div class=\"flex align-items-center mb-2 pb-1\" *ngIf=\"alertData?.status !== 'Verified'\">\r\n <h4 class=\"mr-3 mt-0 mb-0 text-color font-bold\" style=\"font-size: 21px; font-weight: bold; border-color: rgba(68, 72, 109, 0.2) ;\" >Alerts</h4>\r\n <i\r\n class=\"pi pi-exclamation-triangle\"\r\n style=\"font-size: 20px\"\r\n [ngStyle]=\"{\r\n color:\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? '#FB392D'\r\n : '#8A8EA6'\r\n }\"\r\n ></i>\r\n </div>\r\n <p class=\"text-color mb-0\">{{ alertData?.alertMessage }}</p>\r\n </div>\r\n </div>\r\n <ng-content></ng-content>\r\n <app-linked-document (selectedDocumentChange)=\"handleSelectedDocument($event)\" [selectedDocument]=\"selectedDocument\" [documentList]=\"documentList\"></app-linked-document>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".alert-card{background-color:#fb392d1a}.success-alert{border-radius:10px;border:1px solid rgba(251,57,45,.1);background:linear-gradient(0deg,#dedede 0% 100%),#fff}.p-timeline-event-opposite{display:none}.decription{color:#676b89}.textAreaControl textarea{width:100%;resize:vertical;max-width:100%}.document-btn-wrapper .p-button-outlined{color:#f57c00}.document-viewer .p-dialog{width:100%;height:100%;max-height:100%!important;box-shadow:none!important}.document-viewer .p-dialog-header-close-icon{height:20px;width:20px}.document-viewer .p-dialog-header,.document-viewer .p-dialog-content{background-color:#fff;border-radius:0}.uploadedImages{width:95%;height:100%;object-fit:contain}\n"] }]
|
|
2720
|
+
}], ctorParameters: () => [{ type: DocumentHttpService }, { type: DocumentHelperService }], propDecorators: { selectedDocument: [{
|
|
1512
2721
|
type: Input
|
|
1513
2722
|
}], documentList: [{
|
|
1514
2723
|
type: Input
|
|
1515
2724
|
}] } });
|
|
1516
2725
|
|
|
1517
|
-
/**
|
|
1518
|
-
* Service for managing user session details.
|
|
1519
|
-
* @class SessionService
|
|
1520
|
-
* @typedef {SessionService}
|
|
1521
|
-
*/
|
|
1522
|
-
class SessionService {
|
|
1523
|
-
router;
|
|
1524
|
-
/**
|
|
1525
|
-
* Creates an instance of SessionService.
|
|
1526
|
-
* @param {Router} router - Angular Router for navigation.
|
|
1527
|
-
*/
|
|
1528
|
-
constructor(router) {
|
|
1529
|
-
this.router = router;
|
|
1530
|
-
}
|
|
1531
|
-
/**
|
|
1532
|
-
* Retrieves the current user's role from local storage.
|
|
1533
|
-
* @returns {string | null} The user's role, or null if not found.
|
|
1534
|
-
*/
|
|
1535
|
-
getUserRole() {
|
|
1536
|
-
return localStorage.getItem('role');
|
|
1537
|
-
}
|
|
1538
|
-
/**
|
|
1539
|
-
* Stores the user session data in local storage.
|
|
1540
|
-
* @param {any} data - The session data to store.
|
|
1541
|
-
*/
|
|
1542
|
-
setUserSession(data) {
|
|
1543
|
-
localStorage.setItem(SHARED.SESSIONKEY, JSON.stringify(data));
|
|
1544
|
-
}
|
|
1545
|
-
/**
|
|
1546
|
-
* Retrieves the stored user session data.
|
|
1547
|
-
* @returns {any | null} The parsed session data, or null if not found.
|
|
1548
|
-
*/
|
|
1549
|
-
getUserSession() {
|
|
1550
|
-
const sessionData = localStorage.getItem(SHARED.SESSIONKEY);
|
|
1551
|
-
return sessionData ? JSON.parse(sessionData) : null;
|
|
1552
|
-
}
|
|
1553
|
-
/**
|
|
1554
|
-
* Retrieves the user's permissions from the stored session data.
|
|
1555
|
-
* @returns {any | null} The user's permissions, or null if not found.
|
|
1556
|
-
*/
|
|
1557
|
-
getUserPermissions() {
|
|
1558
|
-
const sessionData = localStorage.getItem(SHARED.SESSIONKEY);
|
|
1559
|
-
return sessionData ? JSON.parse(sessionData).permissions : null;
|
|
1560
|
-
}
|
|
1561
|
-
/**
|
|
1562
|
-
* Retrieves the session ID from the stored session data.
|
|
1563
|
-
* @returns {any | null} The session ID, or null if not found.
|
|
1564
|
-
*/
|
|
1565
|
-
getSessionID() {
|
|
1566
|
-
const sessionData = localStorage.getItem(SHARED.SESSIONKEY);
|
|
1567
|
-
console.log(sessionData);
|
|
1568
|
-
if (sessionData) {
|
|
1569
|
-
const sessionId = JSON.parse(sessionData);
|
|
1570
|
-
console.log(sessionId);
|
|
1571
|
-
return sessionId;
|
|
1572
|
-
}
|
|
1573
|
-
return null;
|
|
1574
|
-
}
|
|
1575
|
-
/**
|
|
1576
|
-
* Clears all stored session data from local storage.
|
|
1577
|
-
*/
|
|
1578
|
-
clearSession() {
|
|
1579
|
-
localStorage.clear();
|
|
1580
|
-
}
|
|
1581
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionService, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1582
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionService, providedIn: 'root' });
|
|
1583
|
-
}
|
|
1584
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionService, decorators: [{
|
|
1585
|
-
type: Injectable,
|
|
1586
|
-
args: [{
|
|
1587
|
-
providedIn: 'root'
|
|
1588
|
-
}]
|
|
1589
|
-
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
1590
|
-
|
|
1591
|
-
/**
|
|
1592
|
-
* Directive to conditionally show or hide elements based on user permissions.
|
|
1593
|
-
* @class HasPermissionDirective
|
|
1594
|
-
* @typedef {HasPermissionDirective}
|
|
1595
|
-
*/
|
|
1596
|
-
class HasPermissionDirective {
|
|
1597
|
-
el;
|
|
1598
|
-
renderer;
|
|
1599
|
-
sessionService;
|
|
1600
|
-
/**
|
|
1601
|
-
* The required permission(s) to display the element.
|
|
1602
|
-
* Accepts a single string or an array of strings.
|
|
1603
|
-
* @type {string | string[]}
|
|
1604
|
-
*/
|
|
1605
|
-
permission;
|
|
1606
|
-
/**
|
|
1607
|
-
* Creates an instance of HasPermissionDirective.
|
|
1608
|
-
* @param {ElementRef} el - Reference to the host element.
|
|
1609
|
-
* @param {Renderer2} renderer - Angular Renderer for DOM manipulation.
|
|
1610
|
-
* @param {SessionService} sessionService - Service to retrieve user permissions.
|
|
1611
|
-
*/
|
|
1612
|
-
constructor(el, renderer, sessionService) {
|
|
1613
|
-
this.el = el;
|
|
1614
|
-
this.renderer = renderer;
|
|
1615
|
-
this.sessionService = sessionService;
|
|
1616
|
-
}
|
|
1617
|
-
/**
|
|
1618
|
-
* Lifecycle hook that is called when input properties change.
|
|
1619
|
-
* @param {SimpleChanges} changes - The changes in input properties.
|
|
1620
|
-
*/
|
|
1621
|
-
ngOnChanges(changes) {
|
|
1622
|
-
if (changes['permission']) {
|
|
1623
|
-
this.checkPermission();
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
/**
|
|
1627
|
-
* Checks if the user has the required permission(s).
|
|
1628
|
-
* Hides the element if the permission is not found.
|
|
1629
|
-
*/
|
|
1630
|
-
checkPermission() {
|
|
1631
|
-
const userPermissionsObjects = this.sessionService.getUserPermissions();
|
|
1632
|
-
const userPermissionNames = userPermissionsObjects?.map((perm) => perm.name) || [];
|
|
1633
|
-
const requiredPermissions = Array.isArray(this.permission)
|
|
1634
|
-
? this.permission
|
|
1635
|
-
: [this.permission];
|
|
1636
|
-
const hasPermission = requiredPermissions.some(permission => userPermissionNames.includes(permission));
|
|
1637
|
-
if (!hasPermission) {
|
|
1638
|
-
this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
|
|
1639
|
-
}
|
|
1640
|
-
else {
|
|
1641
|
-
this.renderer.removeStyle(this.el.nativeElement, 'display');
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SessionService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1645
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: HasPermissionDirective, isStandalone: false, selector: "[permission]", inputs: { permission: "permission" }, usesOnChanges: true, ngImport: i0 });
|
|
1646
|
-
}
|
|
1647
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HasPermissionDirective, decorators: [{
|
|
1648
|
-
type: Directive,
|
|
1649
|
-
args: [{
|
|
1650
|
-
selector: '[permission]',
|
|
1651
|
-
standalone: false
|
|
1652
|
-
}]
|
|
1653
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: SessionService }], propDecorators: { permission: [{
|
|
1654
|
-
type: Input
|
|
1655
|
-
}] } });
|
|
1656
|
-
|
|
1657
2726
|
/**
|
|
1658
2727
|
* This component is responsible for displaying and managing a list of documents.
|
|
1659
2728
|
* Provides functionality for file upload, document selection, and dialog management.
|
|
@@ -1664,7 +2733,7 @@ class DocumentListComponent {
|
|
|
1664
2733
|
documentHttpService;
|
|
1665
2734
|
documentQuery;
|
|
1666
2735
|
documentStore;
|
|
1667
|
-
|
|
2736
|
+
documentTableBuilder;
|
|
1668
2737
|
/**
|
|
1669
2738
|
* Represents the context ID for the document list.
|
|
1670
2739
|
* This value is passed from the parent component.
|
|
@@ -1672,6 +2741,16 @@ class DocumentListComponent {
|
|
|
1672
2741
|
* @memberof DocumentListComponent
|
|
1673
2742
|
*/
|
|
1674
2743
|
contextId = SHARED.EMPTY;
|
|
2744
|
+
/**
|
|
2745
|
+
* The document list response data passed from the parent component.
|
|
2746
|
+
* @type {DocumentListResponse[] | null}
|
|
2747
|
+
* @memberof DocumentListComponent
|
|
2748
|
+
*/
|
|
2749
|
+
documentListResponse = null;
|
|
2750
|
+
/**
|
|
2751
|
+
* Subscription to document list response from store
|
|
2752
|
+
*/
|
|
2753
|
+
documentListSubscription = new Subscription();
|
|
1675
2754
|
/**
|
|
1676
2755
|
* Default visibility of the upload button.
|
|
1677
2756
|
* @type {boolean}
|
|
@@ -1690,12 +2769,6 @@ class DocumentListComponent {
|
|
|
1690
2769
|
* @memberof DocumentListComponent
|
|
1691
2770
|
*/
|
|
1692
2771
|
isSidebarVisible = SHARED.FALSE;
|
|
1693
|
-
/**
|
|
1694
|
-
* Default visibility of the Accordion.
|
|
1695
|
-
* @type {boolean}
|
|
1696
|
-
* @memberof DocumentListComponent
|
|
1697
|
-
*/
|
|
1698
|
-
isCollapsed = SHARED.FALSE;
|
|
1699
2772
|
/**
|
|
1700
2773
|
* Default visibility of the messages.
|
|
1701
2774
|
* @type {Message[]}
|
|
@@ -1743,6 +2816,20 @@ class DocumentListComponent {
|
|
|
1743
2816
|
* @type {string | undefined}
|
|
1744
2817
|
*/
|
|
1745
2818
|
fileName;
|
|
2819
|
+
/**
|
|
2820
|
+
* Table data for each category
|
|
2821
|
+
*/
|
|
2822
|
+
categoryTables = [];
|
|
2823
|
+
/**
|
|
2824
|
+
* Document categories from the response
|
|
2825
|
+
*/
|
|
2826
|
+
documentCategories = [];
|
|
2827
|
+
/**
|
|
2828
|
+
* Filter properties
|
|
2829
|
+
*/
|
|
2830
|
+
status = null;
|
|
2831
|
+
category = null;
|
|
2832
|
+
searchKey = null;
|
|
1746
2833
|
/**
|
|
1747
2834
|
* Creates an instance of DocumentListComponent.
|
|
1748
2835
|
* @class
|
|
@@ -1751,17 +2838,19 @@ class DocumentListComponent {
|
|
|
1751
2838
|
* @param {DocumentQuery} documentQuery - The service responsible for geting stored documents.
|
|
1752
2839
|
* @param {DocumentStore} documentStore - The service responsible for storing documents.
|
|
1753
2840
|
*/
|
|
1754
|
-
constructor(documentUploadService, documentHttpService, documentQuery, documentStore) {
|
|
2841
|
+
constructor(documentUploadService, documentHttpService, documentQuery, documentStore, documentTableBuilder) {
|
|
1755
2842
|
this.documentUploadService = documentUploadService;
|
|
1756
2843
|
this.documentHttpService = documentHttpService;
|
|
1757
2844
|
this.documentQuery = documentQuery;
|
|
1758
2845
|
this.documentStore = documentStore;
|
|
2846
|
+
this.documentTableBuilder = documentTableBuilder;
|
|
1759
2847
|
}
|
|
1760
2848
|
/**
|
|
1761
2849
|
* Initializes the component by fetching the document type list.
|
|
1762
2850
|
*/
|
|
1763
2851
|
ngOnInit() {
|
|
1764
2852
|
this.getDocumentTypeList();
|
|
2853
|
+
this.setupDocumentListSubscription();
|
|
1765
2854
|
}
|
|
1766
2855
|
/**
|
|
1767
2856
|
* Handles the click event for file upload.
|
|
@@ -1774,17 +2863,6 @@ class DocumentListComponent {
|
|
|
1774
2863
|
this.documentStore.setMessage(SHARED.EMPTY_ARRAY);
|
|
1775
2864
|
this.isSidebarVisible = SHARED.TRUE;
|
|
1776
2865
|
}
|
|
1777
|
-
/**
|
|
1778
|
-
* Handles the selection of an individual document.
|
|
1779
|
-
* Opens a dialog to display or manage the selected document.
|
|
1780
|
-
* @param {DocumentModel} document - The document that was clicked by the user.
|
|
1781
|
-
* @memberof DocumentListComponent
|
|
1782
|
-
*/
|
|
1783
|
-
handleClickForDocument(document) {
|
|
1784
|
-
this.isdialogVisible = SHARED.TRUE;
|
|
1785
|
-
this.selectedDocument = document;
|
|
1786
|
-
this.fileName = document.fileName;
|
|
1787
|
-
}
|
|
1788
2866
|
/**
|
|
1789
2867
|
* Handles the save click event to update the document's file name.
|
|
1790
2868
|
* This method creates a payload with the updated file name and calls the
|
|
@@ -1799,15 +2877,6 @@ class DocumentListComponent {
|
|
|
1799
2877
|
console.log(`${SHARED.UPDATE_DOCUMENT_NAME} ${this.selectedDocument._id}`);
|
|
1800
2878
|
});
|
|
1801
2879
|
}
|
|
1802
|
-
/**
|
|
1803
|
-
* Closes the dialog and resets the selected document.
|
|
1804
|
-
* @memberof DocumentListComponent
|
|
1805
|
-
*/
|
|
1806
|
-
handleCloseModal() {
|
|
1807
|
-
this.selectedDocument = { _id: SHARED.EMPTY };
|
|
1808
|
-
this.isdialogVisible = SHARED.FALSE;
|
|
1809
|
-
this.onRefresh.emit();
|
|
1810
|
-
}
|
|
1811
2880
|
/**
|
|
1812
2881
|
* Handles the upload action for a document.
|
|
1813
2882
|
* Validates if a document type is selected and logs the result.
|
|
@@ -1820,7 +2889,6 @@ class DocumentListComponent {
|
|
|
1820
2889
|
this.documentQuery.selectMessages().subscribe((message) => {
|
|
1821
2890
|
if (message.length > 0) {
|
|
1822
2891
|
this.messages = message;
|
|
1823
|
-
this.onRefresh.emit();
|
|
1824
2892
|
this.selectedOption = null;
|
|
1825
2893
|
setTimeout(() => {
|
|
1826
2894
|
this.messages = SHARED.EMPTY_ARRAY;
|
|
@@ -1868,36 +2936,344 @@ class DocumentListComponent {
|
|
|
1868
2936
|
handleOpenSideBar(isVisible) {
|
|
1869
2937
|
this.isSidebarVisible = isVisible;
|
|
1870
2938
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
2939
|
+
/**
|
|
2940
|
+
* Builds table data for all document categories
|
|
2941
|
+
*/
|
|
2942
|
+
buildCategoryTables() {
|
|
2943
|
+
this.categoryTables = this.documentTableBuilder.buildDocumentCategoriesTables(this.documentCategories);
|
|
2944
|
+
}
|
|
2945
|
+
/**
|
|
2946
|
+
* Gets completion count for a category
|
|
2947
|
+
*/
|
|
2948
|
+
getCompletionCount(category) {
|
|
2949
|
+
return this.documentTableBuilder.getCompletionCount(category);
|
|
2950
|
+
}
|
|
2951
|
+
/**
|
|
2952
|
+
* Gets pending document count for a category
|
|
2953
|
+
*/
|
|
2954
|
+
getPendingDocumentCount(category) {
|
|
2955
|
+
return this.documentTableBuilder.getPendingDocumentCount(category);
|
|
2956
|
+
}
|
|
2957
|
+
/**
|
|
2958
|
+
* Gets approved document count for a category
|
|
2959
|
+
*/
|
|
2960
|
+
getApprovedDocumentCount(category) {
|
|
2961
|
+
return this.documentTableBuilder.getApprovedDocumentCount(category);
|
|
2962
|
+
}
|
|
2963
|
+
/**
|
|
2964
|
+
* Builds document categories from the API response
|
|
2965
|
+
*/
|
|
2966
|
+
buildDocumentCategories() {
|
|
2967
|
+
console.log('Building document categories with response:', this.documentListResponse);
|
|
2968
|
+
if (!this.documentListResponse) {
|
|
2969
|
+
this.documentCategories = [];
|
|
2970
|
+
this.categoryTables = [];
|
|
2971
|
+
console.log('No document response, clearing tables');
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
this.documentCategories = [...this.documentListResponse];
|
|
2975
|
+
this.categoryTables = this.documentListResponse.map(category => this.documentTableBuilder.buildDocumentTable(category.list));
|
|
2976
|
+
console.log('Built category tables:', this.categoryTables.length);
|
|
2977
|
+
}
|
|
2978
|
+
/**
|
|
2979
|
+
* Sets up subscription to document list response from store
|
|
2980
|
+
*/
|
|
2981
|
+
setupDocumentListSubscription() {
|
|
2982
|
+
this.documentListSubscription.add(this.documentQuery.selectDocumentListResponse().subscribe({
|
|
2983
|
+
next: (response) => {
|
|
2984
|
+
console.log('DocumentListComponent received response:', response);
|
|
2985
|
+
this.documentListResponse = response;
|
|
2986
|
+
this.buildDocumentCategories();
|
|
2987
|
+
},
|
|
2988
|
+
error: (error) => {
|
|
2989
|
+
console.error('Error receiving document list response:', error);
|
|
2990
|
+
}
|
|
2991
|
+
}));
|
|
2992
|
+
}
|
|
2993
|
+
handleTableRowClick(rowData) {
|
|
2994
|
+
this.isdialogVisible = SHARED.TRUE;
|
|
2995
|
+
this.selectedDocument = rowData;
|
|
2996
|
+
}
|
|
2997
|
+
/**
|
|
2998
|
+
* Cleanup subscriptions on component destroy
|
|
2999
|
+
*/
|
|
3000
|
+
ngOnDestroy() {
|
|
3001
|
+
this.documentListSubscription.unsubscribe();
|
|
3002
|
+
}
|
|
3003
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentListComponent, deps: [{ token: DocumentUploadService }, { token: DocumentHttpService }, { token: DocumentQuery }, { token: DocumentStore }, { token: DocumentTableBuilderService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3004
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentListComponent, isStandalone: false, selector: "lib-document-list", inputs: { contextId: "contextId", documentListResponse: "documentListResponse", isUploadButtonVisible: "isUploadButtonVisible", documentList: "documentList", status: "status", category: "category", searchKey: "searchKey" }, ngImport: i0, template: "<div class=\"document-viewer\">\n <p-dialog [(visible)]=\"isdialogVisible\" [modal]=\"true\" \n class=\"w-full h-full document-dailog-wrapper\" [draggable]=\"false\" [closable]=\"true\">\n <document-viewer [selectedDocument]=\"selectedDocument\" [documentList]=\"documentList\">\n <ng-template pTemplate=\"header\">\n <div class=\"w-full flex align-items-center justify-content-between\">\n <input type=\"text\" class=\"w-full border-none bg-white h-3rem file-input-wrapper\" pInputText\n [(ngModel)]=\"fileName\" />\n <button pButton pRipple class=\"mx-3 w-6rem save-btn-wrapper\" label=\"Save\" (click)=\"handleSaveClick()\">\n </button>\n </div>\n </ng-template>\n <ng-content></ng-content>\n </document-viewer>\n </p-dialog>\n</div>\n\n\n<div class=\"document-categories-container\">\n <div class=\"category\" *ngFor=\"let category of documentCategories; let i = index\">\n <div class=\"category-header\">\n <div class=\"category-title\">\n <h3>{{ category.label }} Documents</h3>\n <p class=\"category-description\">{{ category.categoryDescription }}</p>\n </div>\n <div class=\"completion-status\">\n <span class=\"status-badge\">{{ getCompletionCount(category) }} Complete</span>\n </div>\n </div>\n\n <div class=\"table-container\">\n <lib-table-primary \n [tableData]=\"categoryTables[i]\" \n [tableStyle]=\"{ 'min-width': '100%' }\"\n (rowClick)=\"handleTableRowClick($event)\">\n </lib-table-primary>\n </div>\n </div>\n</div>\n<div class=\"grid m-0\">\n <div class=\"col-12 p-0\">\n <p-sidebar [(visible)]=\"isSidebarVisible\" position=\"right\" [styleClass]=\"'right-sidebar'\" class=\"relative\">\n <ng-template pTemplate=\"header\">\n <p-messages [(value)]=\"messages\" [enableService]=\"false\" />\n </ng-template>\n <ng-template pTemplate=\"content\">\n <div class=\"side-bar-con\">\n <lib-document-upload [contextId]=\"contextId\"></lib-document-upload>\n <div class=\"p-fluid\">\n <div class=\"field\">\n <label for=\"city\">Select Folder</label>\n <p-dropdown id=\"city\" optionLabel=\"label\" optionValue=\"value\" [options]=\"options\"\n placeholder=\"Select a Folder\" [(ngModel)]=\"selectedOption\"></p-dropdown>\n </div>\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"footer\" class=\"bg-gray-100 p-0\">\n <div class=\"bg-gray-100 p-4\">\n <p-button label=\"Save\" class=\"p-button-rounded p-button-success save-btn\" (click)=\"handleUploadDocument()\"\n [disabled]=\"!selectedOption\">\n </p-button>\n </div>\n </ng-template>\n </p-sidebar>\n </div>\n</div>", styles: [".document-list-wrapper .p-accordion-header-link{padding:.5rem}.document-list-wrapper .p-sidebar-right,.right-sidebar{width:35%}.document-title-wrapper{font-size:20px;font-weight:700;color:var(--text-color)}.document-input-field{display:flex;flex-direction:column}.document-input-field input{width:100%;height:46px;padding:10px 15px;gap:10px;border-radius:10px;outline:none;border:1px solid rgba(76,98,146,.1019607843);font-size:15px}label{color:#0f1729;font-weight:600}.document-list-dropDown .p-element{padding:10px 0 10px 15px}.document-list-dropDown .p-dropdown{border-radius:10px!important}.side-bar-con{display:flex;flex-direction:column}.save-btn-con{width:100%;border-top:1px solid rgba(76,98,146,.2);background:#4c629214;padding:13px 40px}.save-btn-wrapper{padding:10px 4px}.save-btn .p-button{height:45px!important;width:140px;border-radius:10px}.p-sidebar-footer{padding:0}.file-input-wrapper.p-inputtext:enabled:focus{box-shadow:0 0 0 .2rem #a6d5fa!important}.document-categories-container{padding:1rem;background-color:#f8f9fa;min-height:100vh}.document-categories-container .category{background:#fff;border-radius:8px;margin-bottom:2rem;box-shadow:0 2px 4px #0000001a;overflow:hidden}.document-categories-container .category .category-header{display:flex;justify-content:space-between;align-items:flex-start;padding:1.5rem 1.5rem 1rem;border-bottom:1px solid #e9ecef}.document-categories-container .category .category-header .category-title h3{margin:0 0 .5rem;font-size:1.25rem;font-weight:600;color:#2c3e50}.document-categories-container .category .category-header .category-title .category-description{margin:0;color:#6c757d;font-size:.875rem;line-height:1.4}.document-categories-container .category .category-header .completion-status .status-badge{background-color:#fbbf24;color:#92400e;padding:.375rem .75rem;border-radius:6px;font-size:.75rem;font-weight:500;display:inline-block}.document-categories-container .category .table-container{padding:0}.document-sections-container{padding:1rem;background-color:#f8f9fa;min-height:100vh}.document-sections-container .section{background:#fff;border-radius:8px;margin-bottom:2rem;box-shadow:0 2px 4px #0000001a;overflow:hidden}.document-sections-container .section .section-header{display:flex;justify-content:space-between;align-items:flex-start;padding:1.5rem 1.5rem 1rem;border-bottom:1px solid #e9ecef}.document-sections-container .section .section-header .section-title h3{margin:0 0 .5rem;font-size:1.25rem;font-weight:600;color:#2c3e50}.document-sections-container .section .section-header .section-title .section-description{margin:0;color:#6c757d;font-size:.875rem;line-height:1.4}.document-sections-container .section .section-header .completion-status .status-badge{background-color:#fbbf24;color:#92400e;padding:.375rem .75rem;border-radius:6px;font-size:.75rem;font-weight:500;display:inline-block}.document-sections-container .section .table-container{padding:0}@media (max-width: 768px){.document-categories-container,.document-sections-container{padding:.5rem}.document-categories-container .category .category-header,.document-categories-container .category .section-header,.document-categories-container .section .category-header,.document-categories-container .section .section-header,.document-sections-container .category .category-header,.document-sections-container .category .section-header,.document-sections-container .section .category-header,.document-sections-container .section .section-header{flex-direction:column;gap:1rem;align-items:flex-start}.document-categories-container .category .category-header .completion-status,.document-categories-container .category .section-header .completion-status,.document-categories-container .section .category-header .completion-status,.document-categories-container .section .section-header .completion-status,.document-sections-container .category .category-header .completion-status,.document-sections-container .category .section-header .completion-status,.document-sections-container .section .category-header .completion-status,.document-sections-container .section .section-header .completion-status{align-self:flex-end}}\n"], dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i8.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i8.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i9.Sidebar, selector: "p-sidebar", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: i10.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }, { kind: "directive", type: i11.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i11.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i11.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i12.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: i13.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i14.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "component", type: TablePrimaryComponent, selector: "lib-table-primary", inputs: ["tableData", "showHeader", "tableStyle"], outputs: ["rowClick"] }, { kind: "component", type: DocumentUploadComponent, selector: "lib-document-upload", inputs: ["contextId"] }, { kind: "component", type: DocumentViewerComponent, selector: "document-viewer", inputs: ["selectedDocument", "documentList"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
3005
|
+
}
|
|
3006
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentListComponent, decorators: [{
|
|
3007
|
+
type: Component,
|
|
3008
|
+
args: [{ selector: 'lib-document-list', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-viewer\">\n <p-dialog [(visible)]=\"isdialogVisible\" [modal]=\"true\" \n class=\"w-full h-full document-dailog-wrapper\" [draggable]=\"false\" [closable]=\"true\">\n <document-viewer [selectedDocument]=\"selectedDocument\" [documentList]=\"documentList\">\n <ng-template pTemplate=\"header\">\n <div class=\"w-full flex align-items-center justify-content-between\">\n <input type=\"text\" class=\"w-full border-none bg-white h-3rem file-input-wrapper\" pInputText\n [(ngModel)]=\"fileName\" />\n <button pButton pRipple class=\"mx-3 w-6rem save-btn-wrapper\" label=\"Save\" (click)=\"handleSaveClick()\">\n </button>\n </div>\n </ng-template>\n <ng-content></ng-content>\n </document-viewer>\n </p-dialog>\n</div>\n\n\n<div class=\"document-categories-container\">\n <div class=\"category\" *ngFor=\"let category of documentCategories; let i = index\">\n <div class=\"category-header\">\n <div class=\"category-title\">\n <h3>{{ category.label }} Documents</h3>\n <p class=\"category-description\">{{ category.categoryDescription }}</p>\n </div>\n <div class=\"completion-status\">\n <span class=\"status-badge\">{{ getCompletionCount(category) }} Complete</span>\n </div>\n </div>\n\n <div class=\"table-container\">\n <lib-table-primary \n [tableData]=\"categoryTables[i]\" \n [tableStyle]=\"{ 'min-width': '100%' }\"\n (rowClick)=\"handleTableRowClick($event)\">\n </lib-table-primary>\n </div>\n </div>\n</div>\n<div class=\"grid m-0\">\n <div class=\"col-12 p-0\">\n <p-sidebar [(visible)]=\"isSidebarVisible\" position=\"right\" [styleClass]=\"'right-sidebar'\" class=\"relative\">\n <ng-template pTemplate=\"header\">\n <p-messages [(value)]=\"messages\" [enableService]=\"false\" />\n </ng-template>\n <ng-template pTemplate=\"content\">\n <div class=\"side-bar-con\">\n <lib-document-upload [contextId]=\"contextId\"></lib-document-upload>\n <div class=\"p-fluid\">\n <div class=\"field\">\n <label for=\"city\">Select Folder</label>\n <p-dropdown id=\"city\" optionLabel=\"label\" optionValue=\"value\" [options]=\"options\"\n placeholder=\"Select a Folder\" [(ngModel)]=\"selectedOption\"></p-dropdown>\n </div>\n </div>\n </div>\n </ng-template>\n <ng-template pTemplate=\"footer\" class=\"bg-gray-100 p-0\">\n <div class=\"bg-gray-100 p-4\">\n <p-button label=\"Save\" class=\"p-button-rounded p-button-success save-btn\" (click)=\"handleUploadDocument()\"\n [disabled]=\"!selectedOption\">\n </p-button>\n </div>\n </ng-template>\n </p-sidebar>\n </div>\n</div>", styles: [".document-list-wrapper .p-accordion-header-link{padding:.5rem}.document-list-wrapper .p-sidebar-right,.right-sidebar{width:35%}.document-title-wrapper{font-size:20px;font-weight:700;color:var(--text-color)}.document-input-field{display:flex;flex-direction:column}.document-input-field input{width:100%;height:46px;padding:10px 15px;gap:10px;border-radius:10px;outline:none;border:1px solid rgba(76,98,146,.1019607843);font-size:15px}label{color:#0f1729;font-weight:600}.document-list-dropDown .p-element{padding:10px 0 10px 15px}.document-list-dropDown .p-dropdown{border-radius:10px!important}.side-bar-con{display:flex;flex-direction:column}.save-btn-con{width:100%;border-top:1px solid rgba(76,98,146,.2);background:#4c629214;padding:13px 40px}.save-btn-wrapper{padding:10px 4px}.save-btn .p-button{height:45px!important;width:140px;border-radius:10px}.p-sidebar-footer{padding:0}.file-input-wrapper.p-inputtext:enabled:focus{box-shadow:0 0 0 .2rem #a6d5fa!important}.document-categories-container{padding:1rem;background-color:#f8f9fa;min-height:100vh}.document-categories-container .category{background:#fff;border-radius:8px;margin-bottom:2rem;box-shadow:0 2px 4px #0000001a;overflow:hidden}.document-categories-container .category .category-header{display:flex;justify-content:space-between;align-items:flex-start;padding:1.5rem 1.5rem 1rem;border-bottom:1px solid #e9ecef}.document-categories-container .category .category-header .category-title h3{margin:0 0 .5rem;font-size:1.25rem;font-weight:600;color:#2c3e50}.document-categories-container .category .category-header .category-title .category-description{margin:0;color:#6c757d;font-size:.875rem;line-height:1.4}.document-categories-container .category .category-header .completion-status .status-badge{background-color:#fbbf24;color:#92400e;padding:.375rem .75rem;border-radius:6px;font-size:.75rem;font-weight:500;display:inline-block}.document-categories-container .category .table-container{padding:0}.document-sections-container{padding:1rem;background-color:#f8f9fa;min-height:100vh}.document-sections-container .section{background:#fff;border-radius:8px;margin-bottom:2rem;box-shadow:0 2px 4px #0000001a;overflow:hidden}.document-sections-container .section .section-header{display:flex;justify-content:space-between;align-items:flex-start;padding:1.5rem 1.5rem 1rem;border-bottom:1px solid #e9ecef}.document-sections-container .section .section-header .section-title h3{margin:0 0 .5rem;font-size:1.25rem;font-weight:600;color:#2c3e50}.document-sections-container .section .section-header .section-title .section-description{margin:0;color:#6c757d;font-size:.875rem;line-height:1.4}.document-sections-container .section .section-header .completion-status .status-badge{background-color:#fbbf24;color:#92400e;padding:.375rem .75rem;border-radius:6px;font-size:.75rem;font-weight:500;display:inline-block}.document-sections-container .section .table-container{padding:0}@media (max-width: 768px){.document-categories-container,.document-sections-container{padding:.5rem}.document-categories-container .category .category-header,.document-categories-container .category .section-header,.document-categories-container .section .category-header,.document-categories-container .section .section-header,.document-sections-container .category .category-header,.document-sections-container .category .section-header,.document-sections-container .section .category-header,.document-sections-container .section .section-header{flex-direction:column;gap:1rem;align-items:flex-start}.document-categories-container .category .category-header .completion-status,.document-categories-container .category .section-header .completion-status,.document-categories-container .section .category-header .completion-status,.document-categories-container .section .section-header .completion-status,.document-sections-container .category .category-header .completion-status,.document-sections-container .category .section-header .completion-status,.document-sections-container .section .category-header .completion-status,.document-sections-container .section .section-header .completion-status{align-self:flex-end}}\n"] }]
|
|
3009
|
+
}], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentHttpService }, { type: DocumentQuery }, { type: DocumentStore }, { type: DocumentTableBuilderService }], propDecorators: { contextId: [{
|
|
3010
|
+
type: Input
|
|
3011
|
+
}], documentListResponse: [{
|
|
3012
|
+
type: Input
|
|
3013
|
+
}], isUploadButtonVisible: [{
|
|
3014
|
+
type: Input
|
|
3015
|
+
}], documentList: [{
|
|
3016
|
+
type: Input
|
|
3017
|
+
}], status: [{
|
|
3018
|
+
type: Input
|
|
3019
|
+
}], category: [{
|
|
3020
|
+
type: Input
|
|
3021
|
+
}], searchKey: [{
|
|
3022
|
+
type: Input
|
|
3023
|
+
}] } });
|
|
3024
|
+
|
|
3025
|
+
class DocumentMenuService {
|
|
3026
|
+
documentStore;
|
|
3027
|
+
constructor(documentStore) {
|
|
3028
|
+
this.documentStore = documentStore;
|
|
3029
|
+
}
|
|
3030
|
+
/**
|
|
3031
|
+
* Gets the category name for a given menu item _id
|
|
3032
|
+
* @param menuItemId - The _id of the menu item
|
|
3033
|
+
* @param categories - The list of document categories
|
|
3034
|
+
* @returns The category name or null if not found
|
|
3035
|
+
*/
|
|
3036
|
+
getMenuItemCategory(menuItemId, categories) {
|
|
3037
|
+
for (const category of categories) {
|
|
3038
|
+
if (category.items?.some((menuItem) => menuItem._id === menuItemId)) {
|
|
3039
|
+
return category.label;
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
return null;
|
|
3043
|
+
}
|
|
3044
|
+
/**
|
|
3045
|
+
* Gets the menu item by its _id
|
|
3046
|
+
* @param menuItemId - The _id of the menu item
|
|
3047
|
+
* @param categories - The list of document categories
|
|
3048
|
+
* @returns The menu item or null if not found
|
|
3049
|
+
*/
|
|
3050
|
+
getMenuItemById(menuItemId, categories) {
|
|
3051
|
+
for (const category of categories) {
|
|
3052
|
+
if (category.items) {
|
|
3053
|
+
const item = category.items.find((menuItem) => menuItem._id === menuItemId);
|
|
3054
|
+
if (item) {
|
|
3055
|
+
return item;
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
return null;
|
|
3060
|
+
}
|
|
3061
|
+
/**
|
|
3062
|
+
* Handles user list visibility based on menu item category
|
|
3063
|
+
* @param menuItemId - The _id of the menu item
|
|
3064
|
+
* @param categories - The list of document categories
|
|
3065
|
+
*/
|
|
3066
|
+
handleUserListVisibility(menuItemId, categories) {
|
|
3067
|
+
const category = this.getMenuItemCategory(menuItemId, categories);
|
|
3068
|
+
const menuItem = this.getMenuItemById(menuItemId, categories);
|
|
3069
|
+
if (category === SHARED.APPLICATION) {
|
|
3070
|
+
this.documentStore.setShowUserList(true);
|
|
3071
|
+
}
|
|
3072
|
+
else if (category === SHARED.APPLICANTS) {
|
|
3073
|
+
this.documentStore.setShowUserList(true);
|
|
3074
|
+
}
|
|
3075
|
+
else {
|
|
3076
|
+
this.documentStore.setShowUserList(false);
|
|
3077
|
+
this.documentStore.setSelectedUserId(null);
|
|
3078
|
+
this.documentStore.setSelectedStatus(null);
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
/**
|
|
3082
|
+
* Handles document status based on selected menu item
|
|
3083
|
+
* @param menuItemId - The _id of the selected menu item
|
|
3084
|
+
* @param categories - The list of document categories
|
|
3085
|
+
*/
|
|
3086
|
+
handleDocumentStatus(menuItemId, categories) {
|
|
3087
|
+
const menuItem = this.getMenuItemById(menuItemId, categories);
|
|
3088
|
+
if (menuItem) {
|
|
3089
|
+
// You can add logic here to handle document status based on the selected menu item
|
|
3090
|
+
// For example, filtering documents by status, updating status counts, etc.
|
|
3091
|
+
console.log('Selected menu item:', menuItem.label, 'with status:', menuItem.status);
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
/**
|
|
3095
|
+
* Calculates total documents for a menu item
|
|
3096
|
+
* @param item - The menu item
|
|
3097
|
+
* @returns Total number of documents
|
|
3098
|
+
*/
|
|
3099
|
+
getTotalDocuments(item) {
|
|
3100
|
+
return item.status.Pending + item.status.Reviewing + item.status.Accepted + item.status.Rejected;
|
|
3101
|
+
}
|
|
3102
|
+
/**
|
|
3103
|
+
* Calculates completed documents for a menu item
|
|
3104
|
+
* @param item - The menu item
|
|
3105
|
+
* @returns Number of completed documents
|
|
3106
|
+
*/
|
|
3107
|
+
getCompletedDocuments(item) {
|
|
3108
|
+
return item.status.Accepted;
|
|
3109
|
+
}
|
|
3110
|
+
/**
|
|
3111
|
+
* Gets badge value for a menu item
|
|
3112
|
+
* @param item - The menu item
|
|
3113
|
+
* @returns Badge value string (e.g., "1/2")
|
|
3114
|
+
*/
|
|
3115
|
+
getBadgeValue(item) {
|
|
3116
|
+
const completed = this.getCompletedDocuments(item);
|
|
3117
|
+
const total = this.getTotalDocuments(item);
|
|
3118
|
+
return `${completed}/${total}`;
|
|
3119
|
+
}
|
|
3120
|
+
/**
|
|
3121
|
+
* Gets badge severity based on status
|
|
3122
|
+
* @param item - The menu item
|
|
3123
|
+
* @returns Badge severity for PrimeNG
|
|
3124
|
+
*/
|
|
3125
|
+
getBadgeSeverity(item) {
|
|
3126
|
+
const completed = this.getCompletedDocuments(item);
|
|
3127
|
+
const total = this.getTotalDocuments(item);
|
|
3128
|
+
if (total === 0)
|
|
3129
|
+
return 'info';
|
|
3130
|
+
if (completed === total)
|
|
3131
|
+
return 'success';
|
|
3132
|
+
if (completed > 0)
|
|
3133
|
+
return 'warning';
|
|
3134
|
+
return 'danger';
|
|
3135
|
+
}
|
|
3136
|
+
/**
|
|
3137
|
+
* Checks if badge should be shown for a menu item
|
|
3138
|
+
* @param item - The menu item
|
|
3139
|
+
* @returns True if badge should be shown
|
|
3140
|
+
*/
|
|
3141
|
+
shouldShowBadge(item) {
|
|
3142
|
+
return this.getTotalDocuments(item) > 0;
|
|
3143
|
+
}
|
|
3144
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentMenuService, deps: [{ token: DocumentStore }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3145
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentMenuService, providedIn: 'root' });
|
|
3146
|
+
}
|
|
3147
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentMenuService, decorators: [{
|
|
3148
|
+
type: Injectable,
|
|
3149
|
+
args: [{
|
|
3150
|
+
providedIn: 'root'
|
|
3151
|
+
}]
|
|
3152
|
+
}], ctorParameters: () => [{ type: DocumentStore }] });
|
|
3153
|
+
|
|
3154
|
+
class DocumentsMenuComponent {
|
|
3155
|
+
documentStore;
|
|
3156
|
+
documentQuery;
|
|
3157
|
+
documentMenuService;
|
|
3158
|
+
documentHelperService;
|
|
3159
|
+
catagories = SHARED.EMPTY_ARRAY;
|
|
3160
|
+
applicationNumber = SHARED.EMPTY;
|
|
3161
|
+
contextId = SHARED.EMPTY;
|
|
3162
|
+
selectedMenuItem = null;
|
|
3163
|
+
selectedMenuItemId = null;
|
|
3164
|
+
constructor(documentStore, documentQuery, documentMenuService, documentHelperService) {
|
|
3165
|
+
this.documentStore = documentStore;
|
|
3166
|
+
this.documentQuery = documentQuery;
|
|
3167
|
+
this.documentMenuService = documentMenuService;
|
|
3168
|
+
this.documentHelperService = documentHelperService;
|
|
3169
|
+
}
|
|
3170
|
+
ngOnInit() {
|
|
3171
|
+
this.documentQuery.selectSelectedMenuItem().subscribe(menuItemId => {
|
|
3172
|
+
this.selectedMenuItemId = menuItemId;
|
|
3173
|
+
this.selectedMenuItem = this.findMenuItemLabelById(menuItemId);
|
|
3174
|
+
});
|
|
3175
|
+
}
|
|
3176
|
+
ngOnChanges(changes) {
|
|
3177
|
+
if (changes['catagories'] && this.catagories) {
|
|
3178
|
+
this.updateMenuItemsData();
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
/**
|
|
3182
|
+
* Finds the label of a menu item by its _id
|
|
3183
|
+
* @param id The _id to search for
|
|
3184
|
+
* @returns The label of the menu item or null if not found
|
|
3185
|
+
*/
|
|
3186
|
+
findMenuItemLabelById(id) {
|
|
3187
|
+
if (!id)
|
|
3188
|
+
return null;
|
|
3189
|
+
for (const category of this.catagories) {
|
|
3190
|
+
if (category.items) {
|
|
3191
|
+
const item = category.items.find(item => item._id === id);
|
|
3192
|
+
if (item) {
|
|
3193
|
+
return item.label;
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
return null;
|
|
3198
|
+
}
|
|
3199
|
+
/**
|
|
3200
|
+
* Update menu use catagories
|
|
3201
|
+
*/
|
|
3202
|
+
updateMenuItemsData() {
|
|
3203
|
+
this.catagories.forEach(category => {
|
|
3204
|
+
if (category.items) {
|
|
3205
|
+
category.items.forEach(item => {
|
|
3206
|
+
item.menuData = {
|
|
3207
|
+
totalDocuments: this.documentMenuService.getTotalDocuments(item),
|
|
3208
|
+
completedDocuments: this.documentMenuService.getCompletedDocuments(item),
|
|
3209
|
+
badgeValue: this.documentMenuService.getBadgeValue(item),
|
|
3210
|
+
badgeSeverity: this.documentMenuService.getBadgeSeverity(item),
|
|
3211
|
+
shouldShowBadge: this.documentMenuService.shouldShowBadge(item)
|
|
3212
|
+
};
|
|
3213
|
+
});
|
|
3214
|
+
}
|
|
3215
|
+
});
|
|
3216
|
+
}
|
|
3217
|
+
/**
|
|
3218
|
+
* Handle the menu item click
|
|
3219
|
+
* @param {*} event - Event
|
|
3220
|
+
* @param {DocumentCategoryItem} item - catagory item
|
|
3221
|
+
*/
|
|
3222
|
+
onMenuItemClick(event, item) {
|
|
3223
|
+
if (this.selectedMenuItemId === item._id) {
|
|
3224
|
+
console.log('Deselecting menu item:', item._id);
|
|
3225
|
+
console.log('Using contextId for API call:', this.contextId);
|
|
3226
|
+
this.selectedMenuItem = null;
|
|
3227
|
+
this.selectedMenuItemId = null;
|
|
3228
|
+
this.documentStore.setSelectedMenuItem(null);
|
|
3229
|
+
// Force refresh to get unfiltered results
|
|
3230
|
+
this.documentHelperService.refreshDocumentsWithoutFilters(this.contextId);
|
|
3231
|
+
}
|
|
3232
|
+
else {
|
|
3233
|
+
console.log('Selecting menu item:', item._id);
|
|
3234
|
+
this.selectedMenuItem = item.label;
|
|
3235
|
+
this.selectedMenuItemId = item._id;
|
|
3236
|
+
this.documentStore.setSelectedMenuItem(item._id);
|
|
3237
|
+
this.documentMenuService.handleUserListVisibility(item._id, this.catagories);
|
|
3238
|
+
}
|
|
3239
|
+
}
|
|
3240
|
+
onSelectMenuItem(menuItemId) {
|
|
3241
|
+
const label = this.findMenuItemLabelById(menuItemId);
|
|
3242
|
+
if (label) {
|
|
3243
|
+
this.selectedMenuItem = label;
|
|
3244
|
+
this.selectedMenuItemId = menuItemId;
|
|
3245
|
+
this.documentStore.setSelectedMenuItem(menuItemId);
|
|
3246
|
+
this.documentMenuService.handleUserListVisibility(menuItemId, this.catagories);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
onUnselectMenuItem() {
|
|
3250
|
+
this.selectedMenuItem = null;
|
|
3251
|
+
this.selectedMenuItemId = null;
|
|
3252
|
+
this.documentStore.setSelectedMenuItem(null);
|
|
3253
|
+
// Force refresh to get unfiltered results
|
|
3254
|
+
this.documentHelperService.refreshDocumentsWithoutFilters(this.contextId);
|
|
3255
|
+
}
|
|
3256
|
+
getSelectedMenuItem() {
|
|
3257
|
+
return this.selectedMenuItem;
|
|
3258
|
+
}
|
|
3259
|
+
getSelectedMenuItemId() {
|
|
3260
|
+
return this.selectedMenuItemId;
|
|
3261
|
+
}
|
|
3262
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentsMenuComponent, deps: [{ token: DocumentStore }, { token: DocumentQuery }, { token: DocumentMenuService }, { token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3263
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentsMenuComponent, isStandalone: false, selector: "lib-documents-menu", inputs: { catagories: "catagories", applicationNumber: "applicationNumber", contextId: "contextId" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-sidebar-container h-full\">\r\n <p-card class=\"widget-menu-wrapper h-full\">\r\n <div class=\"flex align-items-center justify-content-between widget-menu-header-wrapper\">\r\n <p class=\"mb-0 application-title-wrapper\">ID - {{applicationNumber}}</p>\r\n <div class=\"expand-icon-wrapper\">\r\n <i class=\"ri-arrow-left-s-line text-primary flex align-items-center justify-content-center w-full h-full\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"widget-menu-container\" >\r\n <div class=\"widget-menu-wrapper h-ful l custom-scroll\">\r\n <p-menu [model]=\"catagories\" styleClass=\"w-full md:w-15rem\">\r\n <ng-template pTemplate=\"submenuheader\" let-item>\r\n <span [style]=\"{\r\n color : '#9EA0B3'\r\n }\">{{ item.label }}</span>\r\n </ng-template>\r\n <ng-template pTemplate=\"item\" let-item>\r\n <a pRipple \r\n class=\"flex align-items-center p-menuitem-link\"\r\n [class.selected-menu-item]=\"selectedMenuItemId === item._id\"\r\n (click)=\"onMenuItemClick($event, item)\">\r\n <span [class]=\"item.icon\" class=\"text-xl\"></span>\r\n <span class=\"ml-2\">{{ item.label }}</span>\r\n <p-badge *ngIf=\"item.menuData?.shouldShowBadge\" \r\n class=\"ml-auto\" \r\n [severity]=\"item.menuData?.badgeSeverity\" \r\n [value]=\"item.menuData?.badgeValue\" />\r\n </a>\r\n </ng-template>\r\n </p-menu>\r\n </div>\r\n </div>\r\n </p-card>\r\n</div>\r\n\r\n ", styles: [".expand-icon-wrapper{border:1px solid var(--primary-color);height:24px;width:24px;border-radius:50%;background:var(--blue-bg-light)}::ng-deep .p-badge.p-badge-success{background-color:#dcfce7;color:#16a34a;font-family:inherit;font-size:12px;font-weight:400;font-style:inherit}::ng-deep .p-badge.p-badge-danger{background-color:#fee2e2;color:#dc2626;font-family:inherit;font-size:12px;font-weight:400;font-style:inherit}::ng-deep .p-badge.p-badge-warning{background-color:#fef3c7;color:#d97706;font-family:inherit;font-size:12px;font-weight:400;font-style:inherit}::ng-deep .p-icon-wrapper{display:none}::ng-deep .p-menu .p-menuitem>.p-menuitem-content .p-menuitem-link{color:#1f2937}@media screen and (min-width: 768px){::ng-deep .md\\:w-15rem{width:100%!important}}::ng-deep .p-menu .p-menuitem:not(p-highlight):not(p-disabled)>.p-menuitem-content:hover{color:#06f!important;background:#0066ff1a!important;background-color:#0066ff1a!important}::ng-deep .p-menu{border:none}::ng-deep .custom-scroll{scrollbar-gutter:inherit}::ng-deep .selected-menu-item{background-color:#0066ff1a!important;color:var(--primary-color)!important;border:1px solid rgba(68,72,109,.1)!important;border-radius:10px!important}::ng-deep .selected-menu-item .text-xl{color:var(--primary-color)!important}::ng-deep .selected-menu-item span{color:var(--primary-color)!important}::ng-deep .p-panelmenu .p-panelmenu-content{border:none!important}.application-title-wrapper{color:#9ea0b3;font-weight:500}.widget-menu-wrapper{margin-top:8px}.widget-menu-header-wrapper{padding:4px 4px 4px 16px}.widget-menu-container{height:calc(100% - 38px)}.custom-scroll{overflow-y:hidden;scrollbar-gutter:stable}.custom-scroll:hover{overflow-y:auto}::ng-deep .document-sidebar-container .p-card{height:100%;box-shadow:none}::ng-deep .document-sidebar-container .p-card .p-card-content{height:100%;padding:0!important}::ng-deep .document-sidebar-container .p-card .p-card-body{height:100%;width:100%;padding:12px 8px;border-radius:10px;border:1px solid #e5e7eb}::ng-deep .document-sidebar-container .widget-menu-wrapper .p-panelmenu-panel .p-panelmenu-expanded .p-panelmenu-content{border:none!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content{border:none;color:var(--text-color);font-weight:400!important;background-color:var(--surface-0)!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action{color:var(--text-color);font-weight:400!important;position:relative;padding:12px}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action .p-icon-wrapper{position:absolute;right:0;top:16px;margin-right:7px;transform:rotate(90deg)!important;transition:none!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action .p-menuitem-text{max-width:75%;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;word-break:break-all}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-menuitem-link-active{border:1px solid rgba(68,72,109,.1);border-radius:10px;padding:12px;color:var(--primary-color);background-color:#0066ff1a!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-menuitem-link-active .p-menuitem-icon{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-menuitem-link-active .p-menuitem-text{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .company-action-wrapper:not(.p-disabled).p-highlight .p-panelmenu-header-content{margin:12px 0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .no-highlight.p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content{background-color:transparent!important;border-radius:10px;padding:12px;border-bottom:0!important;border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .no-highlight.p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content .p-panelmenu-header-action{padding:0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .no-highlight.p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content .p-panelmenu-header-action .p-icon-wrapper{transform:rotate(180deg)!important;transition:none!important;top:0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link{background-color:var(--surface-0)!important;color:var(--text-color);padding:12px 6px!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link .p-menuitem-text{max-width:75%;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;word-break:break-all}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link-active{border:1px solid rgba(68,72,109,.1);border-radius:10px;padding:12px;color:var(--primary-color);box-shadow:none!important;background-color:#0066ff1a!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link-active .p-menuitem-icon{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link-active .p-menuitem-text{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem.p-focus>.p-menuitem-content{background-color:#44486d1a!important}::ng-deep .widget-menu-wrapper .p-panelmenu-panel .p-panelmenu-expanded .p-panelmenu-content{border:1px solid rgba(68,72,109,.1)!important;border-top:0!important;border-bottom-left-radius:10px;border-bottom-right-radius:10px}::ng-deep .widget-menu-wrapper .p-panelmenu-panel .widget-separator{border-top:1px solid rgba(68,72,109,.1)!important}::ng-deep .widget-menu-wrapper .p-panelmenu-panel .widget-separator .p-panelmenu-header-content .p-panelmenu-header-action{padding:0!important}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i7$1.Badge, selector: "p-badge", inputs: ["styleClass", "style", "badgeSize", "severity", "value", "badgeDisabled", "size"] }, { kind: "component", type: i8$2.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "component", type: i9$1.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }] });
|
|
3264
|
+
}
|
|
3265
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentsMenuComponent, decorators: [{
|
|
3266
|
+
type: Component,
|
|
3267
|
+
args: [{ selector: 'lib-documents-menu', standalone: false, template: "<div class=\"document-sidebar-container h-full\">\r\n <p-card class=\"widget-menu-wrapper h-full\">\r\n <div class=\"flex align-items-center justify-content-between widget-menu-header-wrapper\">\r\n <p class=\"mb-0 application-title-wrapper\">ID - {{applicationNumber}}</p>\r\n <div class=\"expand-icon-wrapper\">\r\n <i class=\"ri-arrow-left-s-line text-primary flex align-items-center justify-content-center w-full h-full\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"widget-menu-container\" >\r\n <div class=\"widget-menu-wrapper h-ful l custom-scroll\">\r\n <p-menu [model]=\"catagories\" styleClass=\"w-full md:w-15rem\">\r\n <ng-template pTemplate=\"submenuheader\" let-item>\r\n <span [style]=\"{\r\n color : '#9EA0B3'\r\n }\">{{ item.label }}</span>\r\n </ng-template>\r\n <ng-template pTemplate=\"item\" let-item>\r\n <a pRipple \r\n class=\"flex align-items-center p-menuitem-link\"\r\n [class.selected-menu-item]=\"selectedMenuItemId === item._id\"\r\n (click)=\"onMenuItemClick($event, item)\">\r\n <span [class]=\"item.icon\" class=\"text-xl\"></span>\r\n <span class=\"ml-2\">{{ item.label }}</span>\r\n <p-badge *ngIf=\"item.menuData?.shouldShowBadge\" \r\n class=\"ml-auto\" \r\n [severity]=\"item.menuData?.badgeSeverity\" \r\n [value]=\"item.menuData?.badgeValue\" />\r\n </a>\r\n </ng-template>\r\n </p-menu>\r\n </div>\r\n </div>\r\n </p-card>\r\n</div>\r\n\r\n ", styles: [".expand-icon-wrapper{border:1px solid var(--primary-color);height:24px;width:24px;border-radius:50%;background:var(--blue-bg-light)}::ng-deep .p-badge.p-badge-success{background-color:#dcfce7;color:#16a34a;font-family:inherit;font-size:12px;font-weight:400;font-style:inherit}::ng-deep .p-badge.p-badge-danger{background-color:#fee2e2;color:#dc2626;font-family:inherit;font-size:12px;font-weight:400;font-style:inherit}::ng-deep .p-badge.p-badge-warning{background-color:#fef3c7;color:#d97706;font-family:inherit;font-size:12px;font-weight:400;font-style:inherit}::ng-deep .p-icon-wrapper{display:none}::ng-deep .p-menu .p-menuitem>.p-menuitem-content .p-menuitem-link{color:#1f2937}@media screen and (min-width: 768px){::ng-deep .md\\:w-15rem{width:100%!important}}::ng-deep .p-menu .p-menuitem:not(p-highlight):not(p-disabled)>.p-menuitem-content:hover{color:#06f!important;background:#0066ff1a!important;background-color:#0066ff1a!important}::ng-deep .p-menu{border:none}::ng-deep .custom-scroll{scrollbar-gutter:inherit}::ng-deep .selected-menu-item{background-color:#0066ff1a!important;color:var(--primary-color)!important;border:1px solid rgba(68,72,109,.1)!important;border-radius:10px!important}::ng-deep .selected-menu-item .text-xl{color:var(--primary-color)!important}::ng-deep .selected-menu-item span{color:var(--primary-color)!important}::ng-deep .p-panelmenu .p-panelmenu-content{border:none!important}.application-title-wrapper{color:#9ea0b3;font-weight:500}.widget-menu-wrapper{margin-top:8px}.widget-menu-header-wrapper{padding:4px 4px 4px 16px}.widget-menu-container{height:calc(100% - 38px)}.custom-scroll{overflow-y:hidden;scrollbar-gutter:stable}.custom-scroll:hover{overflow-y:auto}::ng-deep .document-sidebar-container .p-card{height:100%;box-shadow:none}::ng-deep .document-sidebar-container .p-card .p-card-content{height:100%;padding:0!important}::ng-deep .document-sidebar-container .p-card .p-card-body{height:100%;width:100%;padding:12px 8px;border-radius:10px;border:1px solid #e5e7eb}::ng-deep .document-sidebar-container .widget-menu-wrapper .p-panelmenu-panel .p-panelmenu-expanded .p-panelmenu-content{border:none!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content{border:none;color:var(--text-color);font-weight:400!important;background-color:var(--surface-0)!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action{color:var(--text-color);font-weight:400!important;position:relative;padding:12px}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action .p-icon-wrapper{position:absolute;right:0;top:16px;margin-right:7px;transform:rotate(90deg)!important;transition:none!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-panelmenu-header-action .p-menuitem-text{max-width:75%;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;word-break:break-all}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-menuitem-link-active{border:1px solid rgba(68,72,109,.1);border-radius:10px;padding:12px;color:var(--primary-color);background-color:#0066ff1a!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-menuitem-link-active .p-menuitem-icon{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-header .p-panelmenu-header-content .p-menuitem-link-active .p-menuitem-text{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .company-action-wrapper:not(.p-disabled).p-highlight .p-panelmenu-header-content{margin:12px 0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .no-highlight.p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content{background-color:transparent!important;border-radius:10px;padding:12px;border-bottom:0!important;border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .no-highlight.p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content .p-panelmenu-header-action{padding:0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .no-highlight.p-panelmenu-header:not(.p-disabled).p-highlight .p-panelmenu-header-content .p-panelmenu-header-action .p-icon-wrapper{transform:rotate(180deg)!important;transition:none!important;top:0!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link{background-color:var(--surface-0)!important;color:var(--text-color);padding:12px 6px!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link .p-menuitem-text{max-width:75%;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;word-break:break-all}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link-active{border:1px solid rgba(68,72,109,.1);border-radius:10px;padding:12px;color:var(--primary-color);box-shadow:none!important;background-color:#0066ff1a!important}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link-active .p-menuitem-icon{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem>.p-menuitem-content .p-menuitem-link-active .p-menuitem-text{color:var(--primary-color)}::ng-deep .widget-menu-wrapper .p-panelmenu .p-panelmenu-content .p-menuitem.p-focus>.p-menuitem-content{background-color:#44486d1a!important}::ng-deep .widget-menu-wrapper .p-panelmenu-panel .p-panelmenu-expanded .p-panelmenu-content{border:1px solid rgba(68,72,109,.1)!important;border-top:0!important;border-bottom-left-radius:10px;border-bottom-right-radius:10px}::ng-deep .widget-menu-wrapper .p-panelmenu-panel .widget-separator{border-top:1px solid rgba(68,72,109,.1)!important}::ng-deep .widget-menu-wrapper .p-panelmenu-panel .widget-separator .p-panelmenu-header-content .p-panelmenu-header-action{padding:0!important}\n"] }]
|
|
3268
|
+
}], ctorParameters: () => [{ type: DocumentStore }, { type: DocumentQuery }, { type: DocumentMenuService }, { type: DocumentHelperService }], propDecorators: { catagories: [{
|
|
3269
|
+
type: Input
|
|
3270
|
+
}], applicationNumber: [{
|
|
3271
|
+
type: Input
|
|
3272
|
+
}], contextId: [{
|
|
3273
|
+
type: Input
|
|
3274
|
+
}] } });
|
|
3275
|
+
|
|
3276
|
+
/**
|
|
1901
3277
|
*This component is responsible for managing and displaying a list of documents.
|
|
1902
3278
|
* @class DocumentContainerComponent
|
|
1903
3279
|
* @typedef {DocumentContainerComponent}
|
|
@@ -1907,6 +3283,7 @@ class DocumentContainerComponent {
|
|
|
1907
3283
|
documentService;
|
|
1908
3284
|
documentQuery;
|
|
1909
3285
|
documentHttpService;
|
|
3286
|
+
documentHelperService;
|
|
1910
3287
|
/**
|
|
1911
3288
|
* Creates an instance of DocumentContainerComponent.
|
|
1912
3289
|
* @param {DocumentStore} documentStore - Query Store service to manage store document-related state.
|
|
@@ -1914,11 +3291,14 @@ class DocumentContainerComponent {
|
|
|
1914
3291
|
* @param {DocumentQuery} documentQuery - Query service to manage document-related state.
|
|
1915
3292
|
* @param {DocumentHttpService} documentHttpService - Service to make HTTP requests related to documents.
|
|
1916
3293
|
*/
|
|
1917
|
-
constructor(documentStore, documentService, documentQuery, documentHttpService) {
|
|
3294
|
+
constructor(documentStore, documentService, documentQuery, documentHttpService, documentHelperService) {
|
|
3295
|
+
// Note: initializeSelectionWatcher now requires contextId
|
|
3296
|
+
// This should be called from the component that has access to contextId
|
|
1918
3297
|
this.documentStore = documentStore;
|
|
1919
3298
|
this.documentService = documentService;
|
|
1920
3299
|
this.documentQuery = documentQuery;
|
|
1921
3300
|
this.documentHttpService = documentHttpService;
|
|
3301
|
+
this.documentHelperService = documentHelperService;
|
|
1922
3302
|
}
|
|
1923
3303
|
/**
|
|
1924
3304
|
* Get contextId in input.
|
|
@@ -1926,30 +3306,22 @@ class DocumentContainerComponent {
|
|
|
1926
3306
|
*/
|
|
1927
3307
|
contextId = SHARED.EMPTY;
|
|
1928
3308
|
/**
|
|
1929
|
-
*
|
|
1930
|
-
* @type {
|
|
1931
|
-
*/
|
|
1932
|
-
isCollapsed = SHARED.FALSE;
|
|
1933
|
-
/**
|
|
1934
|
-
* Get showFolderList in input.
|
|
1935
|
-
* @type {boolean}
|
|
1936
|
-
*/
|
|
1937
|
-
showFolderList = SHARED.TRUE;
|
|
1938
|
-
/**
|
|
1939
|
-
* Get isUploadButtonVisible in input.
|
|
1940
|
-
* @type {boolean}
|
|
3309
|
+
* The list of folders.
|
|
3310
|
+
* @type {Array}
|
|
1941
3311
|
*/
|
|
1942
|
-
|
|
3312
|
+
applicationNumber = SHARED.EMPTY;
|
|
3313
|
+
catagories = SHARED.EMPTY_ARRAY;
|
|
3314
|
+
userList = SHARED.EMPTY_ARRAY;
|
|
1943
3315
|
/**
|
|
1944
|
-
*
|
|
1945
|
-
* @type {
|
|
3316
|
+
* Status data for the current selection
|
|
3317
|
+
* @type {StatusDataModel[]}
|
|
1946
3318
|
*/
|
|
1947
|
-
|
|
3319
|
+
statusData = [];
|
|
1948
3320
|
/**
|
|
1949
|
-
*
|
|
1950
|
-
* @type {
|
|
3321
|
+
* Document list response from API
|
|
3322
|
+
* @type {DocumentListResponse | null}
|
|
1951
3323
|
*/
|
|
1952
|
-
|
|
3324
|
+
documentListResponse = null;
|
|
1953
3325
|
/**
|
|
1954
3326
|
* Holds the subscription to manage observable cleanup.
|
|
1955
3327
|
* @private
|
|
@@ -1961,88 +3333,88 @@ class DocumentContainerComponent {
|
|
|
1961
3333
|
* @returns {void}
|
|
1962
3334
|
*/
|
|
1963
3335
|
ngOnInit() {
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
const idToFetch = folderBlockId ?? validFolders[0]?._id;
|
|
1970
|
-
if (idToFetch) {
|
|
1971
|
-
// this.fetchDocuments(idToFetch);
|
|
1972
|
-
}
|
|
1973
|
-
else {
|
|
1974
|
-
console.warn('No folders with documents available.');
|
|
1975
|
-
}
|
|
1976
|
-
});
|
|
1977
|
-
this.subscription.add(folderSubscription);
|
|
3336
|
+
this.fetchDocumentCatagories();
|
|
3337
|
+
this.fetchUserList();
|
|
3338
|
+
this.setupStatusDataSubscriptions();
|
|
3339
|
+
this.setupFilteredDocumentSubscription();
|
|
3340
|
+
this.documentHelperService.initializeSelectionWatcherWithInitialLoad(this.contextId);
|
|
1978
3341
|
}
|
|
1979
3342
|
/**
|
|
1980
|
-
*
|
|
1981
|
-
*
|
|
3343
|
+
* Sets up subscriptions to monitor menu item and user selection changes
|
|
3344
|
+
* to trigger status data fetching
|
|
1982
3345
|
*/
|
|
3346
|
+
setupStatusDataSubscriptions() {
|
|
3347
|
+
this.subscription.add(this.documentQuery.selectSelectedMenuItem().subscribe(menuItem => {
|
|
3348
|
+
this.fetchStatusData();
|
|
3349
|
+
}));
|
|
3350
|
+
this.subscription.add(this.documentQuery.selectSelectedUserId().subscribe(userId => {
|
|
3351
|
+
this.fetchStatusData();
|
|
3352
|
+
}));
|
|
3353
|
+
this.fetchStatusData();
|
|
3354
|
+
}
|
|
1983
3355
|
/**
|
|
1984
|
-
* Fetches
|
|
1985
|
-
* @returns {void}
|
|
3356
|
+
* Fetches status data based on current selections
|
|
1986
3357
|
*/
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
3358
|
+
fetchStatusData() {
|
|
3359
|
+
if (!this.contextId) {
|
|
3360
|
+
console.warn('Context ID is required to fetch status data');
|
|
3361
|
+
return;
|
|
3362
|
+
}
|
|
3363
|
+
const currentState = this.documentQuery.getSelectionState();
|
|
3364
|
+
const contextId = currentState.userId || this.contextId;
|
|
3365
|
+
const categoryId = currentState.menuItem || null;
|
|
3366
|
+
this.documentHttpService.getStatusDocumentCount(this.contextId, contextId, categoryId).subscribe({
|
|
3367
|
+
next: (statusData) => {
|
|
3368
|
+
this.statusData = statusData;
|
|
3369
|
+
this.documentStore.setStatusData(statusData);
|
|
3370
|
+
},
|
|
3371
|
+
error: (error) => {
|
|
3372
|
+
console.error('Error fetching status data:', error);
|
|
3373
|
+
}
|
|
3374
|
+
});
|
|
3375
|
+
}
|
|
3376
|
+
/**
|
|
3377
|
+
* Fetches document catagory data.
|
|
3378
|
+
*/
|
|
3379
|
+
fetchDocumentCatagories() {
|
|
3380
|
+
const categoriesSubscription = this.documentHttpService.getDocumentCatagories(this.contextId).subscribe({
|
|
3381
|
+
next: (categories) => {
|
|
3382
|
+
if (categories) {
|
|
3383
|
+
this.catagories = categories.categories;
|
|
3384
|
+
this.applicationNumber = categories.applicationNumber;
|
|
2005
3385
|
}
|
|
2006
3386
|
},
|
|
2007
|
-
/**
|
|
2008
|
-
* Handles errors if the request fails.
|
|
2009
|
-
* @param {any} err - The error object returned by the server.
|
|
2010
|
-
*/
|
|
2011
3387
|
error: (err) => {
|
|
2012
|
-
console.error(
|
|
3388
|
+
console.error('Error fetching document categories:', err);
|
|
2013
3389
|
}
|
|
2014
3390
|
});
|
|
2015
|
-
this.subscription.add(
|
|
3391
|
+
this.subscription.add(categoriesSubscription);
|
|
2016
3392
|
}
|
|
2017
3393
|
/**
|
|
2018
|
-
* Fetches
|
|
2019
|
-
* @param {string} folderBlockId - The folder ID to fetch the document.
|
|
2020
|
-
* @returns {void}
|
|
3394
|
+
* Fetches userlist data
|
|
2021
3395
|
*/
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
* @param {DocumentModel[]} documentList - The list of documents returned by the API.
|
|
2027
|
-
*/
|
|
2028
|
-
next: (documentList) => {
|
|
2029
|
-
if (documentList) {
|
|
2030
|
-
this.documentList = documentList;
|
|
2031
|
-
this.documentStore.setDocumentList(documentList);
|
|
2032
|
-
}
|
|
2033
|
-
else {
|
|
2034
|
-
console.error(ERRORS.ERROR_FETCHING_DOCUMENTS);
|
|
2035
|
-
}
|
|
3396
|
+
fetchUserList() {
|
|
3397
|
+
this.documentHttpService.getUserListByContextId(this.contextId).subscribe({
|
|
3398
|
+
next: (res) => {
|
|
3399
|
+
this.userList = res;
|
|
2036
3400
|
},
|
|
2037
|
-
/**
|
|
2038
|
-
* Handles errors if the request fails.
|
|
2039
|
-
* @param {any} err - The error object returned by the server.
|
|
2040
|
-
*/
|
|
2041
3401
|
error: (err) => {
|
|
2042
|
-
console.
|
|
3402
|
+
console.log(err);
|
|
2043
3403
|
}
|
|
2044
3404
|
});
|
|
2045
|
-
|
|
3405
|
+
}
|
|
3406
|
+
/**
|
|
3407
|
+
* Sets up subscription to listen for filtered document responses
|
|
3408
|
+
*/
|
|
3409
|
+
setupFilteredDocumentSubscription() {
|
|
3410
|
+
this.subscription.add(this.documentQuery.selectDocumentListResponse().subscribe({
|
|
3411
|
+
next: (response) => {
|
|
3412
|
+
this.documentListResponse = response;
|
|
3413
|
+
},
|
|
3414
|
+
error: (error) => {
|
|
3415
|
+
console.error('Error receiving filtered documents:', error);
|
|
3416
|
+
}
|
|
3417
|
+
}));
|
|
2046
3418
|
}
|
|
2047
3419
|
/**
|
|
2048
3420
|
* Unsubscribe subscription on destroy of component .
|
|
@@ -2050,19 +3422,102 @@ class DocumentContainerComponent {
|
|
|
2050
3422
|
ngOnDestroy() {
|
|
2051
3423
|
this.subscription.unsubscribe();
|
|
2052
3424
|
}
|
|
2053
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2054
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3425
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentContainerComponent, deps: [{ token: DocumentStore }, { token: DocumentService }, { token: DocumentQuery }, { token: DocumentHttpService }, { token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3426
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentContainerComponent, isStandalone: false, selector: "lib-document-container", inputs: { contextId: "contextId" }, ngImport: i0, template: "<div class=\"grid m-0 h-full flex\">\r\n <div class=\"col-12 md:col-3 lg:col-3\">\r\n <lib-documents-menu [catagories]=\"catagories\" [applicationNumber]=\"applicationNumber\" [contextId]=\"contextId\"></lib-documents-menu>\r\n </div>\r\n <div class=\"col-12 md:col-9 lg:col-9 p-0 h-full\" >\r\n <div>\r\n <lib-folder-container [contextId]=\"contextId\" [userList]=\"userList\" [statusData]=\"statusData\" [categories]=\"catagories\"></lib-folder-container>\r\n </div>\r\n <div >\r\n <lib-document-list [contextId]=\"contextId\" [documentListResponse]=\"documentListResponse\">\r\n <ng-content></ng-content>\r\n </lib-document-list>\r\n </div>\r\n </div>\r\n</div>", styles: [".custom-scroll{overflow-y:hidden;scrollbar-gutter:stable}.custom-scroll:hover{overflow-y:auto}\n"], dependencies: [{ kind: "component", type: FolderContainerComponent, selector: "lib-folder-container", inputs: ["documentList", "folderList", "contextId", "userList", "statusData", "categories"] }, { kind: "component", type: DocumentListComponent, selector: "lib-document-list", inputs: ["contextId", "documentListResponse", "isUploadButtonVisible", "documentList", "status", "category", "searchKey"] }, { kind: "component", type: DocumentsMenuComponent, selector: "lib-documents-menu", inputs: ["catagories", "applicationNumber", "contextId"] }] });
|
|
2055
3427
|
}
|
|
2056
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
3428
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentContainerComponent, decorators: [{
|
|
2057
3429
|
type: Component,
|
|
2058
|
-
args: [{ selector: 'lib-document-container', standalone: false, template: "<div class=\"grid m-0 h-full flex\">\r\n
|
|
2059
|
-
}], ctorParameters: () => [{ type: DocumentStore }, { type: DocumentService
|
|
2060
|
-
type: Input
|
|
2061
|
-
}], isCollapsed: [{
|
|
3430
|
+
args: [{ selector: 'lib-document-container', standalone: false, template: "<div class=\"grid m-0 h-full flex\">\r\n <div class=\"col-12 md:col-3 lg:col-3\">\r\n <lib-documents-menu [catagories]=\"catagories\" [applicationNumber]=\"applicationNumber\" [contextId]=\"contextId\"></lib-documents-menu>\r\n </div>\r\n <div class=\"col-12 md:col-9 lg:col-9 p-0 h-full\" >\r\n <div>\r\n <lib-folder-container [contextId]=\"contextId\" [userList]=\"userList\" [statusData]=\"statusData\" [categories]=\"catagories\"></lib-folder-container>\r\n </div>\r\n <div >\r\n <lib-document-list [contextId]=\"contextId\" [documentListResponse]=\"documentListResponse\">\r\n <ng-content></ng-content>\r\n </lib-document-list>\r\n </div>\r\n </div>\r\n</div>", styles: [".custom-scroll{overflow-y:hidden;scrollbar-gutter:stable}.custom-scroll:hover{overflow-y:auto}\n"] }]
|
|
3431
|
+
}], ctorParameters: () => [{ type: DocumentStore }, { type: DocumentService }, { type: DocumentQuery }, { type: DocumentHttpService }, { type: DocumentHelperService }], propDecorators: { contextId: [{
|
|
2062
3432
|
type: Input
|
|
2063
|
-
}]
|
|
3433
|
+
}] } });
|
|
3434
|
+
|
|
3435
|
+
/**
|
|
3436
|
+
* The `FolderBlockComponent` is responsible for displaying a block of folders and
|
|
3437
|
+
* providing filtering functionality based on folder IDs.
|
|
3438
|
+
*
|
|
3439
|
+
* It uses data from the `DocumentStore` and constants from the `SHARED` configuration
|
|
3440
|
+
* to display missing and pending file counts.
|
|
3441
|
+
*/
|
|
3442
|
+
class FolderBlockComponent {
|
|
3443
|
+
documentStore;
|
|
3444
|
+
/**
|
|
3445
|
+
* Array of folder blocks data to display.
|
|
3446
|
+
* Each folder is represented as a `FolderBlockModel`.
|
|
3447
|
+
*/
|
|
3448
|
+
folderList = SHARED.EMPTY_ARRAY;
|
|
3449
|
+
/** Number of missing files, sourced from the `SHARED` constants. */
|
|
3450
|
+
missingFileCount = SHARED.MISSINGCOUNT;
|
|
3451
|
+
/** Number of pending files, sourced from the `SHARED` constants. */
|
|
3452
|
+
pendingFileCount = SHARED.PENDINGCOUNT;
|
|
3453
|
+
/**
|
|
3454
|
+
* Injects the `DocumentStore` service to manage and access document-related state.
|
|
3455
|
+
* @param {DocumentStore} documentStore - The state management store for documents.
|
|
3456
|
+
*/
|
|
3457
|
+
constructor(documentStore) {
|
|
3458
|
+
this.documentStore = documentStore;
|
|
3459
|
+
}
|
|
3460
|
+
/**
|
|
3461
|
+
* Handles the click event for filtering based on the provided folder ID.
|
|
3462
|
+
* This method validates the folder ID and returns it for further processing.
|
|
3463
|
+
* If the folder ID is not provided, an empty string is returned.
|
|
3464
|
+
* @param {string} folderBlockId - The unique identifier of the folder to filter by.
|
|
3465
|
+
* @returns {string} The validated folder ID, or an empty string if the input is invalid.
|
|
3466
|
+
*/
|
|
3467
|
+
handleClickForFilter(folderBlockId) {
|
|
3468
|
+
if (!folderBlockId) {
|
|
3469
|
+
return SHARED.EMPTY;
|
|
3470
|
+
}
|
|
3471
|
+
this.documentStore.setParentDocumentTypeId(folderBlockId);
|
|
3472
|
+
return folderBlockId;
|
|
3473
|
+
}
|
|
3474
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderBlockComponent, deps: [{ token: DocumentStore }], target: i0.ɵɵFactoryTarget.Component });
|
|
3475
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FolderBlockComponent, isStandalone: false, selector: "lib-folder-block", inputs: { folderList: "folderList" }, ngImport: i0, template: "<div class=\"card p-0 folder-info\">\r\n <div class=\"text-900 text-xl font-semibold ml-2 mb-1\">Folders</div>\r\n <div class=\"grid m-0\">\r\n <div *ngFor=\"let folder of folderList\" class=\"col-12 md:col-6 xl:col-4 container-wrapper\">\r\n <div\r\n class=\"p-3 border-1 h-full surface-border flex flex-column justify-content-between hover:surface-100 cursor-pointer border-round\"\r\n (click)=\"handleClickForFilter(folder._id)\"\r\n >\r\n <div class=\"icon\">\r\n <img src=\"../../../../assets/images/FolderImg.png\" alt=\"\" />\r\n </div>\r\n <div class=\"flex flex-column\">\r\n <span class=\"text-600 mt-2\"> {{ folder.documentCount }} Files </span>\r\n <span class=\"text-900 text-lg mt-2 mb-2 font-semibold font-medium\">\r\n {{ folder.folderName }}\r\n </span>\r\n </div>\r\n <hr />\r\n <div class=\"flex justify-content-between\">\r\n <div class=\"flex flex-column\">\r\n <span>Missing</span>\r\n <span\r\n [ngClass]=\"{\r\n 'text-pink-500': missingFileCount > 0,\r\n 'text-green-500': missingFileCount === 0\r\n }\"\r\n >\r\n {{ missingFileCount }}\r\n </span>\r\n </div>\r\n <div class=\"flex flex-column\">\r\n <span>Pending</span>\r\n <span\r\n [ngClass]=\"{\r\n 'text-yellow-500': pendingFileCount > 0,\r\n 'text-green-500': pendingFileCount === 0\r\n }\"\r\n >\r\n {{ pendingFileCount }}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".container-wrapper:nth-child(3n+1){padding-left:0}.container-wrapper:nth-child(3n){padding-right:0}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
3476
|
+
}
|
|
3477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderBlockComponent, decorators: [{
|
|
3478
|
+
type: Component,
|
|
3479
|
+
args: [{ selector: 'lib-folder-block', standalone: false, template: "<div class=\"card p-0 folder-info\">\r\n <div class=\"text-900 text-xl font-semibold ml-2 mb-1\">Folders</div>\r\n <div class=\"grid m-0\">\r\n <div *ngFor=\"let folder of folderList\" class=\"col-12 md:col-6 xl:col-4 container-wrapper\">\r\n <div\r\n class=\"p-3 border-1 h-full surface-border flex flex-column justify-content-between hover:surface-100 cursor-pointer border-round\"\r\n (click)=\"handleClickForFilter(folder._id)\"\r\n >\r\n <div class=\"icon\">\r\n <img src=\"../../../../assets/images/FolderImg.png\" alt=\"\" />\r\n </div>\r\n <div class=\"flex flex-column\">\r\n <span class=\"text-600 mt-2\"> {{ folder.documentCount }} Files </span>\r\n <span class=\"text-900 text-lg mt-2 mb-2 font-semibold font-medium\">\r\n {{ folder.folderName }}\r\n </span>\r\n </div>\r\n <hr />\r\n <div class=\"flex justify-content-between\">\r\n <div class=\"flex flex-column\">\r\n <span>Missing</span>\r\n <span\r\n [ngClass]=\"{\r\n 'text-pink-500': missingFileCount > 0,\r\n 'text-green-500': missingFileCount === 0\r\n }\"\r\n >\r\n {{ missingFileCount }}\r\n </span>\r\n </div>\r\n <div class=\"flex flex-column\">\r\n <span>Pending</span>\r\n <span\r\n [ngClass]=\"{\r\n 'text-yellow-500': pendingFileCount > 0,\r\n 'text-green-500': pendingFileCount === 0\r\n }\"\r\n >\r\n {{ pendingFileCount }}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".container-wrapper:nth-child(3n+1){padding-left:0}.container-wrapper:nth-child(3n){padding-right:0}\n"] }]
|
|
3480
|
+
}], ctorParameters: () => [{ type: DocumentStore }], propDecorators: { folderList: [{
|
|
2064
3481
|
type: Input
|
|
2065
|
-
}]
|
|
3482
|
+
}] } });
|
|
3483
|
+
|
|
3484
|
+
/**
|
|
3485
|
+
* DocumentListItemComponent
|
|
3486
|
+
*
|
|
3487
|
+
* This component displays individual document items within a list.
|
|
3488
|
+
* It accepts a list of documents as input and handles interactions with documents.
|
|
3489
|
+
*/
|
|
3490
|
+
class DocumentListItemComponent {
|
|
3491
|
+
/**
|
|
3492
|
+
* Emit the selected document.
|
|
3493
|
+
* @type {EventEmitter<DocumentModel>}
|
|
3494
|
+
*/
|
|
3495
|
+
documentClick = new EventEmitter();
|
|
3496
|
+
/**
|
|
3497
|
+
* The document to display.
|
|
3498
|
+
* @type {DocumentModel[]}
|
|
3499
|
+
*/
|
|
3500
|
+
document;
|
|
3501
|
+
/**
|
|
3502
|
+
* Handles interactions with a document.
|
|
3503
|
+
* @param {DocumentModel} document - The document to be opened or interacted with.
|
|
3504
|
+
*/
|
|
3505
|
+
handleOpenDocument(document) {
|
|
3506
|
+
if (!document) {
|
|
3507
|
+
console.error('Error: Document is null or undefined:', document);
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3510
|
+
this.documentClick.emit(document);
|
|
3511
|
+
}
|
|
3512
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3513
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentListItemComponent, isStandalone: false, selector: "lib-document-list-item", inputs: { document: "document" }, outputs: { documentClick: "documentClick" }, ngImport: i0, template: "<div class=\"grid m-0\">\r\n <div\r\n class=\"col-12 flex align-items-center justify-content-between md:col-12 xl:col-12\"\r\n >\r\n <div\r\n class=\"col-5 flex cursor-pointer align-items-center pl-0\"\r\n (click)=\"handleOpenDocument(document)\"\r\n >\r\n <img src=\"../../../../assets/images/Frame.png\" alt=\"\" />\r\n <span class=\"ml-4 file-name-wrapper document-text-wrapper\">{{ document.fileName }}</span>\r\n </div>\r\n <div class=\"col-4 flex align-items-center justify-content-center\">\r\n <span\r\n [class]=\"'product-badge status-' + document.status?.toLowerCase()\"\r\n class=\"flex align-items-center justify-content-center pl-2 pr-2 pt-1 pb-1\"\r\n >\r\n <ng-container *ngIf=\"document.status?.toLowerCase() === 'pending'\">\r\n <i class=\"pi pi-clock pr-1\" style=\"font-size: 12px;\"></i>\r\n Pending\r\n </ng-container>\r\n <ng-container *ngIf=\"document.status?.toLowerCase() === 'verified'\">\r\n <i class=\"pi pi-check-circle pr-1\" style=\"font-size: 12px;\"></i>\r\n Verified\r\n </ng-container>\r\n <ng-container *ngIf=\"document.status?.toLowerCase() === 'alert'\">\r\n <i class=\"pi pi-bell pr-1\" style=\"font-size: 12px;\"></i>\r\n Alert\r\n </ng-container>\r\n </span>\r\n </div>\r\n <div class=\"document-type file-name-wrapper document-text-wrapper\">\r\n {{document.documentTypeName}}\r\n </div>\r\n </div>\r\n </div>\r\n ", styles: [".product-badge.status-pending{background:#e9b127;color:#fff;border-radius:4px}.product-badge.status-verified{background:#4caf50;color:#fff;border-radius:4px}.product-badge.status-alert{background:#f57c00;color:#fff;border-radius:4px}.product-badge{text-transform:none;font-weight:500;font-size:12px}.file-name-wrapper{font-size:15px;font-weight:500}.document-text-wrapper{display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
3514
|
+
}
|
|
3515
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentListItemComponent, decorators: [{
|
|
3516
|
+
type: Component,
|
|
3517
|
+
args: [{ selector: 'lib-document-list-item', standalone: false, template: "<div class=\"grid m-0\">\r\n <div\r\n class=\"col-12 flex align-items-center justify-content-between md:col-12 xl:col-12\"\r\n >\r\n <div\r\n class=\"col-5 flex cursor-pointer align-items-center pl-0\"\r\n (click)=\"handleOpenDocument(document)\"\r\n >\r\n <img src=\"../../../../assets/images/Frame.png\" alt=\"\" />\r\n <span class=\"ml-4 file-name-wrapper document-text-wrapper\">{{ document.fileName }}</span>\r\n </div>\r\n <div class=\"col-4 flex align-items-center justify-content-center\">\r\n <span\r\n [class]=\"'product-badge status-' + document.status?.toLowerCase()\"\r\n class=\"flex align-items-center justify-content-center pl-2 pr-2 pt-1 pb-1\"\r\n >\r\n <ng-container *ngIf=\"document.status?.toLowerCase() === 'pending'\">\r\n <i class=\"pi pi-clock pr-1\" style=\"font-size: 12px;\"></i>\r\n Pending\r\n </ng-container>\r\n <ng-container *ngIf=\"document.status?.toLowerCase() === 'verified'\">\r\n <i class=\"pi pi-check-circle pr-1\" style=\"font-size: 12px;\"></i>\r\n Verified\r\n </ng-container>\r\n <ng-container *ngIf=\"document.status?.toLowerCase() === 'alert'\">\r\n <i class=\"pi pi-bell pr-1\" style=\"font-size: 12px;\"></i>\r\n Alert\r\n </ng-container>\r\n </span>\r\n </div>\r\n <div class=\"document-type file-name-wrapper document-text-wrapper\">\r\n {{document.documentTypeName}}\r\n </div>\r\n </div>\r\n </div>\r\n ", styles: [".product-badge.status-pending{background:#e9b127;color:#fff;border-radius:4px}.product-badge.status-verified{background:#4caf50;color:#fff;border-radius:4px}.product-badge.status-alert{background:#f57c00;color:#fff;border-radius:4px}.product-badge{text-transform:none;font-weight:500;font-size:12px}.file-name-wrapper{font-size:15px;font-weight:500}.document-text-wrapper{display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}\n"] }]
|
|
3518
|
+
}], propDecorators: { documentClick: [{
|
|
3519
|
+
type: Output
|
|
3520
|
+
}], document: [{
|
|
2066
3521
|
type: Input
|
|
2067
3522
|
}] } });
|
|
2068
3523
|
|
|
@@ -2092,10 +3547,10 @@ class GlobalErrorHandler {
|
|
|
2092
3547
|
handleError(error) {
|
|
2093
3548
|
console.error('GlobalErrorHandler:', error);
|
|
2094
3549
|
}
|
|
2095
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2096
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.
|
|
3550
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GlobalErrorHandler, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3551
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GlobalErrorHandler });
|
|
2097
3552
|
}
|
|
2098
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
3553
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GlobalErrorHandler, decorators: [{
|
|
2099
3554
|
type: Injectable
|
|
2100
3555
|
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
2101
3556
|
|
|
@@ -2123,16 +3578,181 @@ class DocumentDirective {
|
|
|
2123
3578
|
}
|
|
2124
3579
|
});
|
|
2125
3580
|
}
|
|
2126
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2127
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.
|
|
3581
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentDirective, deps: [{ token: DocumentHelperService }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3582
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: DocumentDirective, isStandalone: false, selector: "[doc]", ngImport: i0 });
|
|
2128
3583
|
}
|
|
2129
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
3584
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentDirective, decorators: [{
|
|
2130
3585
|
type: Directive,
|
|
2131
3586
|
args: [{
|
|
2132
3587
|
selector: '[doc]',
|
|
2133
3588
|
standalone: false
|
|
2134
3589
|
}]
|
|
2135
|
-
}], ctorParameters: () => [{ type:
|
|
3590
|
+
}], ctorParameters: () => [{ type: DocumentHelperService }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }] });
|
|
3591
|
+
|
|
3592
|
+
/**
|
|
3593
|
+
* Service for managing user session details.
|
|
3594
|
+
* @class SessionService
|
|
3595
|
+
* @typedef {SessionService}
|
|
3596
|
+
*/
|
|
3597
|
+
class SessionService {
|
|
3598
|
+
router;
|
|
3599
|
+
/**
|
|
3600
|
+
* Creates an instance of SessionService.
|
|
3601
|
+
* @param {Router} router - Angular Router for navigation.
|
|
3602
|
+
*/
|
|
3603
|
+
constructor(router) {
|
|
3604
|
+
this.router = router;
|
|
3605
|
+
}
|
|
3606
|
+
/**
|
|
3607
|
+
* Retrieves the current user's role from local storage.
|
|
3608
|
+
* @returns {string | null} The user's role, or null if not found.
|
|
3609
|
+
*/
|
|
3610
|
+
getUserRole() {
|
|
3611
|
+
return localStorage.getItem('role');
|
|
3612
|
+
}
|
|
3613
|
+
/**
|
|
3614
|
+
* Stores the user session data in local storage.
|
|
3615
|
+
* @param {any} data - The session data to store.
|
|
3616
|
+
*/
|
|
3617
|
+
setUserSession(data) {
|
|
3618
|
+
localStorage.setItem(SHARED.SESSIONKEY, JSON.stringify(data));
|
|
3619
|
+
}
|
|
3620
|
+
/**
|
|
3621
|
+
* Retrieves the stored user session data.
|
|
3622
|
+
* @returns {any | null} The parsed session data, or null if not found.
|
|
3623
|
+
*/
|
|
3624
|
+
getUserSession() {
|
|
3625
|
+
const sessionData = localStorage.getItem(SHARED.SESSIONKEY);
|
|
3626
|
+
return sessionData ? JSON.parse(sessionData) : null;
|
|
3627
|
+
}
|
|
3628
|
+
/**
|
|
3629
|
+
* Retrieves the user's permissions from the stored session data.
|
|
3630
|
+
* @returns {any | null} The user's permissions, or null if not found.
|
|
3631
|
+
*/
|
|
3632
|
+
getUserPermissions() {
|
|
3633
|
+
const sessionData = localStorage.getItem(SHARED.SESSIONKEY);
|
|
3634
|
+
return sessionData ? JSON.parse(sessionData).permissions : null;
|
|
3635
|
+
}
|
|
3636
|
+
/**
|
|
3637
|
+
* Retrieves the session ID from the stored session data.
|
|
3638
|
+
* @returns {any | null} The session ID, or null if not found.
|
|
3639
|
+
*/
|
|
3640
|
+
getSessionID() {
|
|
3641
|
+
const sessionData = localStorage.getItem(SHARED.SESSIONKEY);
|
|
3642
|
+
console.log(sessionData);
|
|
3643
|
+
if (sessionData) {
|
|
3644
|
+
const sessionId = JSON.parse(sessionData);
|
|
3645
|
+
console.log(sessionId);
|
|
3646
|
+
return sessionId;
|
|
3647
|
+
}
|
|
3648
|
+
return null;
|
|
3649
|
+
}
|
|
3650
|
+
/**
|
|
3651
|
+
* Clears all stored session data from local storage.
|
|
3652
|
+
*/
|
|
3653
|
+
clearSession() {
|
|
3654
|
+
localStorage.clear();
|
|
3655
|
+
}
|
|
3656
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SessionService, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3657
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SessionService, providedIn: 'root' });
|
|
3658
|
+
}
|
|
3659
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SessionService, decorators: [{
|
|
3660
|
+
type: Injectable,
|
|
3661
|
+
args: [{
|
|
3662
|
+
providedIn: 'root'
|
|
3663
|
+
}]
|
|
3664
|
+
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
3665
|
+
|
|
3666
|
+
/**
|
|
3667
|
+
* Directive to conditionally show or hide elements based on user permissions.
|
|
3668
|
+
* @class HasPermissionDirective
|
|
3669
|
+
* @typedef {HasPermissionDirective}
|
|
3670
|
+
*/
|
|
3671
|
+
class HasPermissionDirective {
|
|
3672
|
+
el;
|
|
3673
|
+
renderer;
|
|
3674
|
+
sessionService;
|
|
3675
|
+
/**
|
|
3676
|
+
* The required permission(s) to display the element.
|
|
3677
|
+
* Accepts a single string or an array of strings.
|
|
3678
|
+
* @type {string | string[]}
|
|
3679
|
+
*/
|
|
3680
|
+
permission;
|
|
3681
|
+
/**
|
|
3682
|
+
* Creates an instance of HasPermissionDirective.
|
|
3683
|
+
* @param {ElementRef} el - Reference to the host element.
|
|
3684
|
+
* @param {Renderer2} renderer - Angular Renderer for DOM manipulation.
|
|
3685
|
+
* @param {SessionService} sessionService - Service to retrieve user permissions.
|
|
3686
|
+
*/
|
|
3687
|
+
constructor(el, renderer, sessionService) {
|
|
3688
|
+
this.el = el;
|
|
3689
|
+
this.renderer = renderer;
|
|
3690
|
+
this.sessionService = sessionService;
|
|
3691
|
+
}
|
|
3692
|
+
/**
|
|
3693
|
+
* Lifecycle hook that is called when input properties change.
|
|
3694
|
+
* @param {SimpleChanges} changes - The changes in input properties.
|
|
3695
|
+
*/
|
|
3696
|
+
ngOnChanges(changes) {
|
|
3697
|
+
if (changes['permission']) {
|
|
3698
|
+
this.checkPermission();
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
/**
|
|
3702
|
+
* Checks if the user has the required permission(s).
|
|
3703
|
+
* Hides the element if the permission is not found.
|
|
3704
|
+
*/
|
|
3705
|
+
checkPermission() {
|
|
3706
|
+
const userPermissionsObjects = this.sessionService.getUserPermissions();
|
|
3707
|
+
const userPermissionNames = userPermissionsObjects?.map((perm) => perm.name) || [];
|
|
3708
|
+
const requiredPermissions = Array.isArray(this.permission)
|
|
3709
|
+
? this.permission
|
|
3710
|
+
: [this.permission];
|
|
3711
|
+
const hasPermission = requiredPermissions.some(permission => userPermissionNames.includes(permission));
|
|
3712
|
+
if (!hasPermission) {
|
|
3713
|
+
this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
|
|
3714
|
+
}
|
|
3715
|
+
else {
|
|
3716
|
+
this.renderer.removeStyle(this.el.nativeElement, 'display');
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SessionService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3720
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: HasPermissionDirective, isStandalone: false, selector: "[permission]", inputs: { permission: "permission" }, usesOnChanges: true, ngImport: i0 });
|
|
3721
|
+
}
|
|
3722
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HasPermissionDirective, decorators: [{
|
|
3723
|
+
type: Directive,
|
|
3724
|
+
args: [{
|
|
3725
|
+
selector: '[permission]',
|
|
3726
|
+
standalone: false
|
|
3727
|
+
}]
|
|
3728
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: SessionService }], propDecorators: { permission: [{
|
|
3729
|
+
type: Input
|
|
3730
|
+
}] } });
|
|
3731
|
+
|
|
3732
|
+
class SharedModule {
|
|
3733
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3734
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: SharedModule, declarations: [TablePrimaryComponent], imports: [CommonModule,
|
|
3735
|
+
TableModule,
|
|
3736
|
+
ButtonModule,
|
|
3737
|
+
RippleModule], exports: [TablePrimaryComponent] });
|
|
3738
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SharedModule, imports: [CommonModule,
|
|
3739
|
+
TableModule,
|
|
3740
|
+
ButtonModule,
|
|
3741
|
+
RippleModule] });
|
|
3742
|
+
}
|
|
3743
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SharedModule, decorators: [{
|
|
3744
|
+
type: NgModule,
|
|
3745
|
+
args: [{
|
|
3746
|
+
declarations: [TablePrimaryComponent],
|
|
3747
|
+
imports: [
|
|
3748
|
+
CommonModule,
|
|
3749
|
+
TableModule,
|
|
3750
|
+
ButtonModule,
|
|
3751
|
+
RippleModule
|
|
3752
|
+
],
|
|
3753
|
+
exports: [TablePrimaryComponent]
|
|
3754
|
+
}]
|
|
3755
|
+
}] });
|
|
2136
3756
|
|
|
2137
3757
|
/**
|
|
2138
3758
|
* @module DocumentModule
|
|
@@ -2142,8 +3762,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
2142
3762
|
* document lists, and individual document items.
|
|
2143
3763
|
*/
|
|
2144
3764
|
class DocumentModule {
|
|
2145
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.
|
|
2146
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.
|
|
3765
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
3766
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DocumentModule, declarations: [
|
|
2147
3767
|
/**
|
|
2148
3768
|
* The main container for managing documents.
|
|
2149
3769
|
* DocumentContainerComponent
|
|
@@ -2189,7 +3809,9 @@ class DocumentModule {
|
|
|
2189
3809
|
* A component which have linked documents.
|
|
2190
3810
|
*/
|
|
2191
3811
|
LinkedDocumentComponent,
|
|
2192
|
-
DocumentsMenuComponent
|
|
3812
|
+
DocumentsMenuComponent,
|
|
3813
|
+
UserListComponent,
|
|
3814
|
+
DocumentStatusComponent], imports: [
|
|
2193
3815
|
/**
|
|
2194
3816
|
* Angular's CommonModule is imported to access common directives like `ngIf` and `ngFor`.
|
|
2195
3817
|
*/
|
|
@@ -2260,7 +3882,9 @@ class DocumentModule {
|
|
|
2260
3882
|
InputTextModule,
|
|
2261
3883
|
MenuModule,
|
|
2262
3884
|
PanelMenuModule,
|
|
2263
|
-
CardModule
|
|
3885
|
+
CardModule,
|
|
3886
|
+
TableModule,
|
|
3887
|
+
SharedModule], exports: [
|
|
2264
3888
|
/**
|
|
2265
3889
|
* A directive to give permission.
|
|
2266
3890
|
*/
|
|
@@ -2282,7 +3906,7 @@ class DocumentModule {
|
|
|
2282
3906
|
* A directive to show the document.
|
|
2283
3907
|
*/
|
|
2284
3908
|
DocumentDirective] });
|
|
2285
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.
|
|
3909
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentModule, providers: [
|
|
2286
3910
|
/**
|
|
2287
3911
|
* Provide the messageservice to be used in other components.
|
|
2288
3912
|
*/
|
|
@@ -2384,9 +4008,11 @@ class DocumentModule {
|
|
|
2384
4008
|
InputTextModule,
|
|
2385
4009
|
MenuModule,
|
|
2386
4010
|
PanelMenuModule,
|
|
2387
|
-
CardModule
|
|
4011
|
+
CardModule,
|
|
4012
|
+
TableModule,
|
|
4013
|
+
SharedModule] });
|
|
2388
4014
|
}
|
|
2389
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.
|
|
4015
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentModule, decorators: [{
|
|
2390
4016
|
type: NgModule,
|
|
2391
4017
|
args: [{
|
|
2392
4018
|
declarations: [
|
|
@@ -2436,6 +4062,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
2436
4062
|
*/
|
|
2437
4063
|
LinkedDocumentComponent,
|
|
2438
4064
|
DocumentsMenuComponent,
|
|
4065
|
+
UserListComponent,
|
|
4066
|
+
DocumentStatusComponent,
|
|
2439
4067
|
],
|
|
2440
4068
|
imports: [
|
|
2441
4069
|
/**
|
|
@@ -2508,7 +4136,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
2508
4136
|
InputTextModule,
|
|
2509
4137
|
MenuModule,
|
|
2510
4138
|
PanelMenuModule,
|
|
2511
|
-
CardModule
|
|
4139
|
+
CardModule,
|
|
4140
|
+
TableModule,
|
|
4141
|
+
SharedModule
|
|
2512
4142
|
],
|
|
2513
4143
|
exports: [
|
|
2514
4144
|
/**
|
|
@@ -2576,5 +4206,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
|
|
|
2576
4206
|
* Generated bundle index. Do not edit.
|
|
2577
4207
|
*/
|
|
2578
4208
|
|
|
2579
|
-
export { DocumentContainerComponent, DocumentDirective, DocumentListComponent, DocumentModule, DocumentViewerComponent, HasPermissionDirective };
|
|
4209
|
+
export { DocumentContainerComponent, DocumentDirective, DocumentListComponent, DocumentModule, DocumentTableBuilderService, DocumentViewerComponent, HasPermissionDirective };
|
|
2580
4210
|
//# sourceMappingURL=cat-documents-ng.mjs.map
|