cat-documents-ng 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +322 -322
- package/ng-package.json +10 -0
- package/package.json +5 -11
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.html +3 -0
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.scss +13 -0
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.spec.ts +70 -0
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.ts +133 -0
- package/src/Shared/components/table-primary/table-primary.component.html +66 -0
- package/src/Shared/components/table-primary/table-primary.component.scss +227 -0
- package/src/Shared/components/table-primary/table-primary.component.spec.ts +23 -0
- package/src/Shared/components/table-primary/table-primary.component.ts +143 -0
- package/src/Shared/components/table-primary/table-primary.model.ts +21 -0
- package/src/Shared/constant/ERROR.ts +55 -0
- package/src/Shared/constant/PERMISSIONS.ts +17 -0
- package/src/Shared/constant/SHARED.ts +936 -0
- package/{Shared/constant/URLS.d.ts → src/Shared/constant/URLS.ts} +31 -25
- package/src/Shared/services/app-config.service.spec.ts +19 -0
- package/src/Shared/services/app-config.service.ts +73 -0
- package/{Shared/services/global-error.handler.d.ts → src/Shared/services/global-error.handler.ts} +11 -9
- package/src/Shared/services/session.service.spec.ts +16 -0
- package/src/Shared/services/session.service.ts +76 -0
- package/src/Shared/shared.module.ts +25 -0
- package/src/lib/document/components/csv-viewer/csv-viewer.component.ts +1 -0
- package/src/lib/document/components/document-actions/document-actions.component.html +59 -0
- package/src/lib/document/components/document-actions/document-actions.component.scss +362 -0
- package/src/lib/document/components/document-actions/document-actions.component.spec.ts +297 -0
- package/src/lib/document/components/document-actions/document-actions.component.ts +163 -0
- package/src/lib/document/components/document-container/document-container.component.html +36 -0
- package/src/lib/document/components/document-container/document-container.component.scss +144 -0
- package/src/lib/document/components/document-container/document-container.component.spec.ts +110 -0
- package/src/lib/document/components/document-container/document-container.component.ts +363 -0
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.html +332 -0
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.scss +1877 -0
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.spec.ts +258 -0
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.ts +664 -0
- package/src/lib/document/components/document-history/document-history.component.html +96 -0
- package/src/lib/document/components/document-history/document-history.component.scss +392 -0
- package/src/lib/document/components/document-history/document-history.component.spec.ts +93 -0
- package/src/lib/document/components/document-history/document-history.component.ts +373 -0
- package/src/lib/document/components/document-list/document-list.component.html +46 -0
- package/src/lib/document/components/document-list/document-list.component.scss +513 -0
- package/src/lib/document/components/document-list/document-list.component.spec.ts +486 -0
- package/src/lib/document/components/document-list/document-list.component.ts +682 -0
- package/src/lib/document/components/document-list-item/document-list-item.component.html +36 -0
- package/src/lib/document/components/document-list-item/document-list-item.component.scss +34 -0
- package/src/lib/document/components/document-list-item/document-list-item.component.spec.ts +75 -0
- package/src/lib/document/components/document-list-item/document-list-item.component.ts +40 -0
- package/src/lib/document/components/document-search/document-search.component.html +64 -0
- package/src/lib/document/components/document-search/document-search.component.scss +206 -0
- package/src/lib/document/components/document-search/document-search.component.spec.ts +82 -0
- package/src/lib/document/components/document-search/document-search.component.ts +163 -0
- package/src/lib/document/components/document-status/document-status.component.html +31 -0
- package/src/lib/document/components/document-status/document-status.component.scss +192 -0
- package/src/lib/document/components/document-status/document-status.component.spec.ts +23 -0
- package/src/lib/document/components/document-status/document-status.component.ts +87 -0
- package/src/lib/document/components/document-upload/document-upload.component.html +160 -0
- package/src/lib/document/components/document-upload/document-upload.component.scss +235 -0
- package/src/lib/document/components/document-upload/document-upload.component.spec.ts +95 -0
- package/src/lib/document/components/document-upload/document-upload.component.ts +668 -0
- package/src/lib/document/components/document-viewer/document-viewer.component.html +50 -0
- package/src/lib/document/components/document-viewer/document-viewer.component.scss +187 -0
- package/src/lib/document/components/document-viewer/document-viewer.component.spec.ts +79 -0
- package/src/lib/document/components/document-viewer/document-viewer.component.ts +261 -0
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.html +48 -0
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.scss +320 -0
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.spec.ts +59 -0
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.ts +150 -0
- package/src/lib/document/components/documents-menu/documents-menu.component.html +44 -0
- package/src/lib/document/components/documents-menu/documents-menu.component.scss +363 -0
- package/src/lib/document/components/documents-menu/documents-menu.component.spec.ts +23 -0
- package/src/lib/document/components/documents-menu/documents-menu.component.ts +316 -0
- package/src/lib/document/components/folder-block/folder-block.component.html +46 -0
- package/src/lib/document/components/folder-block/folder-block.component.scss +9 -0
- package/src/lib/document/components/folder-block/folder-block.component.spec.ts +70 -0
- package/{lib/document/components/folder-block/folder-block.component.d.ts → src/lib/document/components/folder-block/folder-block.component.ts} +28 -12
- package/src/lib/document/components/folder-container/folder-container.component.html +56 -0
- package/src/lib/document/components/folder-container/folder-container.component.scss +20 -0
- package/src/lib/document/components/folder-container/folder-container.component.spec.ts +27 -0
- package/src/lib/document/components/folder-container/folder-container.component.ts +328 -0
- package/src/lib/document/components/linked-document/linked-document.component.html +23 -0
- package/src/lib/document/components/linked-document/linked-document.component.scss +10 -0
- package/src/lib/document/components/linked-document/linked-document.component.spec.ts +61 -0
- package/src/lib/document/components/linked-document/linked-document.component.ts +49 -0
- package/src/lib/document/components/request-document/request-document.component.html +86 -0
- package/src/lib/document/components/request-document/request-document.component.scss +16 -0
- package/src/lib/document/components/request-document/request-document.component.ts +278 -0
- package/src/lib/document/components/sidebar/sidebar.component.html +75 -0
- package/src/lib/document/components/sidebar/sidebar.component.scss +157 -0
- package/src/lib/document/components/sidebar/sidebar.component.spec.ts +114 -0
- package/src/lib/document/components/sidebar/sidebar.component.ts +223 -0
- package/src/lib/document/components/user-list/user-list.component.html +33 -0
- package/src/lib/document/components/user-list/user-list.component.scss +118 -0
- package/src/lib/document/components/user-list/user-list.component.spec.ts +23 -0
- package/src/lib/document/components/user-list/user-list.component.ts +181 -0
- package/src/lib/document/constant/DOCUMENT_HISTORY.ts +52 -0
- package/src/lib/document/directives/document.directive.ts +32 -0
- package/src/lib/document/directives/permission.directive.spec.ts +0 -0
- package/src/lib/document/directives/permission.directive.ts +72 -0
- package/src/lib/document/document.module.ts +351 -0
- package/{lib/document/models/document-alert.model.d.ts → src/lib/document/models/document-alert.model.ts} +11 -4
- package/src/lib/document/models/document-category.model.ts +30 -0
- package/src/lib/document/models/document-history.model.ts +109 -0
- package/src/lib/document/models/document-list-response.model.ts +37 -0
- package/src/lib/document/models/document-type.model.ts +44 -0
- package/src/lib/document/models/document.model.ts +53 -0
- package/{lib/document/models/folder.model.d.ts → src/lib/document/models/folder.model.ts} +10 -4
- package/src/lib/document/models/status-data.model.ts +31 -0
- package/src/lib/document/models/uploaded-file-response.model.ts +7 -0
- package/src/lib/document/models/user-list.model.ts +10 -0
- package/src/lib/document/services/csv-parser.service.spec.ts +97 -0
- package/src/lib/document/services/csv-parser.service.ts +303 -0
- package/src/lib/document/services/document-actions.service.ts +125 -0
- package/src/lib/document/services/document-content-type.service.ts +193 -0
- package/src/lib/document/services/document-history-style.service.ts +138 -0
- package/src/lib/document/services/document-history.service.ts +129 -0
- package/src/lib/document/services/document-http.service.spec.ts +119 -0
- package/src/lib/document/services/document-http.service.ts +497 -0
- package/src/lib/document/services/document-list.service.ts +195 -0
- package/src/lib/document/services/document-menu.service.ts +277 -0
- package/src/lib/document/services/document-scroll.service.ts +138 -0
- package/src/lib/document/services/document-severity.service.ts +98 -0
- package/src/lib/document/services/document-table-builder.service.ts +82 -0
- package/src/lib/document/services/document-upload-business.service.ts +326 -0
- package/src/lib/document/services/document-upload-data.service.ts +82 -0
- package/src/lib/document/services/document-upload-form.service.ts +149 -0
- package/src/lib/document/services/document-upload.service.spec.ts +99 -0
- package/src/lib/document/services/document-upload.service.ts +209 -0
- package/src/lib/document/services/document-viewer.service.ts +279 -0
- package/src/lib/document/services/document-zoom.service.spec.ts +56 -0
- package/src/lib/document/services/document-zoom.service.ts +164 -0
- package/src/lib/document/services/document.service.ts +356 -0
- package/src/lib/document/services/eml-parser.service.ts +444 -0
- package/src/lib/document/services/excel-parser.service.spec.ts +66 -0
- package/src/lib/document/services/excel-parser.service.ts +483 -0
- package/src/lib/document/services/file-format.service.spec.ts +16 -0
- package/src/lib/document/services/file-format.service.ts +63 -0
- package/src/lib/document/services/status-calculator.service.ts +44 -0
- package/src/lib/document/services/user-list.service.ts +77 -0
- package/src/lib/document/state/document.query.ts +378 -0
- package/{lib/document/state/document.service.d.ts → src/lib/document/state/document.service.ts} +46 -15
- package/src/lib/document/state/document.state.ts +100 -0
- package/src/lib/document/state/document.store.ts +200 -0
- package/{public-api.d.ts → src/public-api.ts} +4 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.lib.prod.json +11 -0
- package/tsconfig.spec.json +15 -0
- package/Shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +0 -44
- package/Shared/components/table-primary/table-primary.component.d.ts +0 -31
- package/Shared/components/table-primary/table-primary.model.d.ts +0 -19
- package/Shared/constant/ERROR.d.ts +0 -52
- package/Shared/constant/SHARED.d.ts +0 -546
- package/Shared/services/app-config.service.d.ts +0 -51
- package/Shared/services/session.service.d.ts +0 -46
- package/Shared/shared.module.d.ts +0 -14
- package/fesm2022/cat-documents-ng.mjs +0 -11392
- package/fesm2022/cat-documents-ng.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/document/components/document-actions/document-actions.component.d.ts +0 -78
- package/lib/document/components/document-container/document-container.component.d.ts +0 -162
- package/lib/document/components/document-content-viewer/document-content-viewer.component.d.ts +0 -291
- package/lib/document/components/document-history/document-history.component.d.ts +0 -160
- package/lib/document/components/document-list/document-list.component.d.ts +0 -299
- package/lib/document/components/document-list-item/document-list-item.component.d.ts +0 -28
- package/lib/document/components/document-search/document-search.component.d.ts +0 -77
- package/lib/document/components/document-status/document-status.component.d.ts +0 -24
- package/lib/document/components/document-upload/document-upload.component.d.ts +0 -321
- package/lib/document/components/document-viewer/document-viewer.component.d.ts +0 -137
- package/lib/document/components/document-zoom-controls/document-zoom-controls.component.d.ts +0 -33
- package/lib/document/components/documents-menu/documents-menu.component.d.ts +0 -110
- package/lib/document/components/folder-container/folder-container.component.d.ts +0 -162
- package/lib/document/components/linked-document/linked-document.component.d.ts +0 -39
- package/lib/document/components/request-document/request-document.component.d.ts +0 -69
- package/lib/document/components/sidebar/sidebar.component.d.ts +0 -109
- package/lib/document/components/user-list/user-list.component.d.ts +0 -34
- package/lib/document/constant/DOCUMENT_HISTORY.d.ts +0 -41
- package/lib/document/directives/document.directive.d.ts +0 -20
- package/lib/document/directives/permission.directive.d.ts +0 -38
- package/lib/document/document.module.d.ts +0 -60
- package/lib/document/models/document-category.model.d.ts +0 -24
- package/lib/document/models/document-history.model.d.ts +0 -94
- package/lib/document/models/document-list-response.model.d.ts +0 -33
- package/lib/document/models/document-type.model.d.ts +0 -37
- package/lib/document/models/document.model.d.ts +0 -44
- package/lib/document/models/status-data.model.d.ts +0 -27
- package/lib/document/models/uploaded-file-response.model.d.ts +0 -7
- package/lib/document/models/user-list.model.d.ts +0 -8
- package/lib/document/services/csv-parser.service.d.ts +0 -88
- package/lib/document/services/document-actions.service.d.ts +0 -48
- package/lib/document/services/document-content-type.service.d.ts +0 -85
- package/lib/document/services/document-history-style.service.d.ts +0 -34
- package/lib/document/services/document-history.service.d.ts +0 -42
- package/lib/document/services/document-http.service.d.ts +0 -179
- package/lib/document/services/document-list.service.d.ts +0 -74
- package/lib/document/services/document-menu.service.d.ts +0 -122
- package/lib/document/services/document-scroll.service.d.ts +0 -55
- package/lib/document/services/document-table-builder.service.d.ts +0 -38
- package/lib/document/services/document-upload-business.service.d.ts +0 -107
- package/lib/document/services/document-upload-data.service.d.ts +0 -40
- package/lib/document/services/document-upload-form.service.d.ts +0 -41
- package/lib/document/services/document-upload.service.d.ts +0 -99
- package/lib/document/services/document-viewer.service.d.ts +0 -97
- package/lib/document/services/document-zoom.service.d.ts +0 -81
- package/lib/document/services/document.service.d.ts +0 -161
- package/lib/document/services/eml-parser.service.d.ts +0 -116
- package/lib/document/services/excel-parser.service.d.ts +0 -169
- package/lib/document/services/file-format.service.d.ts +0 -34
- package/lib/document/services/status-calculator.service.d.ts +0 -20
- package/lib/document/services/user-list.service.d.ts +0 -29
- package/lib/document/state/document.query.d.ts +0 -243
- package/lib/document/state/document.state.d.ts +0 -61
- package/lib/document/state/document.store.d.ts +0 -56
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { DocumentCategory, DocumentCategoryItem } from '../models/document-category.model';
|
|
3
|
+
import { DocumentStore } from '../state/document.store';
|
|
4
|
+
import { DocumentListResponse } from '../models/document-list-response.model';
|
|
5
|
+
import { SHARED } from '../../../Shared/constant/SHARED';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root'
|
|
9
|
+
})
|
|
10
|
+
export class DocumentMenuService {
|
|
11
|
+
|
|
12
|
+
constructor(private documentStore: DocumentStore) {}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Sorts categories alphabetically by label
|
|
16
|
+
* @param categories - The list of document categories to sort
|
|
17
|
+
* @returns Sorted categories array
|
|
18
|
+
*/
|
|
19
|
+
sortCategoriesAlphabetically(categories: DocumentCategory[]): DocumentCategory[] {
|
|
20
|
+
return [...categories].sort((a, b) => a.label.localeCompare(b.label));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Sorts menu items within each category alphabetically by label
|
|
25
|
+
* @param categories - The list of document categories to sort
|
|
26
|
+
* @returns Categories with sorted menu items
|
|
27
|
+
*/
|
|
28
|
+
sortMenuItemsAlphabetically(categories: DocumentCategory[]): DocumentCategory[] {
|
|
29
|
+
return categories.map(category => ({
|
|
30
|
+
...category,
|
|
31
|
+
items: category.items ? [...category.items].sort((a, b) => a.label.localeCompare(b.label)) : category.items
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Sorts both categories and their menu items alphabetically
|
|
37
|
+
* @param categories - The list of document categories to sort
|
|
38
|
+
* @returns Fully sorted categories array
|
|
39
|
+
*/
|
|
40
|
+
sortCategoriesAndMenuItems(categories: DocumentCategory[]): DocumentCategory[] {
|
|
41
|
+
const sortedCategories = this.sortCategoriesAlphabetically(categories);
|
|
42
|
+
return this.sortMenuItemsAlphabetically(sortedCategories);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Gets the category name for a given menu item _id
|
|
47
|
+
* @param menuItemId - The _id of the menu item
|
|
48
|
+
* @param categories - The list of document categories
|
|
49
|
+
* @returns The category name or null if not found
|
|
50
|
+
*/
|
|
51
|
+
getMenuItemCategory(menuItemId: string, categories: DocumentCategory[]): string | null {
|
|
52
|
+
for (const category of categories) {
|
|
53
|
+
if (category.items?.some((menuItem: DocumentCategoryItem) => menuItem._id === menuItemId)) {
|
|
54
|
+
return category.label;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Gets the menu item by its _id
|
|
62
|
+
* @param menuItemId - The _id of the menu item
|
|
63
|
+
* @param categories - The list of document categories
|
|
64
|
+
* @returns The menu item or null if not found
|
|
65
|
+
*/
|
|
66
|
+
getMenuItemById(menuItemId: string, categories: DocumentCategory[]): DocumentCategoryItem | null {
|
|
67
|
+
for (const category of categories) {
|
|
68
|
+
if (category.items) {
|
|
69
|
+
const item = category.items.find((menuItem: DocumentCategoryItem) => menuItem._id === menuItemId);
|
|
70
|
+
if (item) {
|
|
71
|
+
return item;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Handles user list visibility based on menu item category
|
|
80
|
+
* @param menuItemId - The _id of the menu item
|
|
81
|
+
* @param categories - The list of document categories
|
|
82
|
+
*/
|
|
83
|
+
handleUserListVisibility(menuItemId: string, categories: DocumentCategory[]): void {
|
|
84
|
+
const category = this.getMenuItemCategory(menuItemId, categories);
|
|
85
|
+
this.documentStore.setShowUserList(true);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Calculates total documents for a menu item
|
|
90
|
+
* @param item - The menu item
|
|
91
|
+
* @returns Total number of documents
|
|
92
|
+
*/
|
|
93
|
+
getTotalDocuments(item: DocumentCategoryItem): number {
|
|
94
|
+
const status = item.status;
|
|
95
|
+
// Handle both uppercase and lowercase keys
|
|
96
|
+
const pending = status.Pending || status.pending || 0;
|
|
97
|
+
const reviewing = status.Reviewing || status.reviewing || 0;
|
|
98
|
+
const accepted = status.Accepted || status.approved || 0; // Note: approved maps to Accepted
|
|
99
|
+
const rejected = status.Rejected || status.rejected || 0;
|
|
100
|
+
|
|
101
|
+
return pending + reviewing + accepted + rejected;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets badge value for a menu item
|
|
108
|
+
* @param item - The menu item
|
|
109
|
+
* @returns Badge value string (e.g., "2/3")
|
|
110
|
+
*/
|
|
111
|
+
getBadgeValue(item: DocumentCategoryItem): string {
|
|
112
|
+
const approved = this.getApprovedDocuments(item);
|
|
113
|
+
const total = this.getTotalDocuments(item);
|
|
114
|
+
return `${approved}/${total}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Gets badge severity based on status
|
|
119
|
+
* @param item - The menu item
|
|
120
|
+
* @returns Badge severity for PrimeNG
|
|
121
|
+
*/
|
|
122
|
+
getBadgeSeverity(item: DocumentCategoryItem): 'success' | 'info' | 'warning' | 'danger' {
|
|
123
|
+
const status = item.status;
|
|
124
|
+
const total = this.getTotalDocuments(item);
|
|
125
|
+
const pending = status.Pending || status.pending || 0;
|
|
126
|
+
const rejected = status.Rejected || status.rejected || 0;
|
|
127
|
+
const reviewing = status.Reviewing || status.reviewing || 0;
|
|
128
|
+
const approved = this.getApprovedDocuments(item);
|
|
129
|
+
|
|
130
|
+
if (total === 0) return 'info';
|
|
131
|
+
if (pending > 0) return 'info';
|
|
132
|
+
if (rejected > 0) return 'danger';
|
|
133
|
+
if (reviewing > 0) return 'warning';
|
|
134
|
+
if (approved === total && total > 0) return 'success';
|
|
135
|
+
return 'warning';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Checks if badge should be shown for a menu item
|
|
140
|
+
* @param item - The menu item
|
|
141
|
+
* @returns True if badge should be shown
|
|
142
|
+
*/
|
|
143
|
+
shouldShowBadge(item: DocumentCategoryItem): boolean {
|
|
144
|
+
return this.getTotalDocuments(item) > 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Calculates approved documents for a menu item
|
|
149
|
+
* @param item - The menu item
|
|
150
|
+
* @returns Number of approved documents
|
|
151
|
+
*/
|
|
152
|
+
getApprovedDocuments(item: DocumentCategoryItem): number {
|
|
153
|
+
const status = item.status;
|
|
154
|
+
// Handle both uppercase and lowercase keys, with approved mapping to Accepted
|
|
155
|
+
return status.Accepted || status.approved || 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Checks if a menu item's section is visible in the filtered document list
|
|
160
|
+
* @param menuItemId - The ID of the menu item to check
|
|
161
|
+
* @param documentListResponse - The filtered document list response
|
|
162
|
+
* @returns True if the section is visible, false otherwise
|
|
163
|
+
*/
|
|
164
|
+
isMenuItemSectionVisible(menuItemId: string, documentListResponse: DocumentListResponse[] | null, menuItemLabel?: string): boolean {
|
|
165
|
+
if (!menuItemId || !documentListResponse || documentListResponse.length === 0) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return documentListResponse.some(category => {
|
|
170
|
+
if (!category.label || !category.list || category.list.length === 0) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const categoryLabelLower = category.label.toLowerCase();
|
|
175
|
+
if (menuItemLabel) {
|
|
176
|
+
const menuItemLabelLower = menuItemLabel.toLowerCase();
|
|
177
|
+
if (categoryLabelLower === menuItemLabelLower) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
if (this.isSmartPartialMatch(menuItemLabelLower, categoryLabelLower)) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const menuItemIdLower = menuItemId.toLowerCase();
|
|
185
|
+
if (this.isSmartPartialMatch(menuItemIdLower, categoryLabelLower)) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return false;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Performs smart partial matching to prevent substring conflicts
|
|
195
|
+
* @param menuLabel - The menu item label to match
|
|
196
|
+
* @param categoryLabel - The category label to match against
|
|
197
|
+
* @returns True if it's a valid partial match, false otherwise
|
|
198
|
+
*/
|
|
199
|
+
private isSmartPartialMatch(menuLabel: string, categoryLabel: string): boolean {
|
|
200
|
+
// If the category label is significantly longer than menu label, it's likely a different section
|
|
201
|
+
if (categoryLabel.length > menuLabel.length + 3) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
const menuWords = menuLabel.split(/\s+/);
|
|
205
|
+
const categoryWords = categoryLabel.split(/\s+/);
|
|
206
|
+
return menuWords.every(word =>
|
|
207
|
+
categoryWords.some(catWord =>
|
|
208
|
+
catWord.toLowerCase().startsWith(word.toLowerCase()) ||
|
|
209
|
+
word.toLowerCase().startsWith(catWord.toLowerCase())
|
|
210
|
+
)
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Deselects a menu item if its section is not visible in the filtered document list
|
|
217
|
+
* @param menuItemId - The ID of the menu item to check
|
|
218
|
+
* @param documentListResponse - The filtered document list response
|
|
219
|
+
* @param menuItemLabel - The label of the menu item (optional)
|
|
220
|
+
* @returns True if the menu item was deselected, false otherwise
|
|
221
|
+
*/
|
|
222
|
+
deselectMenuItemIfSectionNotVisible(menuItemId: string, documentListResponse: DocumentListResponse[] | null, menuItemLabel?: string): boolean {
|
|
223
|
+
if (!this.isMenuItemSectionVisible(menuItemId, documentListResponse, menuItemLabel)) {
|
|
224
|
+
this.documentStore.setSelectedMenuItem(null);
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Checks if a menu item should be selectable based on the filtered document list
|
|
232
|
+
* @param menuItemId - The ID of the menu item to check
|
|
233
|
+
* @param documentListResponse - The filtered document list response
|
|
234
|
+
* @param menuItemLabel - The label of the menu item (optional)
|
|
235
|
+
* @returns True if the menu item should be selectable, false otherwise
|
|
236
|
+
*/
|
|
237
|
+
isMenuItemSelectable(menuItemId: string, documentListResponse: DocumentListResponse[] | null, menuItemLabel?: string): boolean {
|
|
238
|
+
return this.isMenuItemSectionVisible(menuItemId, documentListResponse, menuItemLabel);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Gets the selectability status for all menu items in categories
|
|
243
|
+
* @param categories - The document categories containing menu items
|
|
244
|
+
* @param documentListResponse - The filtered document list response
|
|
245
|
+
* @returns Map of menu item IDs to their selectability status
|
|
246
|
+
*/
|
|
247
|
+
getMenuItemsSelectabilityStatus(categories: DocumentCategory[], documentListResponse: DocumentListResponse[] | null): Map<string, boolean> {
|
|
248
|
+
const selectabilityMap = new Map<string, boolean>();
|
|
249
|
+
|
|
250
|
+
categories.forEach(category => {
|
|
251
|
+
if (category.items) {
|
|
252
|
+
category.items.forEach(item => {
|
|
253
|
+
const isSelectable = this.isMenuItemSelectable(item._id, documentListResponse);
|
|
254
|
+
selectabilityMap.set(item._id, isSelectable);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
return selectabilityMap;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Updates menu items with selectability status
|
|
264
|
+
* @param categories - The document categories containing menu items
|
|
265
|
+
* @param documentListResponse - The filtered document list response
|
|
266
|
+
* @returns Updated categories with selectability information
|
|
267
|
+
*/
|
|
268
|
+
updateMenuItemsWithSelectabilityStatus(categories: DocumentCategory[], documentListResponse: DocumentListResponse[] | null): DocumentCategory[] {
|
|
269
|
+
return categories.map(category => ({
|
|
270
|
+
...category,
|
|
271
|
+
items: category.items?.map(item => ({
|
|
272
|
+
...item,
|
|
273
|
+
isSelectable: this.isMenuItemSelectable(item._id, documentListResponse, item.label)
|
|
274
|
+
}))
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Injectable, OnDestroy } from '@angular/core';
|
|
2
|
+
import { DocumentStore } from '../state/document.store';
|
|
3
|
+
|
|
4
|
+
export interface ScrollTarget {
|
|
5
|
+
element: Element;
|
|
6
|
+
menuItemId: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@Injectable({
|
|
10
|
+
providedIn: 'root'
|
|
11
|
+
})
|
|
12
|
+
export class DocumentScrollService implements OnDestroy {
|
|
13
|
+
private sectionObserver: IntersectionObserver | null = null;
|
|
14
|
+
private currentObservedSection: Element | null = null;
|
|
15
|
+
private isScrolling: boolean = false;
|
|
16
|
+
private scrollHandler: (() => void) | null = null;
|
|
17
|
+
private scrollTimeout: any = null;
|
|
18
|
+
|
|
19
|
+
constructor(private documentStore: DocumentStore) {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Sets up scroll event listeners to track scrolling state
|
|
23
|
+
* @param containerElement - The container element to monitor for scroll events
|
|
24
|
+
*/
|
|
25
|
+
setupScrollListeners(containerElement: HTMLElement): void {
|
|
26
|
+
if (containerElement) {
|
|
27
|
+
this.scrollHandler = () => {
|
|
28
|
+
this.isScrolling = true;
|
|
29
|
+
if (this.scrollTimeout) {
|
|
30
|
+
clearTimeout(this.scrollTimeout);
|
|
31
|
+
}
|
|
32
|
+
this.scrollTimeout = setTimeout(() => {
|
|
33
|
+
this.isScrolling = false;
|
|
34
|
+
}, 150);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
containerElement.addEventListener('scroll', this.scrollHandler);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Sets up intersection observer to detect when the selected section scrolls out of view
|
|
43
|
+
* @param sectionElement - The section element to observe
|
|
44
|
+
* @param menuItemId - The ID of the selected menu item
|
|
45
|
+
*/
|
|
46
|
+
setupSectionObserver(sectionElement: Element, menuItemId: string): void {
|
|
47
|
+
this.disconnectSectionObserver();
|
|
48
|
+
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
if (!menuItemId || this.isScrolling) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.sectionObserver = new IntersectionObserver(
|
|
55
|
+
(entries) => {
|
|
56
|
+
entries.forEach(entry => {
|
|
57
|
+
if (entry.intersectionRatio === 0 ) {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
if (this.sectionObserver && menuItemId && entry.intersectionRatio === 0) {
|
|
60
|
+
this.documentStore.setSelectedMenuItem(null);
|
|
61
|
+
this.disconnectSectionObserver();
|
|
62
|
+
}
|
|
63
|
+
}, 200);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
threshold: [0, 0.1, 0.5, 1],
|
|
69
|
+
rootMargin: '0px'
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Always start observing regardless of current visibility
|
|
74
|
+
// The IntersectionObserver will handle visibility changes automatically
|
|
75
|
+
this.sectionObserver.observe(sectionElement);
|
|
76
|
+
this.currentObservedSection = sectionElement;
|
|
77
|
+
}, 1200);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Disconnects the section observer
|
|
82
|
+
*/
|
|
83
|
+
disconnectSectionObserver(): void {
|
|
84
|
+
if (this.sectionObserver) {
|
|
85
|
+
this.sectionObserver.disconnect();
|
|
86
|
+
this.sectionObserver = null;
|
|
87
|
+
this.currentObservedSection = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Sets the scrolling flag to true (called when starting a scroll operation)
|
|
93
|
+
*/
|
|
94
|
+
setScrolling(): void {
|
|
95
|
+
this.isScrolling = true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Resets the scrolling flag after a specified delay
|
|
100
|
+
* @param delay - Delay in milliseconds before resetting the flag
|
|
101
|
+
*/
|
|
102
|
+
resetScrollingAfterDelay(delay: number = 1200): void {
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
this.isScrolling = false;
|
|
105
|
+
}, delay);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Gets the current scrolling state
|
|
110
|
+
*/
|
|
111
|
+
get isCurrentlyScrolling(): boolean {
|
|
112
|
+
return this.isScrolling;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Cleans up all resources
|
|
117
|
+
*/
|
|
118
|
+
ngOnDestroy(): void {
|
|
119
|
+
this.disconnectSectionObserver();
|
|
120
|
+
this.cleanupScrollListeners();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Removes scroll event listeners
|
|
125
|
+
* @param containerElement - The container element to remove listeners from
|
|
126
|
+
*/
|
|
127
|
+
cleanupScrollListeners(containerElement?: HTMLElement): void {
|
|
128
|
+
if (containerElement && this.scrollHandler) {
|
|
129
|
+
containerElement.removeEventListener('scroll', this.scrollHandler);
|
|
130
|
+
this.scrollHandler = null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (this.scrollTimeout) {
|
|
134
|
+
clearTimeout(this.scrollTimeout);
|
|
135
|
+
this.scrollTimeout = null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { SHARED } from '../../../Shared/constant/SHARED';
|
|
3
|
+
import { DocumentListItem } from '../models/document-list-response.model';
|
|
4
|
+
|
|
5
|
+
export type SeverityLevel = 'success' | 'info' | 'warning' | 'danger';
|
|
6
|
+
|
|
7
|
+
@Injectable({
|
|
8
|
+
providedIn: 'root'
|
|
9
|
+
})
|
|
10
|
+
export class DocumentSeverityService {
|
|
11
|
+
|
|
12
|
+
constructor() {}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Calculate severity for a list of documents based on their statuses
|
|
16
|
+
* This is the centralized severity calculation logic used across the application
|
|
17
|
+
* @param documents The list of documents to calculate severity for
|
|
18
|
+
* @returns Severity level for the document list
|
|
19
|
+
*/
|
|
20
|
+
calculateSeverity(documents: DocumentListItem[]): SeverityLevel {
|
|
21
|
+
if (!documents || documents.length === 0) {
|
|
22
|
+
return 'info';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const total = documents.length;
|
|
26
|
+
const pending = documents.filter(doc =>
|
|
27
|
+
doc.status.toLowerCase() === SHARED.PENDING_STATUS
|
|
28
|
+
).length;
|
|
29
|
+
const rejected = documents.filter(doc =>
|
|
30
|
+
doc.status.toLowerCase() === SHARED.REJECTED_STATUS
|
|
31
|
+
).length;
|
|
32
|
+
const reviewing = documents.filter(doc =>
|
|
33
|
+
doc.status.toLowerCase() === SHARED.REVIEWING_STATUS
|
|
34
|
+
).length;
|
|
35
|
+
const approved = documents.filter(doc =>
|
|
36
|
+
doc.status.toLowerCase() === SHARED.APPROVED_STATUS ||
|
|
37
|
+
doc.status.toLowerCase() === SHARED.UPLOADED_STATUS
|
|
38
|
+
).length;
|
|
39
|
+
|
|
40
|
+
// Severity calculation logic:
|
|
41
|
+
// - info (grey): No documents or has pending documents
|
|
42
|
+
// - danger (red): Has rejected documents
|
|
43
|
+
// - warning (orange): Has documents under review or mixed status
|
|
44
|
+
// - success (green): All documents are approved
|
|
45
|
+
if (total === 0) return 'info';
|
|
46
|
+
if (pending > 0) return 'info';
|
|
47
|
+
if (rejected > 0) return 'danger';
|
|
48
|
+
if (reviewing > 0) return 'warning';
|
|
49
|
+
if (approved === total && total > 0) return 'success';
|
|
50
|
+
return 'warning';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Calculate severity for a category based on document statuses
|
|
55
|
+
* @param category The document category
|
|
56
|
+
* @returns Severity level for the category
|
|
57
|
+
*/
|
|
58
|
+
calculateCategorySeverity(category: any): SeverityLevel {
|
|
59
|
+
if (!category.list || category.list.length === 0) {
|
|
60
|
+
return 'info';
|
|
61
|
+
}
|
|
62
|
+
return this.calculateSeverity(category.list);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Calculate severity for a menu item based on status counts
|
|
67
|
+
* @param status The status object with counts
|
|
68
|
+
* @returns Severity level for the menu item
|
|
69
|
+
*/
|
|
70
|
+
calculateMenuItemSeverity(status: any): SeverityLevel {
|
|
71
|
+
const total = this.getTotalFromStatus(status);
|
|
72
|
+
const pending = status.Pending || status.pending || 0;
|
|
73
|
+
const rejected = status.Rejected || status.rejected || 0;
|
|
74
|
+
const reviewing = status.Reviewing || status.reviewing || 0;
|
|
75
|
+
const approved = status.Accepted || status.approved || 0;
|
|
76
|
+
|
|
77
|
+
if (total === 0) return 'info';
|
|
78
|
+
if (pending > 0) return 'info';
|
|
79
|
+
if (rejected > 0) return 'danger';
|
|
80
|
+
if (reviewing > 0) return 'warning';
|
|
81
|
+
if (approved === total && total > 0) return 'success';
|
|
82
|
+
return 'warning';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Helper method to get total count from status object
|
|
87
|
+
* @param status The status object
|
|
88
|
+
* @returns Total count
|
|
89
|
+
*/
|
|
90
|
+
private getTotalFromStatus(status: any): number {
|
|
91
|
+
const pending = status.Pending || status.pending || 0;
|
|
92
|
+
const reviewing = status.Reviewing || status.reviewing || 0;
|
|
93
|
+
const accepted = status.Accepted || status.approved || 0;
|
|
94
|
+
const rejected = status.Rejected || status.rejected || 0;
|
|
95
|
+
|
|
96
|
+
return pending + reviewing + accepted + rejected;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { DocumentListResponse, DocumentListItem } from '../models/document-list-response.model';
|
|
3
|
+
import { SHARED } from '../../../Shared/constant/SHARED';
|
|
4
|
+
import { TableData } from '../../../Shared/components/table-primary/table-primary.model';
|
|
5
|
+
|
|
6
|
+
@Injectable({
|
|
7
|
+
providedIn: 'root'
|
|
8
|
+
})
|
|
9
|
+
export class DocumentTableBuilderService {
|
|
10
|
+
|
|
11
|
+
constructor() { }
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Builds a single table from document list items
|
|
15
|
+
* @param documents Array of document list items
|
|
16
|
+
* @returns TableData object
|
|
17
|
+
*/
|
|
18
|
+
buildDocumentTable(documents: DocumentListItem[]): TableData {
|
|
19
|
+
const columns = SHARED.DOCUMENT_TABLE_COLUMNS.filter(col => col.type !== SHARED.ACTIONS);
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
columns: columns,
|
|
23
|
+
data: documents
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Gets completion count for a category
|
|
29
|
+
* @param category Document category
|
|
30
|
+
* @returns Completion string (e.g., "2/4")
|
|
31
|
+
*/
|
|
32
|
+
getCompletionCount(category: DocumentListResponse): string {
|
|
33
|
+
const total = category.list.length;
|
|
34
|
+
const completed = category.list.filter(doc =>
|
|
35
|
+
doc.status.toLowerCase() === SHARED.APPROVED ||
|
|
36
|
+
doc.status.toLowerCase() === SHARED.UPLOADED
|
|
37
|
+
).length;
|
|
38
|
+
return `${completed}/${total}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Gets pending document count for a category
|
|
43
|
+
* @param category Document category
|
|
44
|
+
* @returns Number of pending documents
|
|
45
|
+
*/
|
|
46
|
+
getPendingDocumentCount(category: DocumentListResponse): number {
|
|
47
|
+
return category.totalDocs - category.acceptedDocs;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Gets approved document count for a category
|
|
52
|
+
* @param category Document category
|
|
53
|
+
* @returns Number of approved documents
|
|
54
|
+
*/
|
|
55
|
+
getApprovedDocumentCount(category: DocumentListResponse): number {
|
|
56
|
+
return category.acceptedDocs;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Transforms document model to document list item
|
|
61
|
+
* @param documents Array of DocumentModel
|
|
62
|
+
* @returns Array of DocumentListItem
|
|
63
|
+
*/
|
|
64
|
+
transformDocumentModelToListItem(documents: any[]): DocumentListItem[] {
|
|
65
|
+
return documents.map(doc => {
|
|
66
|
+
return {
|
|
67
|
+
_id: doc._id || SHARED.EMPTY,
|
|
68
|
+
fileName: doc.fileName || SHARED.EMPTY,
|
|
69
|
+
docName: doc.docName || doc.documentName || SHARED.EMPTY,
|
|
70
|
+
fileSize: doc.fileSize || SHARED.EMPTY,
|
|
71
|
+
documentUrl: doc.documentUrl || doc.url || SHARED.EMPTY,
|
|
72
|
+
status: doc.status || SHARED.PENDING,
|
|
73
|
+
uploadedOn: doc.uploadedOn || doc.uploadDate || SHARED.EMPTY,
|
|
74
|
+
ownerName: doc.ownerName || doc.applicantName || SHARED.EMPTY,
|
|
75
|
+
contentType: doc.contentType || SHARED.EMPTY,
|
|
76
|
+
isUploaded: doc.isUploaded || false,
|
|
77
|
+
documentType: doc.documentType || SHARED.EMPTY,
|
|
78
|
+
aliasName: doc.aliasName || SHARED.EMPTY
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|