cat-documents-ng 0.1.28 → 0.1.30

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.
Files changed (92) hide show
  1. package/ng-package.json +11 -0
  2. package/package.json +20 -25
  3. package/{Shared/constant/ERROR.d.ts → src/Shared/constant/ERROR.ts} +38 -36
  4. package/src/Shared/constant/PERMISSIONS.ts +16 -0
  5. package/src/Shared/constant/SHARED.ts +312 -0
  6. package/{Shared/constant/URLS.d.ts → src/Shared/constant/URLS.ts} +65 -60
  7. package/src/Shared/services/app-config.service.spec.ts +19 -0
  8. package/src/Shared/services/app-config.service.ts +73 -0
  9. package/{Shared/services/global-error.handler.d.ts → src/Shared/services/global-error.handler.ts} +29 -27
  10. package/src/Shared/services/session.service.spec.ts +16 -0
  11. package/src/Shared/services/session.service.ts +76 -0
  12. package/src/assets/config/api.config.json +20 -0
  13. package/src/lib/document/components/document-container/document-container.component.html +14 -0
  14. package/src/lib/document/components/document-container/document-container.component.scss +8 -0
  15. package/src/lib/document/components/document-container/document-container.component.spec.ts +110 -0
  16. package/src/lib/document/components/document-container/document-container.component.ts +173 -0
  17. package/src/lib/document/components/document-list/document-list.component.html +81 -0
  18. package/src/lib/document/components/document-list/document-list.component.scss +82 -0
  19. package/src/lib/document/components/document-list/document-list.component.spec.ts +96 -0
  20. package/src/lib/document/components/document-list/document-list.component.ts +244 -0
  21. package/src/lib/document/components/document-list-item/document-list-item.component.html +36 -0
  22. package/src/lib/document/components/document-list-item/document-list-item.component.scss +34 -0
  23. package/src/lib/document/components/document-list-item/document-list-item.component.spec.ts +75 -0
  24. package/src/lib/document/components/document-list-item/document-list-item.component.ts +40 -0
  25. package/src/lib/document/components/document-upload/document-upload.component.html +56 -0
  26. package/src/lib/document/components/document-upload/document-upload.component.scss +32 -0
  27. package/src/lib/document/components/document-upload/document-upload.component.spec.ts +95 -0
  28. package/src/lib/document/components/document-upload/document-upload.component.ts +162 -0
  29. package/src/lib/document/components/document-viewer/document-viewer.component.html +98 -0
  30. package/src/lib/document/components/document-viewer/document-viewer.component.scss +54 -0
  31. package/src/lib/document/components/document-viewer/document-viewer.component.spec.ts +79 -0
  32. package/src/lib/document/components/document-viewer/document-viewer.component.ts +106 -0
  33. package/src/lib/document/components/folder-block/folder-block.component.html +46 -0
  34. package/src/lib/document/components/folder-block/folder-block.component.scss +9 -0
  35. package/src/lib/document/components/folder-block/folder-block.component.spec.ts +70 -0
  36. package/{lib/document/components/folder-block/folder-block.component.d.ts → src/lib/document/components/folder-block/folder-block.component.ts} +53 -37
  37. package/src/lib/document/components/folder-container/folder-container.component.html +2 -0
  38. package/src/lib/document/components/folder-container/folder-container.component.scss +0 -0
  39. package/src/lib/document/components/folder-container/folder-container.component.spec.ts +27 -0
  40. package/src/lib/document/components/folder-container/folder-container.component.ts +37 -0
  41. package/src/lib/document/components/linked-document/linked-document.component.html +23 -0
  42. package/src/lib/document/components/linked-document/linked-document.component.scss +10 -0
  43. package/src/lib/document/components/linked-document/linked-document.component.spec.ts +61 -0
  44. package/src/lib/document/components/linked-document/linked-document.component.ts +49 -0
  45. package/src/lib/document/directives/document.directive.ts +32 -0
  46. package/src/lib/document/directives/permission.directive.spec.ts +0 -0
  47. package/src/lib/document/directives/permission.directive.ts +66 -0
  48. package/src/lib/document/document.module.ts +241 -0
  49. package/{lib/document/models/document-alert.model.d.ts → src/lib/document/models/document-alert.model.ts} +45 -38
  50. package/src/lib/document/models/document-type.model.ts +44 -0
  51. package/src/lib/document/models/document.model.ts +53 -0
  52. package/{lib/document/models/folder.model.d.ts → src/lib/document/models/folder.model.ts} +35 -29
  53. package/src/lib/document/services/document-http.service.spec.ts +119 -0
  54. package/src/lib/document/services/document-http.service.ts +125 -0
  55. package/src/lib/document/services/document-upload.service.spec.ts +99 -0
  56. package/src/lib/document/services/document-upload.service.ts +127 -0
  57. package/src/lib/document/services/document.service.ts +29 -0
  58. package/src/lib/document/services/file-format.service.spec.ts +16 -0
  59. package/src/lib/document/services/file-format.service.ts +41 -0
  60. package/src/lib/document/state/document.query.ts +52 -0
  61. package/{lib/document/state/document.service.d.ts → src/lib/document/state/document.service.ts} +95 -64
  62. package/{lib/document/state/document.state.d.ts → src/lib/document/state/document.state.ts} +52 -36
  63. package/src/lib/document/state/document.store.ts +51 -0
  64. package/{public-api.d.ts → src/public-api.ts} +10 -6
  65. package/tsconfig.lib.json +15 -0
  66. package/tsconfig.lib.prod.json +11 -0
  67. package/tsconfig.spec.json +15 -0
  68. package/Shared/constant/PERMISSIONS.d.ts +0 -15
  69. package/Shared/constant/SHARED.d.ts +0 -209
  70. package/Shared/services/app-config.service.d.ts +0 -51
  71. package/Shared/services/session.service.d.ts +0 -46
  72. package/fesm2022/cat-documents-ng.mjs +0 -2538
  73. package/fesm2022/cat-documents-ng.mjs.map +0 -1
  74. package/index.d.ts +0 -5
  75. package/lib/document/components/document-container/document-container.component.d.ts +0 -85
  76. package/lib/document/components/document-list/document-list.component.d.ts +0 -160
  77. package/lib/document/components/document-list-item/document-list-item.component.d.ts +0 -28
  78. package/lib/document/components/document-upload/document-upload.component.d.ts +0 -120
  79. package/lib/document/components/document-viewer/document-viewer.component.d.ts +0 -73
  80. package/lib/document/components/folder-container/folder-container.component.d.ts +0 -29
  81. package/lib/document/components/linked-document/linked-document.component.d.ts +0 -38
  82. package/lib/document/directives/document.directive.d.ts +0 -20
  83. package/lib/document/directives/permission.directive.d.ts +0 -38
  84. package/lib/document/document.module.d.ts +0 -40
  85. package/lib/document/models/document-type.model.d.ts +0 -37
  86. package/lib/document/models/document.model.d.ts +0 -44
  87. package/lib/document/services/document-http.service.d.ts +0 -69
  88. package/lib/document/services/document-upload.service.d.ts +0 -67
  89. package/lib/document/services/document.service.d.ts +0 -20
  90. package/lib/document/services/file-format.service.d.ts +0 -23
  91. package/lib/document/state/document.query.d.ts +0 -42
  92. package/lib/document/state/document.store.d.ts +0 -29
