cat-documents-ng 1.0.6 → 1.0.7
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/Shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +44 -0
- package/Shared/components/table-primary/table-primary.component.d.ts +31 -0
- package/Shared/components/table-primary/table-primary.model.d.ts +19 -0
- package/Shared/constant/ERROR.d.ts +52 -0
- package/Shared/constant/SHARED.d.ts +546 -0
- package/{src/Shared/constant/URLS.ts → Shared/constant/URLS.d.ts} +25 -31
- package/Shared/services/app-config.service.d.ts +51 -0
- package/{src/Shared/services/global-error.handler.ts → Shared/services/global-error.handler.d.ts} +9 -11
- package/Shared/services/session.service.d.ts +46 -0
- package/Shared/shared.module.d.ts +14 -0
- package/fesm2022/cat-documents-ng.mjs +11405 -0
- package/fesm2022/cat-documents-ng.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/document/components/document-actions/document-actions.component.d.ts +78 -0
- package/lib/document/components/document-container/document-container.component.d.ts +162 -0
- package/lib/document/components/document-content-viewer/document-content-viewer.component.d.ts +291 -0
- package/lib/document/components/document-history/document-history.component.d.ts +160 -0
- package/lib/document/components/document-list/document-list.component.d.ts +299 -0
- package/lib/document/components/document-list-item/document-list-item.component.d.ts +28 -0
- package/lib/document/components/document-search/document-search.component.d.ts +77 -0
- package/lib/document/components/document-status/document-status.component.d.ts +24 -0
- package/lib/document/components/document-upload/document-upload.component.d.ts +321 -0
- package/lib/document/components/document-viewer/document-viewer.component.d.ts +137 -0
- package/lib/document/components/document-zoom-controls/document-zoom-controls.component.d.ts +33 -0
- package/lib/document/components/documents-menu/documents-menu.component.d.ts +110 -0
- package/{src/lib/document/components/folder-block/folder-block.component.ts → lib/document/components/folder-block/folder-block.component.d.ts} +12 -28
- package/lib/document/components/folder-container/folder-container.component.d.ts +162 -0
- package/lib/document/components/linked-document/linked-document.component.d.ts +39 -0
- package/lib/document/components/request-document/request-document.component.d.ts +69 -0
- package/lib/document/components/sidebar/sidebar.component.d.ts +109 -0
- package/lib/document/components/user-list/user-list.component.d.ts +34 -0
- package/lib/document/constant/DOCUMENT_HISTORY.d.ts +41 -0
- package/lib/document/directives/document.directive.d.ts +20 -0
- package/lib/document/directives/permission.directive.d.ts +38 -0
- package/lib/document/document.module.d.ts +60 -0
- package/{src/lib/document/models/document-alert.model.ts → lib/document/models/document-alert.model.d.ts} +4 -11
- package/lib/document/models/document-category.model.d.ts +24 -0
- package/lib/document/models/document-history.model.d.ts +94 -0
- package/lib/document/models/document-list-response.model.d.ts +33 -0
- package/lib/document/models/document-type.model.d.ts +37 -0
- package/lib/document/models/document.model.d.ts +44 -0
- package/{src/lib/document/models/folder.model.ts → lib/document/models/folder.model.d.ts} +4 -10
- package/lib/document/models/status-data.model.d.ts +27 -0
- package/lib/document/models/uploaded-file-response.model.d.ts +7 -0
- package/lib/document/models/user-list.model.d.ts +8 -0
- package/lib/document/services/csv-parser.service.d.ts +88 -0
- package/lib/document/services/document-actions.service.d.ts +48 -0
- package/lib/document/services/document-content-type.service.d.ts +85 -0
- package/lib/document/services/document-history-style.service.d.ts +34 -0
- package/lib/document/services/document-history.service.d.ts +42 -0
- package/lib/document/services/document-http.service.d.ts +179 -0
- package/lib/document/services/document-list.service.d.ts +74 -0
- package/lib/document/services/document-menu.service.d.ts +122 -0
- package/lib/document/services/document-scroll.service.d.ts +55 -0
- package/lib/document/services/document-table-builder.service.d.ts +38 -0
- package/lib/document/services/document-upload-business.service.d.ts +107 -0
- package/lib/document/services/document-upload-data.service.d.ts +40 -0
- package/lib/document/services/document-upload-form.service.d.ts +41 -0
- package/lib/document/services/document-upload.service.d.ts +99 -0
- package/lib/document/services/document-viewer.service.d.ts +97 -0
- package/lib/document/services/document-zoom.service.d.ts +81 -0
- package/lib/document/services/document.service.d.ts +161 -0
- package/lib/document/services/eml-parser.service.d.ts +116 -0
- package/lib/document/services/excel-parser.service.d.ts +169 -0
- package/lib/document/services/file-format.service.d.ts +34 -0
- package/lib/document/services/status-calculator.service.d.ts +20 -0
- package/lib/document/services/user-list.service.d.ts +29 -0
- package/lib/document/state/document.query.d.ts +243 -0
- package/{src/lib/document/state/document.service.ts → lib/document/state/document.service.d.ts} +15 -46
- package/lib/document/state/document.state.d.ts +61 -0
- package/lib/document/state/document.store.d.ts +56 -0
- package/package.json +11 -5
- package/{src/public-api.ts → public-api.d.ts} +0 -4
- package/ng-package.json +0 -10
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.html +0 -3
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.scss +0 -13
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.spec.ts +0 -70
- package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.ts +0 -133
- package/src/Shared/components/table-primary/table-primary.component.html +0 -66
- package/src/Shared/components/table-primary/table-primary.component.scss +0 -227
- package/src/Shared/components/table-primary/table-primary.component.spec.ts +0 -23
- package/src/Shared/components/table-primary/table-primary.component.ts +0 -143
- package/src/Shared/components/table-primary/table-primary.model.ts +0 -21
- package/src/Shared/constant/ERROR.ts +0 -55
- package/src/Shared/constant/PERMISSIONS.ts +0 -17
- package/src/Shared/constant/SHARED.ts +0 -936
- package/src/Shared/services/app-config.service.spec.ts +0 -19
- package/src/Shared/services/app-config.service.ts +0 -73
- package/src/Shared/services/session.service.spec.ts +0 -16
- package/src/Shared/services/session.service.ts +0 -76
- package/src/Shared/shared.module.ts +0 -25
- package/src/lib/document/components/csv-viewer/csv-viewer.component.ts +0 -1
- package/src/lib/document/components/document-actions/document-actions.component.html +0 -59
- package/src/lib/document/components/document-actions/document-actions.component.scss +0 -362
- package/src/lib/document/components/document-actions/document-actions.component.spec.ts +0 -297
- package/src/lib/document/components/document-actions/document-actions.component.ts +0 -163
- package/src/lib/document/components/document-container/document-container.component.html +0 -36
- package/src/lib/document/components/document-container/document-container.component.scss +0 -144
- package/src/lib/document/components/document-container/document-container.component.spec.ts +0 -110
- package/src/lib/document/components/document-container/document-container.component.ts +0 -363
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.html +0 -332
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.scss +0 -1877
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.spec.ts +0 -258
- package/src/lib/document/components/document-content-viewer/document-content-viewer.component.ts +0 -664
- package/src/lib/document/components/document-history/document-history.component.html +0 -96
- package/src/lib/document/components/document-history/document-history.component.scss +0 -392
- package/src/lib/document/components/document-history/document-history.component.spec.ts +0 -93
- package/src/lib/document/components/document-history/document-history.component.ts +0 -373
- package/src/lib/document/components/document-list/document-list.component.html +0 -46
- package/src/lib/document/components/document-list/document-list.component.scss +0 -513
- package/src/lib/document/components/document-list/document-list.component.spec.ts +0 -486
- package/src/lib/document/components/document-list/document-list.component.ts +0 -682
- package/src/lib/document/components/document-list-item/document-list-item.component.html +0 -36
- package/src/lib/document/components/document-list-item/document-list-item.component.scss +0 -34
- package/src/lib/document/components/document-list-item/document-list-item.component.spec.ts +0 -75
- package/src/lib/document/components/document-list-item/document-list-item.component.ts +0 -40
- package/src/lib/document/components/document-search/document-search.component.html +0 -64
- package/src/lib/document/components/document-search/document-search.component.scss +0 -206
- package/src/lib/document/components/document-search/document-search.component.spec.ts +0 -82
- package/src/lib/document/components/document-search/document-search.component.ts +0 -163
- package/src/lib/document/components/document-status/document-status.component.html +0 -31
- package/src/lib/document/components/document-status/document-status.component.scss +0 -192
- package/src/lib/document/components/document-status/document-status.component.spec.ts +0 -23
- package/src/lib/document/components/document-status/document-status.component.ts +0 -87
- package/src/lib/document/components/document-upload/document-upload.component.html +0 -160
- package/src/lib/document/components/document-upload/document-upload.component.scss +0 -235
- package/src/lib/document/components/document-upload/document-upload.component.spec.ts +0 -95
- package/src/lib/document/components/document-upload/document-upload.component.ts +0 -668
- package/src/lib/document/components/document-viewer/document-viewer.component.html +0 -50
- package/src/lib/document/components/document-viewer/document-viewer.component.scss +0 -187
- package/src/lib/document/components/document-viewer/document-viewer.component.spec.ts +0 -79
- package/src/lib/document/components/document-viewer/document-viewer.component.ts +0 -261
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.html +0 -48
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.scss +0 -320
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.spec.ts +0 -59
- package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.ts +0 -150
- package/src/lib/document/components/documents-menu/documents-menu.component.html +0 -44
- package/src/lib/document/components/documents-menu/documents-menu.component.scss +0 -363
- package/src/lib/document/components/documents-menu/documents-menu.component.spec.ts +0 -23
- package/src/lib/document/components/documents-menu/documents-menu.component.ts +0 -316
- package/src/lib/document/components/folder-block/folder-block.component.html +0 -46
- package/src/lib/document/components/folder-block/folder-block.component.scss +0 -9
- package/src/lib/document/components/folder-block/folder-block.component.spec.ts +0 -70
- package/src/lib/document/components/folder-container/folder-container.component.html +0 -56
- package/src/lib/document/components/folder-container/folder-container.component.scss +0 -20
- package/src/lib/document/components/folder-container/folder-container.component.spec.ts +0 -27
- package/src/lib/document/components/folder-container/folder-container.component.ts +0 -328
- package/src/lib/document/components/linked-document/linked-document.component.html +0 -23
- package/src/lib/document/components/linked-document/linked-document.component.scss +0 -10
- package/src/lib/document/components/linked-document/linked-document.component.spec.ts +0 -61
- package/src/lib/document/components/linked-document/linked-document.component.ts +0 -49
- package/src/lib/document/components/request-document/request-document.component.html +0 -86
- package/src/lib/document/components/request-document/request-document.component.scss +0 -16
- package/src/lib/document/components/request-document/request-document.component.ts +0 -278
- package/src/lib/document/components/sidebar/sidebar.component.html +0 -75
- package/src/lib/document/components/sidebar/sidebar.component.scss +0 -157
- package/src/lib/document/components/sidebar/sidebar.component.spec.ts +0 -114
- package/src/lib/document/components/sidebar/sidebar.component.ts +0 -223
- package/src/lib/document/components/user-list/user-list.component.html +0 -33
- package/src/lib/document/components/user-list/user-list.component.scss +0 -118
- package/src/lib/document/components/user-list/user-list.component.spec.ts +0 -23
- package/src/lib/document/components/user-list/user-list.component.ts +0 -181
- package/src/lib/document/constant/DOCUMENT_HISTORY.ts +0 -52
- package/src/lib/document/directives/document.directive.ts +0 -32
- package/src/lib/document/directives/permission.directive.spec.ts +0 -0
- package/src/lib/document/directives/permission.directive.ts +0 -72
- package/src/lib/document/document.module.ts +0 -351
- package/src/lib/document/models/document-category.model.ts +0 -30
- package/src/lib/document/models/document-history.model.ts +0 -109
- package/src/lib/document/models/document-list-response.model.ts +0 -37
- package/src/lib/document/models/document-type.model.ts +0 -44
- package/src/lib/document/models/document.model.ts +0 -53
- package/src/lib/document/models/status-data.model.ts +0 -31
- package/src/lib/document/models/uploaded-file-response.model.ts +0 -7
- package/src/lib/document/models/user-list.model.ts +0 -10
- package/src/lib/document/services/csv-parser.service.spec.ts +0 -97
- package/src/lib/document/services/csv-parser.service.ts +0 -303
- package/src/lib/document/services/document-actions.service.ts +0 -125
- package/src/lib/document/services/document-content-type.service.ts +0 -193
- package/src/lib/document/services/document-history-style.service.ts +0 -138
- package/src/lib/document/services/document-history.service.ts +0 -129
- package/src/lib/document/services/document-http.service.spec.ts +0 -119
- package/src/lib/document/services/document-http.service.ts +0 -497
- package/src/lib/document/services/document-list.service.ts +0 -195
- package/src/lib/document/services/document-menu.service.ts +0 -277
- package/src/lib/document/services/document-scroll.service.ts +0 -138
- package/src/lib/document/services/document-severity.service.ts +0 -98
- package/src/lib/document/services/document-table-builder.service.ts +0 -82
- package/src/lib/document/services/document-upload-business.service.ts +0 -326
- package/src/lib/document/services/document-upload-data.service.ts +0 -82
- package/src/lib/document/services/document-upload-form.service.ts +0 -149
- package/src/lib/document/services/document-upload.service.spec.ts +0 -99
- package/src/lib/document/services/document-upload.service.ts +0 -209
- package/src/lib/document/services/document-viewer.service.ts +0 -279
- package/src/lib/document/services/document-zoom.service.spec.ts +0 -56
- package/src/lib/document/services/document-zoom.service.ts +0 -164
- package/src/lib/document/services/document.service.ts +0 -356
- package/src/lib/document/services/eml-parser.service.ts +0 -444
- package/src/lib/document/services/excel-parser.service.spec.ts +0 -66
- package/src/lib/document/services/excel-parser.service.ts +0 -483
- package/src/lib/document/services/file-format.service.spec.ts +0 -16
- package/src/lib/document/services/file-format.service.ts +0 -63
- package/src/lib/document/services/status-calculator.service.ts +0 -44
- package/src/lib/document/services/user-list.service.ts +0 -77
- package/src/lib/document/state/document.query.ts +0 -378
- package/src/lib/document/state/document.state.ts +0 -100
- package/src/lib/document/state/document.store.ts +0 -200
- package/tsconfig.lib.json +0 -15
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -15
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* DocumentTypeModel
|
|
4
|
-
* @interface DocumentTypeModel Model for document types.
|
|
5
|
-
* @typedef {DocumentTypeModel} Model for document types.
|
|
6
|
-
*/
|
|
7
|
-
export interface DocumentTypeModel {
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* The label for the document type.
|
|
11
|
-
* @type {string}
|
|
12
|
-
* @memberof DocumentTypeModel
|
|
13
|
-
*/
|
|
14
|
-
label?: string,
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* The match rules for the document type.
|
|
18
|
-
* @type {string}
|
|
19
|
-
* @memberof DocumentTypeModel
|
|
20
|
-
*/
|
|
21
|
-
matchRules?: string,
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The name of the document type.
|
|
25
|
-
* @type {string}
|
|
26
|
-
* @memberof DocumentTypeModel
|
|
27
|
-
*/
|
|
28
|
-
name?: string,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* The parent document type ID.
|
|
33
|
-
* @type {string}
|
|
34
|
-
* @memberof DocumentTypeModel
|
|
35
|
-
*/
|
|
36
|
-
parentDocumentTypeId?: string,
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* The document type ID.
|
|
40
|
-
* @type {string}
|
|
41
|
-
* @memberof DocumentTypeModel
|
|
42
|
-
*/
|
|
43
|
-
_id: string
|
|
44
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { SHARED } from "../../../Shared/constant/SHARED";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents a document model.
|
|
5
|
-
*
|
|
6
|
-
* This class contains the structure for document-related data, including file name,
|
|
7
|
-
* status, and document URL.
|
|
8
|
-
*/
|
|
9
|
-
export class DocumentModel {
|
|
10
|
-
/**
|
|
11
|
-
* The unique identifier for the document.
|
|
12
|
-
* @type {string}
|
|
13
|
-
*/
|
|
14
|
-
_id: string = SHARED.EMPTY;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* The name of the document file.
|
|
18
|
-
* @type {?string}
|
|
19
|
-
*/
|
|
20
|
-
fileName?: string;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The current status of the document.
|
|
24
|
-
* @type {?string}
|
|
25
|
-
*/
|
|
26
|
-
status?: string;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* The URL where the document is hosted or stored.
|
|
30
|
-
* @type {?string}
|
|
31
|
-
*/
|
|
32
|
-
documentUrl?: string;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Date of document get uploaded
|
|
36
|
-
* @type {?Date}
|
|
37
|
-
*/
|
|
38
|
-
createdAt?: Date
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Shows the type of document
|
|
42
|
-
* @type {?string}
|
|
43
|
-
*/
|
|
44
|
-
documentTypeName?:string;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Shows the type of content
|
|
48
|
-
* @type {?string}
|
|
49
|
-
*/
|
|
50
|
-
contentType?: string;
|
|
51
|
-
|
|
52
|
-
documentName?: string;
|
|
53
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model representing status data for documents.
|
|
3
|
-
* @interface StatusDataModel
|
|
4
|
-
*/
|
|
5
|
-
export interface StatusDataModel {
|
|
6
|
-
/**
|
|
7
|
-
* The status name (e.g., 'Approved', 'Pending', 'Rejected')
|
|
8
|
-
* @type {string}
|
|
9
|
-
*/
|
|
10
|
-
status: string;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* The count of documents with this status
|
|
14
|
-
* @type {number}
|
|
15
|
-
*/
|
|
16
|
-
count: number;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* The color associated with this status for UI display
|
|
20
|
-
* @type {string}
|
|
21
|
-
*/
|
|
22
|
-
color?: string;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The icon class associated with this status
|
|
26
|
-
* @type {string}
|
|
27
|
-
*/
|
|
28
|
-
icon?: string;
|
|
29
|
-
|
|
30
|
-
_id ?: string
|
|
31
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
import { CsvParserService, ParsedCsvData } from './csv-parser.service';
|
|
3
|
-
|
|
4
|
-
describe('CsvParserService', () => {
|
|
5
|
-
let service: CsvParserService;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
TestBed.configureTestingModule({});
|
|
9
|
-
service = TestBed.inject(CsvParserService);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('should be created', () => {
|
|
13
|
-
expect(service).toBeTruthy();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should parse simple CSV data correctly', () => {
|
|
17
|
-
const csvContent = 'Name,Age,City\nJohn,25,New York\nJane,30,Los Angeles';
|
|
18
|
-
const result = service.parseCsvData(csvContent);
|
|
19
|
-
|
|
20
|
-
expect(result.headers).toEqual(['Name', 'Age', 'City']);
|
|
21
|
-
expect(result.rows).toEqual([
|
|
22
|
-
['John', '25', 'New York'],
|
|
23
|
-
['Jane', '30', 'Los Angeles']
|
|
24
|
-
]);
|
|
25
|
-
expect(result.totalRows).toBe(2);
|
|
26
|
-
expect(result.totalColumns).toBe(3);
|
|
27
|
-
expect(result.hasHeaders).toBe(true);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should handle CSV without headers', () => {
|
|
31
|
-
const csvContent = 'John,25,New York\nJane,30,Los Angeles';
|
|
32
|
-
const result = service.parseCsvData(csvContent, { hasHeaders: false });
|
|
33
|
-
|
|
34
|
-
expect(result.headers).toEqual(['Column 1', 'Column 2', 'Column 3']);
|
|
35
|
-
expect(result.rows).toEqual([
|
|
36
|
-
['John', '25', 'New York'],
|
|
37
|
-
['Jane', '30', 'Los Angeles']
|
|
38
|
-
]);
|
|
39
|
-
expect(result.hasHeaders).toBe(false);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should handle quoted fields with commas', () => {
|
|
43
|
-
const csvContent = 'Name,Description,Value\nJohn,"Smith, Jr.",25\nJane,"Doe, Sr.",30';
|
|
44
|
-
const result = service.parseCsvData(csvContent);
|
|
45
|
-
|
|
46
|
-
expect(result.headers).toEqual(['Name', 'Description', 'Value']);
|
|
47
|
-
expect(result.rows).toEqual([
|
|
48
|
-
['John', 'Smith, Jr.', '25'],
|
|
49
|
-
['Jane', 'Doe, Sr.', '30']
|
|
50
|
-
]);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should handle empty CSV content', () => {
|
|
54
|
-
const result = service.parseCsvData('');
|
|
55
|
-
|
|
56
|
-
expect(result.headers).toEqual([]);
|
|
57
|
-
expect(result.rows).toEqual([]);
|
|
58
|
-
expect(result.totalRows).toBe(0);
|
|
59
|
-
expect(result.totalColumns).toBe(0);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should validate CSV content correctly', () => {
|
|
63
|
-
const validCsv = 'Name,Age\nJohn,25\nJane,30';
|
|
64
|
-
const invalidCsv = 'Name,Age\nJohn,25\nJane,30,Extra';
|
|
65
|
-
|
|
66
|
-
const validResult = service.validateCsvContent(validCsv);
|
|
67
|
-
const invalidResult = service.validateCsvContent(invalidCsv);
|
|
68
|
-
|
|
69
|
-
expect(validResult.isValid).toBe(true);
|
|
70
|
-
expect(validResult.errors).toEqual([]);
|
|
71
|
-
|
|
72
|
-
expect(invalidResult.isValid).toBe(false);
|
|
73
|
-
expect(invalidResult.errors.length).toBeGreaterThan(0);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should export data to CSV format', () => {
|
|
77
|
-
const data = [['John', '25'], ['Jane', '30']];
|
|
78
|
-
const headers = ['Name', 'Age'];
|
|
79
|
-
|
|
80
|
-
const csvOutput = service.exportToCsv(data, headers);
|
|
81
|
-
const expected = 'Name,Age\nJohn,25\nJane,30';
|
|
82
|
-
|
|
83
|
-
expect(csvOutput).toBe(expected);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should get CSV preview with limited rows', () => {
|
|
87
|
-
const csvContent = 'Name,Age,City\nJohn,25,NY\nJane,30,LA\nBob,35,CHI\nAlice,28,SF';
|
|
88
|
-
const preview = service.getCsvPreview(csvContent, 2);
|
|
89
|
-
|
|
90
|
-
expect(preview.totalRows).toBe(2);
|
|
91
|
-
expect(preview.headers).toEqual(['Name', 'Age', 'City']);
|
|
92
|
-
expect(preview.rows).toEqual([
|
|
93
|
-
['John', '25', 'NY'],
|
|
94
|
-
['Jane', '30', 'LA']
|
|
95
|
-
]);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { SHARED } from '../../../Shared/constant/SHARED';
|
|
3
|
-
|
|
4
|
-
export interface CsvRowData {
|
|
5
|
-
cells: Array<{
|
|
6
|
-
value: string;
|
|
7
|
-
isHeader?: boolean;
|
|
8
|
-
style?: any;
|
|
9
|
-
}>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface ParsedCsvData {
|
|
13
|
-
headers: string[];
|
|
14
|
-
rows: string[][];
|
|
15
|
-
styledData: CsvRowData[];
|
|
16
|
-
totalRows: number;
|
|
17
|
-
totalColumns: number;
|
|
18
|
-
hasHeaders: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@Injectable({
|
|
22
|
-
providedIn: 'root'
|
|
23
|
-
})
|
|
24
|
-
export class CsvParserService {
|
|
25
|
-
|
|
26
|
-
constructor() { }
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parses CSV data from a string
|
|
30
|
-
* @param csvContent - The CSV content as a string
|
|
31
|
-
* @param options - Parsing options
|
|
32
|
-
* @returns Parsed CSV data
|
|
33
|
-
*/
|
|
34
|
-
parseCsvData(csvContent: string, options: {
|
|
35
|
-
delimiter?: string;
|
|
36
|
-
hasHeaders?: boolean;
|
|
37
|
-
maxRows?: number;
|
|
38
|
-
} = {}): ParsedCsvData {
|
|
39
|
-
const {
|
|
40
|
-
delimiter = ',',
|
|
41
|
-
hasHeaders = true,
|
|
42
|
-
maxRows = 1000
|
|
43
|
-
} = options;
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
// Split content into lines and filter out empty lines
|
|
47
|
-
const lines = csvContent
|
|
48
|
-
.split('\n')
|
|
49
|
-
.map(line => line.trim())
|
|
50
|
-
.filter(line => line.length > 0);
|
|
51
|
-
|
|
52
|
-
if (lines.length === 0) {
|
|
53
|
-
return this.createEmptyCsvData();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Parse each line
|
|
57
|
-
const parsedRows: string[][] = [];
|
|
58
|
-
let headers: string[] = [];
|
|
59
|
-
|
|
60
|
-
lines.forEach((line, index) => {
|
|
61
|
-
if (index >= maxRows) return;
|
|
62
|
-
|
|
63
|
-
const row = this.parseCsvLine(line, delimiter);
|
|
64
|
-
if (row.length > 0) {
|
|
65
|
-
parsedRows.push(row);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// Extract headers if specified
|
|
70
|
-
if (hasHeaders && parsedRows.length > 0) {
|
|
71
|
-
headers = parsedRows[0];
|
|
72
|
-
parsedRows.splice(0, 1); // Remove header row from data
|
|
73
|
-
} else if (parsedRows.length > 0) {
|
|
74
|
-
// Generate default headers if none provided
|
|
75
|
-
headers = parsedRows[0].map((_, index) => `Column ${index + 1}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Create styled data for display
|
|
79
|
-
const styledData = this.createStyledData(headers, parsedRows, hasHeaders);
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
headers,
|
|
83
|
-
rows: parsedRows,
|
|
84
|
-
styledData,
|
|
85
|
-
totalRows: parsedRows.length,
|
|
86
|
-
totalColumns: headers.length,
|
|
87
|
-
hasHeaders
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
} catch (error) {
|
|
91
|
-
console.error('Error parsing CSV data:', error);
|
|
92
|
-
return this.createEmptyCsvData();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Parses a single CSV line with proper handling of quoted fields
|
|
98
|
-
* @param line - Single CSV line
|
|
99
|
-
* @param delimiter - Field delimiter
|
|
100
|
-
* @returns Array of field values
|
|
101
|
-
*/
|
|
102
|
-
private parseCsvLine(line: string, delimiter: string): string[] {
|
|
103
|
-
const result: string[] = [];
|
|
104
|
-
let current = '';
|
|
105
|
-
let inQuotes = false;
|
|
106
|
-
let i = 0;
|
|
107
|
-
|
|
108
|
-
while (i < line.length) {
|
|
109
|
-
const char = line[i];
|
|
110
|
-
|
|
111
|
-
if (char === '"') {
|
|
112
|
-
if (inQuotes && line[i + 1] === '"') {
|
|
113
|
-
// Escaped quote
|
|
114
|
-
current += '"';
|
|
115
|
-
i += 2;
|
|
116
|
-
} else {
|
|
117
|
-
// Toggle quote state
|
|
118
|
-
inQuotes = !inQuotes;
|
|
119
|
-
i++;
|
|
120
|
-
}
|
|
121
|
-
} else if (char === delimiter && !inQuotes) {
|
|
122
|
-
// End of field
|
|
123
|
-
result.push(current.trim());
|
|
124
|
-
current = '';
|
|
125
|
-
i++;
|
|
126
|
-
} else {
|
|
127
|
-
current += char;
|
|
128
|
-
i++;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Add the last field
|
|
133
|
-
result.push(current.trim());
|
|
134
|
-
|
|
135
|
-
return result;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Creates styled data for display in tables
|
|
140
|
-
* @param headers - Column headers
|
|
141
|
-
* @param rows - Data rows
|
|
142
|
-
* @param hasHeaders - Whether the data has headers
|
|
143
|
-
* @returns Styled data array
|
|
144
|
-
*/
|
|
145
|
-
private createStyledData(headers: string[], rows: string[][], hasHeaders: boolean): CsvRowData[] {
|
|
146
|
-
const styledData: CsvRowData[] = [];
|
|
147
|
-
|
|
148
|
-
// Add header row if headers exist
|
|
149
|
-
if (hasHeaders && headers.length > 0) {
|
|
150
|
-
styledData.push({
|
|
151
|
-
cells: headers.map(header => ({
|
|
152
|
-
value: header,
|
|
153
|
-
isHeader: true,
|
|
154
|
-
style: { fontWeight: 'bold', backgroundColor: '#f8f9fa' }
|
|
155
|
-
}))
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Add data rows
|
|
160
|
-
rows.forEach(row => {
|
|
161
|
-
styledData.push({
|
|
162
|
-
cells: row.map((cell, index) => ({
|
|
163
|
-
value: cell || '',
|
|
164
|
-
isHeader: false,
|
|
165
|
-
style: {}
|
|
166
|
-
}))
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
return styledData;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Creates empty CSV data structure
|
|
175
|
-
* @returns Empty CSV data
|
|
176
|
-
*/
|
|
177
|
-
private createEmptyCsvData(): ParsedCsvData {
|
|
178
|
-
return {
|
|
179
|
-
headers: [],
|
|
180
|
-
rows: [],
|
|
181
|
-
styledData: [],
|
|
182
|
-
totalRows: 0,
|
|
183
|
-
totalColumns: 0,
|
|
184
|
-
hasHeaders: false
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Validates CSV content
|
|
190
|
-
* @param csvContent - CSV content to validate
|
|
191
|
-
* @returns Validation result
|
|
192
|
-
*/
|
|
193
|
-
validateCsvContent(csvContent: string): { isValid: boolean; errors: string[] } {
|
|
194
|
-
const errors: string[] = [];
|
|
195
|
-
|
|
196
|
-
if (!csvContent || csvContent.trim().length === 0) {
|
|
197
|
-
errors.push('CSV content is empty');
|
|
198
|
-
return { isValid: false, errors };
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const lines = csvContent.split('\n').filter(line => line.trim().length > 0);
|
|
202
|
-
|
|
203
|
-
if (lines.length === 0) {
|
|
204
|
-
errors.push('No valid lines found in CSV');
|
|
205
|
-
return { isValid: false, errors };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Check for consistent column count
|
|
209
|
-
const columnCounts = lines.map(line => this.countColumns(line));
|
|
210
|
-
const firstColumnCount = columnCounts[0];
|
|
211
|
-
|
|
212
|
-
for (let i = 1; i < columnCounts.length; i++) {
|
|
213
|
-
if (columnCounts[i] !== firstColumnCount) {
|
|
214
|
-
errors.push(`Line ${i + 1} has ${columnCounts[i]} columns, expected ${firstColumnCount}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
isValid: errors.length === 0,
|
|
220
|
-
errors
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Counts columns in a CSV line
|
|
226
|
-
* @param line - CSV line
|
|
227
|
-
* @returns Number of columns
|
|
228
|
-
*/
|
|
229
|
-
private countColumns(line: string): number {
|
|
230
|
-
let count = 0;
|
|
231
|
-
let inQuotes = false;
|
|
232
|
-
let i = 0;
|
|
233
|
-
|
|
234
|
-
while (i < line.length) {
|
|
235
|
-
const char = line[i];
|
|
236
|
-
|
|
237
|
-
if (char === '"') {
|
|
238
|
-
if (inQuotes && line[i + 1] === '"') {
|
|
239
|
-
i += 2;
|
|
240
|
-
} else {
|
|
241
|
-
inQuotes = !inQuotes;
|
|
242
|
-
i++;
|
|
243
|
-
}
|
|
244
|
-
} else if (char === ',' && !inQuotes) {
|
|
245
|
-
count++;
|
|
246
|
-
i++;
|
|
247
|
-
} else {
|
|
248
|
-
i++;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return count + 1; // +1 because we count delimiters, not fields
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Exports data to CSV format
|
|
257
|
-
* @param data - Data to export
|
|
258
|
-
* @param headers - Column headers
|
|
259
|
-
* @param delimiter - Field delimiter
|
|
260
|
-
* @returns CSV string
|
|
261
|
-
*/
|
|
262
|
-
exportToCsv(data: string[][], headers: string[], delimiter: string = ','): string {
|
|
263
|
-
const csvLines: string[] = [];
|
|
264
|
-
|
|
265
|
-
// Add headers if provided
|
|
266
|
-
if (headers && headers.length > 0) {
|
|
267
|
-
csvLines.push(this.escapeCsvField(headers.join(delimiter)));
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Add data rows
|
|
271
|
-
data.forEach(row => {
|
|
272
|
-
const escapedRow = row.map(field => this.escapeCsvField(field));
|
|
273
|
-
csvLines.push(escapedRow.join(delimiter));
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
return csvLines.join('\n');
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Escapes a CSV field value
|
|
281
|
-
* @param field - Field value to escape
|
|
282
|
-
* @returns Escaped field value
|
|
283
|
-
*/
|
|
284
|
-
private escapeCsvField(field: string): string {
|
|
285
|
-
if (field.includes(',') || field.includes('"') || field.includes('\n') || field.includes('\r')) {
|
|
286
|
-
return `"${field.replace(/"/g, '""')}"`;
|
|
287
|
-
}
|
|
288
|
-
return field;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Gets CSV preview (first few rows)
|
|
293
|
-
* @param csvContent - Full CSV content
|
|
294
|
-
* @param maxRows - Maximum number of rows to preview
|
|
295
|
-
* @returns Preview data
|
|
296
|
-
*/
|
|
297
|
-
getCsvPreview(csvContent: string, maxRows: number = 10): ParsedCsvData {
|
|
298
|
-
const lines = csvContent.split('\n').filter(line => line.trim().length > 0);
|
|
299
|
-
const previewContent = lines.slice(0, maxRows + 1).join('\n'); // +1 for header
|
|
300
|
-
|
|
301
|
-
return this.parseCsvData(previewContent, { maxRows });
|
|
302
|
-
}
|
|
303
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { SHARED } from '../../../Shared/constant/SHARED';
|
|
3
|
-
|
|
4
|
-
export interface DocumentAction {
|
|
5
|
-
type: typeof SHARED.REJECT_ACTION | typeof SHARED.ACCEPT_ACTION | typeof SHARED.DELETE_ACTION;
|
|
6
|
-
note?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
@Injectable({
|
|
10
|
-
providedIn: 'root'
|
|
11
|
-
})
|
|
12
|
-
export class DocumentActionsService {
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Calculates the card class based on status
|
|
16
|
-
* @param currentStatus - The current status of the document
|
|
17
|
-
* @param statusId - The status ID from API
|
|
18
|
-
* @returns {string} The CSS class for the card
|
|
19
|
-
*/
|
|
20
|
-
calculateCardClass(currentStatus?: string, statusId?: string): string {
|
|
21
|
-
// Use statusId if available, otherwise fall back to currentStatus
|
|
22
|
-
if (statusId) {
|
|
23
|
-
return `status-${statusId}-card`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (!currentStatus) {
|
|
27
|
-
return SHARED.CARD_PENDING;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const status = currentStatus.toLowerCase();
|
|
31
|
-
if (status === SHARED.STATUS_ACCEPTED.toLowerCase() || status === SHARED.STATUS_APPROVED.toLowerCase()) {
|
|
32
|
-
return SHARED.CARD_ACCEPTED;
|
|
33
|
-
} else if (status === SHARED.STATUS_REJECTED_LOWERCASE.toLowerCase() || status === SHARED.STATUS_REJECTED.toLowerCase()) {
|
|
34
|
-
return SHARED.CARD_REJECTED;
|
|
35
|
-
} else {
|
|
36
|
-
return SHARED.CARD_PENDING;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Calculates the reject button class based on status
|
|
42
|
-
* @param currentStatus - The current status of the document
|
|
43
|
-
* @param statusId - The status ID from API
|
|
44
|
-
* @returns {string} The CSS class for the reject button
|
|
45
|
-
*/
|
|
46
|
-
calculateRejectButtonClass(currentStatus?: string, statusId?: string): string {
|
|
47
|
-
// Use statusId if available, otherwise fall back to currentStatus
|
|
48
|
-
if (statusId) {
|
|
49
|
-
return `status-${statusId}-reject`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!currentStatus) {
|
|
53
|
-
return SHARED.BUTTON_DEFAULT_REJECT;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const status = currentStatus.toLowerCase();
|
|
57
|
-
if (status === SHARED.STATUS_ACCEPTED.toLowerCase() || status === SHARED.STATUS_APPROVED.toLowerCase()) {
|
|
58
|
-
return SHARED.BUTTON_SECONDARY_REJECT;
|
|
59
|
-
} else if (status === SHARED.STATUS_REJECTED_LOWERCASE.toLowerCase() || status === SHARED.STATUS_REJECTED.toLowerCase()) {
|
|
60
|
-
return SHARED.BUTTON_PRIMARY_REJECT;
|
|
61
|
-
} else {
|
|
62
|
-
return SHARED.BUTTON_DEFAULT_REJECT;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Calculates the accept button class based on status
|
|
68
|
-
* @param currentStatus - The current status of the document
|
|
69
|
-
* @param statusId - The status ID from API
|
|
70
|
-
* @returns {string} The CSS class for the accept button
|
|
71
|
-
*/
|
|
72
|
-
calculateAcceptButtonClass(currentStatus?: string, statusId?: string): string {
|
|
73
|
-
// Use statusId if available, otherwise fall back to currentStatus
|
|
74
|
-
if (statusId) {
|
|
75
|
-
return `status-${statusId}-accept`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (!currentStatus) {
|
|
79
|
-
return SHARED.BUTTON_DEFAULT_ACCEPT;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const status = currentStatus.toLowerCase();
|
|
83
|
-
if (status === SHARED.STATUS_ACCEPTED.toLowerCase() || status === SHARED.STATUS_APPROVED.toLowerCase()) {
|
|
84
|
-
return SHARED.BUTTON_PRIMARY_ACCEPT;
|
|
85
|
-
} else if (status === SHARED.STATUS_REJECTED_LOWERCASE.toLowerCase() || status === SHARED.STATUS_REJECTED.toLowerCase()) {
|
|
86
|
-
return SHARED.BUTTON_SECONDARY_ACCEPT;
|
|
87
|
-
} else {
|
|
88
|
-
return SHARED.BUTTON_DEFAULT_ACCEPT;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Creates an accept action
|
|
94
|
-
* @param note - The acceptance note
|
|
95
|
-
* @returns {DocumentAction} The accept action
|
|
96
|
-
*/
|
|
97
|
-
createAcceptAction(note: string): DocumentAction {
|
|
98
|
-
return {
|
|
99
|
-
type: SHARED.ACCEPT_ACTION as 'accept',
|
|
100
|
-
note: note
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Creates a reject action
|
|
106
|
-
* @param note - The rejection note
|
|
107
|
-
* @returns {DocumentAction} The reject action
|
|
108
|
-
*/
|
|
109
|
-
createRejectAction(note: string): DocumentAction {
|
|
110
|
-
return {
|
|
111
|
-
type: SHARED.REJECT_ACTION as 'reject',
|
|
112
|
-
note: note
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Creates a delete action
|
|
118
|
-
* @returns {DocumentAction} The delete action
|
|
119
|
-
*/
|
|
120
|
-
createDeleteAction(): DocumentAction {
|
|
121
|
-
return {
|
|
122
|
-
type: SHARED.DELETE_ACTION as 'delete'
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
}
|