@@ -0,0 +1,96 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { DocumentListComponent } from './document-list.component';
3
+ import { DocumentUploadService } from '../../services/document-upload.service';
4
+ import { DocumentHttpService } from '../../services/document-http.service';
5
+ import { of } from 'rxjs';
6
+ import { NO_ERRORS_SCHEMA } from '@angular/core';
7
+ import { DocumentTypeModel } from '../../models/document-type.model';
8
+ import { DocumentModel } from '../../models/document.model';
9
+ import { SHARED } from '../../../../Shared/constant/SHARED';
10
+
11
+ describe('DocumentListComponent', () => {
12
+ let component: DocumentListComponent;
13
+ let fixture: ComponentFixture<DocumentListComponent>;
14
+ let documentUploadService: jasmine.SpyObj<DocumentUploadService>;
15
+ let documentHttpService: jasmine.SpyObj<DocumentHttpService>;
16
+
17
+ beforeEach(async () => {
18
+ // Mock services
19
+ documentUploadService = jasmine.createSpyObj('DocumentUploadService', [
20
+ 'getDocumentNameAndType',
21
+ 'handleTemplatedUpload'
22
+ ]);
23
+ documentHttpService = jasmine.createSpyObj('DocumentHttpService', ['getDocumentTypes', 'updateDocumentName']);
24
+
25
+ // Mock `getDocumentTypes` to return valid `DocumentTypeModel` objects
26
+ documentHttpService.getDocumentTypes.and.returnValue(
27
+ of([
28
+ { _id: 1, label: 'Type 1', matchRules: [], name: 'Type 1', parentDocumentTypeId: null },
29
+ { _id: 2, label: 'Type 2', matchRules: [], name: 'Type 2', parentDocumentTypeId: null }
30
+ ] as unknown as DocumentTypeModel[])
31
+ );
32
+
33
+ await TestBed.configureTestingModule({
34
+ declarations: [DocumentListComponent],
35
+ providers: [
36
+ { provide: DocumentUploadService, useValue: documentUploadService },
37
+ { provide: DocumentHttpService, useValue: documentHttpService }
38
+ ],
39
+ schemas: [NO_ERRORS_SCHEMA] // To suppress schema-related errors
40
+ }).compileComponents();
41
+
42
+ fixture = TestBed.createComponent(DocumentListComponent);
43
+ component = fixture.componentInstance;
44
+ fixture.detectChanges(); // Trigger lifecycle hooks and initial data binding
45
+ });
46
+
47
+ it('should create', () => {
48
+ expect(component).toBeTruthy();
49
+ });
50
+
51
+ it('should fetch document types on initialization', () => {
52
+ expect(component.options).toEqual([
53
+ { label: 'Type 1', value: 1 },
54
+ { label: 'Type 2', value: 2 }
55
+ ]);
56
+ });
57
+
58
+ it('should handle file upload click', () => {
59
+ const event = new MouseEvent('click');
60
+ spyOn(event, 'stopPropagation');
61
+ component.handleFileUploadClick(event);
62
+ expect(event.stopPropagation).toHaveBeenCalled();
63
+ expect(component.isSidebarVisible).toBeTrue();
64
+ });
65
+
66
+ it('should handle document click and open dialog', () => {
67
+ const mockDocument = { _id: "1", documentUrl: 'http://example.com/doc.pdf' } as DocumentModel;
68
+
69
+ component.handleClickForDocument(mockDocument);
70
+ expect(component.isdialogVisible).toBeTrue();
71
+ expect(component.selectedDocument).toBe(mockDocument);
72
+ });
73
+
74
+ it('should handle dialog close and reset selected document', () => {
75
+ component.selectedDocument = { _id: "1" };
76
+ component.handleCloseModal();
77
+ expect(component.selectedDocument).toEqual({ _id: "" });
78
+
79
+
80
+ expect(component.isdialogVisible).toBeFalse();
81
+ });
82
+
83
+ it('should update document name on handleSaveClick', () => {
84
+ component.fileName = 'New Document';
85
+ component.selectedDocument = { _id: '1' } as DocumentModel;
86
+
87
+ spyOn(console, 'log');
88
+
89
+ documentHttpService.updateDocumentName.and.returnValue(of({} as DocumentModel));
90
+
91
+ component.handleSaveClick();
92
+ expect(documentHttpService.updateDocumentName).toHaveBeenCalledWith('1', { fileName: 'New Document' });
93
+ expect(console.log).toHaveBeenCalledWith(`${SHARED.UPDATE_DOCUMENT_NAME} 1`);
94
+ });
95
+
96
+ });
@@ -0,0 +1,244 @@
1
+ import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
2
+ import { DocumentModel } from '../../models/document.model';
3
+ import { SHARED } from '../../../../Shared/constant/SHARED';
4
+ import { ERRORS } from '../../../../Shared/constant/ERROR';
5
+ import { DocumentHttpService } from '../../services/document-http.service';
6
+ import { DocumentTypeModel } from '../../models/document-type.model';
7
+ import { DocumentUploadService } from '../../services/document-upload.service';
8
+ import { Message } from 'primeng/api';
9
+ import { DocumentQuery } from '../../state/document.query';
10
+ import { DocumentStore } from '../../state/document.store';
11
+ import { PERMISSIONS } from '../../../../Shared/constant/PERMISSIONS';
12
+
13
+ /**
14
+ * This component is responsible for displaying and managing a list of documents.
15
+ * Provides functionality for file upload, document selection, and dialog management.
16
+ * @class DocumentListComponent
17
+ */
18
+ @Component({
19
+ selector: 'lib-document-list',
20
+ standalone: false,
21
+ templateUrl: './document-list.component.html',
22
+ styleUrls: ['./document-list.component.scss'],
23
+ encapsulation: ViewEncapsulation.None
24
+ })
25
+ export class DocumentListComponent implements OnInit{
26
+
27
+ @Output() onRefresh = new EventEmitter();
28
+ /**
29
+ * Represents the context ID for the document list.
30
+ * This value is passed from the parent component.
31
+ * @type {string}
32
+ * @memberof DocumentListComponent
33
+ */
34
+ @Input() contextId: string = SHARED.EMPTY;
35
+
36
+ /**
37
+ * Default visibility of the upload button.
38
+ * @type {boolean}
39
+ * @memberof DocumentListComponent
40
+ */
41
+ @Input() isUploadButtonVisible:boolean = SHARED.TRUE;
42
+
43
+ /**
44
+ * The currently selected document.
45
+ * @type {DocumentModel}
46
+ * @memberof DocumentListComponent
47
+ */
48
+ selectedDocument!: DocumentModel;
49
+
50
+ /**
51
+ * Default visibility of the sidebar.
52
+ * @type {boolean}
53
+ * @memberof DocumentListComponent
54
+ */
55
+ isSidebarVisible: boolean = SHARED.FALSE;
56
+
57
+ /**
58
+ * Default visibility of the Accordion.
59
+ * @type {boolean}
60
+ * @memberof DocumentListComponent
61
+ */
62
+ @Input() isCollapsed: boolean = SHARED.FALSE;
63
+
64
+ /**
65
+ * Default visibility of the messages.
66
+ * @type {Message[]}
67
+ * @memberof DocumentListComponent
68
+ */
69
+ messages: Message[] = SHARED.EMPTY_ARRAY;
70
+
71
+ /**
72
+ * Default visibility of the dialog.
73
+ * @type {boolean}
74
+ * @memberof DocumentListComponent
75
+ */
76
+ isdialogVisible: boolean = SHARED.FALSE;
77
+
78
+ /**
79
+ * The list of documents to display.
80
+ * This value is passed from the parent component.
81
+ * @type {DocumentModel[]}
82
+ * @memberof DocumentListComponent
83
+ */
84
+ @Input() documentList: DocumentModel[] = SHARED.EMPTY_ARRAY;
85
+
86
+ /**
87
+ * The name of the document being uploaded or managed.
88
+ * @type {string}
89
+ * @memberof DocumentListComponent
90
+ */
91
+ documentName: string = SHARED.EMPTY;
92
+
93
+ /**
94
+ * Available document types for selection.
95
+ * @type {string[]}
96
+ * @memberof DocumentListComponent
97
+ */
98
+ options : any[] = SHARED.EMPTY_ARRAY;
99
+
100
+ /**
101
+ * The selected option for the document type.
102
+ * @type {(string | null)}
103
+ * @memberof DocumentListComponent
104
+ */
105
+ selectedOption: string | null = null;
106
+
107
+ /**
108
+ * The set of permissions available for this component.
109
+ */
110
+ PERMISSION = PERMISSIONS;
111
+ /**
112
+ * The file name associated with the document.
113
+ * It may be undefined until a file is selected or loaded.
114
+ * @type {string | undefined}
115
+ */
116
+ fileName!: string | undefined;
117
+ /**
118
+ * Creates an instance of DocumentListComponent.
119
+ * @class
120
+ * @param {DocumentUploadService} documentUploadService - The service responsible for uploading documents.
121
+ * @param {DocumentHttpService} documentHttpService - The service responsible for fetching documents from the server.
122
+ * @param {DocumentQuery} documentQuery - The service responsible for geting stored documents.
123
+ * @param {DocumentStore} documentStore - The service responsible for storing documents.
124
+ */
125
+ constructor(public documentUploadService : DocumentUploadService ,public documentHttpService : DocumentHttpService, public documentQuery : DocumentQuery, public documentStore : DocumentStore) {
126
+
127
+ }
128
+
129
+ /**
130
+ * Initializes the component by fetching the document type list.
131
+ */
132
+ ngOnInit(): void {
133
+ this.getDocumentTypeList();
134
+ }
135
+
136
+ /**
137
+ * Handles the click event for file upload.
138
+ * Prevents event propagation and displays the sidebar.
139
+ * @param {MouseEvent} event - The click event triggered by the user.
140
+ * @memberof DocumentListComponent
141
+ */
142
+ handleFileUploadClick(event: MouseEvent): void {
143
+ event.stopPropagation();
144
+ this.documentStore.setMessage(SHARED.EMPTY_ARRAY)
145
+ this.isSidebarVisible = SHARED.TRUE;
146
+ }
147
+
148
+ /**
149
+ * Handles the selection of an individual document.
150
+ * Opens a dialog to display or manage the selected document.
151
+ * @param {DocumentModel} document - The document that was clicked by the user.
152
+ * @memberof DocumentListComponent
153
+ */
154
+ handleClickForDocument(document: DocumentModel): void {
155
+ this.isdialogVisible = SHARED.TRUE;
156
+ this.selectedDocument = document;
157
+ this.fileName = document.fileName;
158
+ }
159
+
160
+ /**
161
+ * Handles the save click event to update the document's file name.
162
+ * This method creates a payload with the updated file name and calls the
163
+ * updateDocumentName() method from the documentHttpService. On a successful update,
164
+ * it logs a message with the document's ID.
165
+ * @returns {void}
166
+ */
167
+ handleSaveClick() {
168
+ const payload = { fileName: this.fileName };
169
+ this.documentHttpService.updateDocumentName(this.selectedDocument._id, payload)
170
+ .subscribe((res) => {
171
+ console.log(`${SHARED.UPDATE_DOCUMENT_NAME} ${this.selectedDocument._id}`);
172
+ })
173
+ }
174
+ /**
175
+ * Closes the dialog and resets the selected document.
176
+ * @memberof DocumentListComponent
177
+ */
178
+ handleCloseModal(): void {
179
+ this.selectedDocument = { _id: SHARED.EMPTY };
180
+ this.isdialogVisible = SHARED.FALSE;
181
+ this.onRefresh.emit();
182
+ }
183
+
184
+ /**
185
+ * Handles the upload action for a document.
186
+ * Validates if a document type is selected and logs the result.
187
+ * @memberof DocumentListComponent
188
+ */
189
+ handleUploadDocument(): void {
190
+ if (this.selectedOption) {
191
+ this.documentUploadService.getDocumentNameAndType(this.selectedOption);
192
+ this.documentUploadService.handleTemplatedUpload();
193
+ this.documentQuery.selectMessages().subscribe((message:Message[])=>{
194
+ if(message.length > 0){
195
+ this.messages = message;
196
+ this.onRefresh.emit();
197
+ this.selectedOption = null;
198
+ setTimeout(() => {
199
+ this.messages = SHARED.EMPTY_ARRAY
200
+ this.handleOpenSideBar(false);
201
+ }, 1000);
202
+ }
203
+ })
204
+ } else {
205
+ console.error(ERRORS.INVALID_RECIPIENT);
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Fetches the list of document types from the server.
211
+ * Updates the options array with the available document types.
212
+ * @memberof DocumentListComponent
213
+ * @returns {void}
214
+ */
215
+ getDocumentTypeList() {
216
+ this.documentHttpService.getDocumentTypes().subscribe({
217
+ /**
218
+ * Handles the successful API response.
219
+ * @param {DocumentTypeModel[]} documentTypes - The list of document types returned by the API.
220
+ */
221
+ next: (documentTypes: DocumentTypeModel[]) => {
222
+ if (documentTypes) {
223
+ this.options = documentTypes.map((doc) => ({
224
+ label: doc.label,
225
+ value: doc._id
226
+ }));
227
+ } else {
228
+ console.error(ERRORS.ERROR_ALLDOCUMENT_MISSING, documentTypes);
229
+ }
230
+ },
231
+ /**
232
+ * Handles errors if the request fails.
233
+ * @param {any} err - The error object returned by the server.
234
+ */
235
+ error: (err: any) => {
236
+ console.error(ERRORS.ERROR_DOCUMENT_TYPES, err);
237
+ }
238
+ });
239
+ }
240
+
241
+ handleOpenSideBar(isVisible : boolean){
242
+ this.isSidebarVisible = isVisible
243
+ }
244
+ }
@@ -0,0 +1,36 @@
1
+ <div class="grid m-0">
2
+ <div
3
+ class="col-12 flex align-items-center justify-content-between md:col-12 xl:col-12"
4
+ >
5
+ <div
6
+ class="col-5 flex cursor-pointer align-items-center pl-0"
7
+ (click)="handleOpenDocument(document)"
8
+ >
9
+ <img src="../../../../assets/images/Frame.png" alt="" />
10
+ <span class="ml-4 file-name-wrapper document-text-wrapper">{{ document.fileName }}</span>
11
+ </div>
12
+ <div class="col-4 flex align-items-center justify-content-center">
13
+ <span
14
+ [class]="'product-badge status-' + document.status?.toLowerCase()"
15
+ class="flex align-items-center justify-content-center pl-2 pr-2 pt-1 pb-1"
16
+ >
17
+ <ng-container *ngIf="document.status?.toLowerCase() === 'pending'">
18
+ <i class="pi pi-clock pr-1" style="font-size: 12px;"></i>
19
+ Pending
20
+ </ng-container>
21
+ <ng-container *ngIf="document.status?.toLowerCase() === 'verified'">
22
+ <i class="pi pi-check-circle pr-1" style="font-size: 12px;"></i>
23
+ Verified
24
+ </ng-container>
25
+ <ng-container *ngIf="document.status?.toLowerCase() === 'alert'">
26
+ <i class="pi pi-bell pr-1" style="font-size: 12px;"></i>
27
+ Alert
28
+ </ng-container>
29
+ </span>
30
+ </div>
31
+ <div class="document-type file-name-wrapper document-text-wrapper">
32
+ {{document.documentTypeName}}
33
+ </div>
34
+ </div>
35
+ </div>
36
+
@@ -0,0 +1,34 @@
1
+ .product-badge.status-pending {
2
+ background: #e9b127;
3
+ color: #ffffff;
4
+ border-radius: 4px;
5
+ }
6
+ .product-badge.status-verified {
7
+ background: #4caf50;
8
+ color: #ffffff;
9
+ border-radius: 4px;
10
+ }
11
+ .product-badge.status-alert {
12
+ background: #f57c00;
13
+ color: #ffffff;
14
+ border-radius: 4px;
15
+ }
16
+ .product-badge {
17
+ text-transform: none;
18
+ font-weight: 500;
19
+ font-size: 12px;
20
+
21
+ }
22
+
23
+ .file-name-wrapper{
24
+ font-size: 15px;
25
+ font-weight: 500;
26
+ }
27
+
28
+ .document-text-wrapper{
29
+ display: -webkit-box;
30
+ -webkit-line-clamp: 1;
31
+ -webkit-box-orient: vertical;
32
+ overflow: hidden;
33
+ text-overflow: ellipsis;
34
+ }
@@ -0,0 +1,75 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { DocumentListItemComponent } from './document-list-item.component';
3
+ import { CommonModule } from '@angular/common';
4
+ import { By } from '@angular/platform-browser';
5
+ import { DocumentModel } from '../../models/document.model';
6
+
7
+ describe('DocumentListItemComponent', () => {
8
+ let component: DocumentListItemComponent;
9
+ let fixture: ComponentFixture<DocumentListItemComponent>;
10
+
11
+ beforeEach(async () => {
12
+ await TestBed.configureTestingModule({
13
+ declarations: [DocumentListItemComponent],
14
+ imports: [CommonModule],
15
+ }).compileComponents();
16
+
17
+ fixture = TestBed.createComponent(DocumentListItemComponent);
18
+ component = fixture.componentInstance;
19
+ component.document = {
20
+ _id : "1",
21
+ fileName : 'test',
22
+ }
23
+ fixture.detectChanges();
24
+ });
25
+
26
+ it('should create', () => {
27
+ expect(component).toBeTruthy();
28
+ });
29
+
30
+ it('should emit the selected document when handleOpenDocument is called', () => {
31
+ spyOn(component.documentClick, 'emit');
32
+ const mockDocument = { _id: "1", fileName: 'test' } as DocumentModel;
33
+ component.handleOpenDocument(mockDocument);
34
+ expect(component.documentClick.emit).toHaveBeenCalledWith(mockDocument);
35
+ });
36
+
37
+ it('should log an error when handleOpenDocument is called with null', () => {
38
+ spyOn(console, 'error');
39
+ component.handleOpenDocument(null as unknown as DocumentModel);
40
+
41
+ expect(console.error).toHaveBeenCalledWith('Error: Document is null or undefined:', null);
42
+ });
43
+
44
+ it('should emit documentClick event when document is clicked', () => {
45
+ spyOn(component.documentClick, 'emit');
46
+ const clickableElement = fixture.debugElement.query(By.css('.cursor-pointer'));
47
+ clickableElement.triggerEventHandler('click', null);
48
+
49
+ expect(component.documentClick.emit).toHaveBeenCalledWith(component.document);
50
+ });
51
+
52
+ it('should display Pending status with the correct icon', () => {
53
+ component.document.status = 'Pending';
54
+ fixture.detectChanges();
55
+
56
+ const statusElement = fixture.debugElement.query(By.css('.status-pending')).nativeElement;
57
+ const iconElement = fixture.debugElement.query(By.css('.pi-clock')).nativeElement;
58
+
59
+ expect(statusElement.textContent).toContain('Pending');
60
+ expect(iconElement).toBeTruthy();
61
+ });
62
+
63
+ it('should display Verified status with the correct icon', () => {
64
+ component.document.status = 'Verified';
65
+ fixture.detectChanges();
66
+
67
+ const statusElement = fixture.debugElement.query(By.css('.status-verified')).nativeElement;
68
+ const iconElement = fixture.debugElement.query(By.css('.pi-check-circle')).nativeElement;
69
+
70
+ expect(statusElement.textContent).toContain('Verified');
71
+ expect(iconElement).toBeTruthy();
72
+ });
73
+
74
+
75
+ });
@@ -0,0 +1,40 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { DocumentModel } from '../../models/document.model';
3
+
4
+ /**
5
+ * DocumentListItemComponent
6
+ *
7
+ * This component displays individual document items within a list.
8
+ * It accepts a list of documents as input and handles interactions with documents.
9
+ */
10
+ @Component({
11
+ selector: 'lib-document-list-item',
12
+ standalone: false,
13
+ templateUrl: './document-list-item.component.html',
14
+ styleUrls: ['./document-list-item.component.scss']
15
+ })
16
+ export class DocumentListItemComponent {
17
+ /**
18
+ * Emit the selected document.
19
+ * @type {EventEmitter<DocumentModel>}
20
+ */
21
+ @Output() documentClick = new EventEmitter<DocumentModel>();
22
+
23
+ /**
24
+ * The document to display.
25
+ * @type {DocumentModel[]}
26
+ */
27
+ @Input() document!: DocumentModel;
28
+
29
+ /**
30
+ * Handles interactions with a document.
31
+ * @param {DocumentModel} document - The document to be opened or interacted with.
32
+ */
33
+ handleOpenDocument(document: DocumentModel): void {
34
+ if (!document) {
35
+ console.error('Error: Document is null or undefined:', document);
36
+ return;
37
+ }
38
+ this.documentClick.emit(document);
39
+ }
40
+ }
@@ -0,0 +1,56 @@
1
+ <div class="grid">
2
+ <div class="col-12 md:col-12">
3
+ <p-fileUpload #fileUploader [multiple]="true" auto="true" accept="image/png,application/pdf" maxFileSize="26214400"
4
+ (onSelect)="onSelectedFiles($event)">
5
+ <ng-template pTemplate="header" let-chooseCallback="chooseCallback" let-clearCallback="clearCallback">
6
+ <div class="docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2">
7
+ <div class="flex gap-2">
8
+ <p-button (onClick)="choose($event, chooseCallback)" icon="pi pi-images" [rounded]="true"
9
+ [outlined]="true" />
10
+ </div>
11
+ </div>
12
+ </ng-template>
13
+ <ng-template pTemplate="content" let-removeFileCallback="removeFileCallback"
14
+ let-removeUploadedFileCallback="removeUploadedFileCallback">
15
+ <div class="col-12 md:col-12 p-0">
16
+ <div class="col-12 md:col-12 p-0" *ngIf="uploadedFiles.length > 0">
17
+ <div *ngFor="let uploadedFile of uploadedFiles; let i = index"
18
+ class="m-0 flex flex-column align-items-center gap-1 mt-3">
19
+ <div class="col-12 md:col-12 p-0 flex documentInfo">
20
+ <div class="documentImage">
21
+ <img src="../../../../assets/images/document.png" [alt]="uploadedFile.file.name" width="45" height="50"
22
+ class="object-contain" />
23
+ </div>
24
+ <div class="flex w-full flex-column mt-2 ml-2">
25
+ <div class="flex justify-content-between">
26
+ <div style=" font-weight: bold;font-size: 14px">
27
+ {{ uploadedFile.file.name }}
28
+ </div>
29
+ <i class="pi pi-times cursor-pointer" (click)="handleDocumentRemove(uploadedFile.file,i)"></i>
30
+ </div>
31
+ <div class="flex justify-content-between mt-1">
32
+ <div style="color: #676B89; font-size: 12px; color: green;" class="pi pi-verified "> {{ uploadedFile.formattedSize }}</div>
33
+ <div class="white-space-nowrap" style="color: #0F8BFD; font-family: 14px;"> {{ uploadedFile.progress }} %</div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <div class="col-12 md:col-12 p-0">
38
+ <p-progressBar [value]="totalSizePercent" [showValue]="false" styleClass="h-1/2rem md:ml-auto relative"
39
+ [ngClass]="{ 'exceeded-progress-bar': totalSizePercent > 100 }">
40
+ </p-progressBar>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </ng-template>
46
+ <ng-template pTemplate="empty" let-chooseCallback="chooseCallback">
47
+ <div *ngIf="!uploadedFiles.length" class="flex align-items-center justify-content-center flex-column"
48
+ (click)="triggerFileUpload()">
49
+ <i class="pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400"></i>
50
+ <p class="mt-4 mb-0">Drag and drop files here to upload.</p>
51
+ </div>
52
+ </ng-template>
53
+ <ng-template pTemplate="file"> </ng-template>
54
+ </p-fileUpload>
55
+ </div>
56
+ </div>
@@ -0,0 +1,32 @@
1
+ .flex {
2
+ display: flex;
3
+ }
4
+ .items-center {
5
+ align-items: center;
6
+ }
7
+ .justify-center {
8
+ justify-content: center;
9
+ }
10
+ .flex-col {
11
+ flex-direction: column;
12
+ }
13
+ .text-muted-color {
14
+ color: #6c757d; // Adjust to match your theme
15
+ }
16
+ .p-fileupload-buttonbar {
17
+ padding: 0px;
18
+ }
19
+ .p-fileupload-content {
20
+ background-color: #0f8bfd1a;
21
+ }
22
+ .p-fileupload {
23
+ .p-fileupload-content {
24
+ padding: 1rem 1rem;
25
+ }
26
+
27
+ }
28
+ .docHeader{
29
+ .p-button-icon{
30
+ padding: 0.5rem;
31
+ }
32
+ }