cat-documents-ng 1.0.4 → 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.
Files changed (210) hide show
  1. package/ng-package.json +10 -0
  2. package/package.json +5 -11
  3. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.html +3 -0
  4. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.scss +13 -0
  5. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.spec.ts +70 -0
  6. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.ts +133 -0
  7. package/src/Shared/components/table-primary/table-primary.component.html +66 -0
  8. package/src/Shared/components/table-primary/table-primary.component.scss +227 -0
  9. package/src/Shared/components/table-primary/table-primary.component.spec.ts +23 -0
  10. package/src/Shared/components/table-primary/table-primary.component.ts +143 -0
  11. package/src/Shared/components/table-primary/table-primary.model.ts +21 -0
  12. package/src/Shared/constant/ERROR.ts +55 -0
  13. package/src/Shared/constant/PERMISSIONS.ts +17 -0
  14. package/src/Shared/constant/SHARED.ts +936 -0
  15. package/{Shared/constant/URLS.d.ts → src/Shared/constant/URLS.ts} +31 -25
  16. package/src/Shared/services/app-config.service.spec.ts +19 -0
  17. package/src/Shared/services/app-config.service.ts +73 -0
  18. package/{Shared/services/global-error.handler.d.ts → src/Shared/services/global-error.handler.ts} +11 -9
  19. package/src/Shared/services/session.service.spec.ts +16 -0
  20. package/src/Shared/services/session.service.ts +76 -0
  21. package/src/Shared/shared.module.ts +25 -0
  22. package/src/lib/document/components/csv-viewer/csv-viewer.component.ts +1 -0
  23. package/src/lib/document/components/document-actions/document-actions.component.html +59 -0
  24. package/src/lib/document/components/document-actions/document-actions.component.scss +362 -0
  25. package/src/lib/document/components/document-actions/document-actions.component.spec.ts +297 -0
  26. package/src/lib/document/components/document-actions/document-actions.component.ts +163 -0
  27. package/src/lib/document/components/document-container/document-container.component.html +36 -0
  28. package/src/lib/document/components/document-container/document-container.component.scss +144 -0
  29. package/src/lib/document/components/document-container/document-container.component.spec.ts +110 -0
  30. package/src/lib/document/components/document-container/document-container.component.ts +363 -0
  31. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.html +332 -0
  32. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.scss +1877 -0
  33. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.spec.ts +258 -0
  34. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.ts +664 -0
  35. package/src/lib/document/components/document-history/document-history.component.html +96 -0
  36. package/src/lib/document/components/document-history/document-history.component.scss +392 -0
  37. package/src/lib/document/components/document-history/document-history.component.spec.ts +93 -0
  38. package/src/lib/document/components/document-history/document-history.component.ts +373 -0
  39. package/src/lib/document/components/document-list/document-list.component.html +46 -0
  40. package/src/lib/document/components/document-list/document-list.component.scss +513 -0
  41. package/src/lib/document/components/document-list/document-list.component.spec.ts +486 -0
  42. package/src/lib/document/components/document-list/document-list.component.ts +682 -0
  43. package/src/lib/document/components/document-list-item/document-list-item.component.html +36 -0
  44. package/src/lib/document/components/document-list-item/document-list-item.component.scss +34 -0
  45. package/src/lib/document/components/document-list-item/document-list-item.component.spec.ts +75 -0
  46. package/src/lib/document/components/document-list-item/document-list-item.component.ts +40 -0
  47. package/src/lib/document/components/document-search/document-search.component.html +64 -0
  48. package/src/lib/document/components/document-search/document-search.component.scss +206 -0
  49. package/src/lib/document/components/document-search/document-search.component.spec.ts +82 -0
  50. package/src/lib/document/components/document-search/document-search.component.ts +163 -0
  51. package/src/lib/document/components/document-status/document-status.component.html +31 -0
  52. package/src/lib/document/components/document-status/document-status.component.scss +192 -0
  53. package/src/lib/document/components/document-status/document-status.component.spec.ts +23 -0
  54. package/src/lib/document/components/document-status/document-status.component.ts +87 -0
  55. package/src/lib/document/components/document-upload/document-upload.component.html +160 -0
  56. package/src/lib/document/components/document-upload/document-upload.component.scss +235 -0
  57. package/src/lib/document/components/document-upload/document-upload.component.spec.ts +95 -0
  58. package/src/lib/document/components/document-upload/document-upload.component.ts +668 -0
  59. package/src/lib/document/components/document-viewer/document-viewer.component.html +50 -0
  60. package/src/lib/document/components/document-viewer/document-viewer.component.scss +187 -0
  61. package/src/lib/document/components/document-viewer/document-viewer.component.spec.ts +79 -0
  62. package/src/lib/document/components/document-viewer/document-viewer.component.ts +261 -0
  63. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.html +48 -0
  64. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.scss +320 -0
  65. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.spec.ts +59 -0
  66. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.ts +150 -0
  67. package/src/lib/document/components/documents-menu/documents-menu.component.html +44 -0
  68. package/src/lib/document/components/documents-menu/documents-menu.component.scss +363 -0
  69. package/src/lib/document/components/documents-menu/documents-menu.component.spec.ts +23 -0
  70. package/src/lib/document/components/documents-menu/documents-menu.component.ts +316 -0
  71. package/src/lib/document/components/folder-block/folder-block.component.html +46 -0
  72. package/src/lib/document/components/folder-block/folder-block.component.scss +9 -0
  73. package/src/lib/document/components/folder-block/folder-block.component.spec.ts +70 -0
  74. package/{lib/document/components/folder-block/folder-block.component.d.ts → src/lib/document/components/folder-block/folder-block.component.ts} +28 -12
  75. package/src/lib/document/components/folder-container/folder-container.component.html +56 -0
  76. package/src/lib/document/components/folder-container/folder-container.component.scss +20 -0
  77. package/src/lib/document/components/folder-container/folder-container.component.spec.ts +27 -0
  78. package/src/lib/document/components/folder-container/folder-container.component.ts +328 -0
  79. package/src/lib/document/components/linked-document/linked-document.component.html +23 -0
  80. package/src/lib/document/components/linked-document/linked-document.component.scss +10 -0
  81. package/src/lib/document/components/linked-document/linked-document.component.spec.ts +61 -0
  82. package/src/lib/document/components/linked-document/linked-document.component.ts +49 -0
  83. package/src/lib/document/components/request-document/request-document.component.html +86 -0
  84. package/src/lib/document/components/request-document/request-document.component.scss +16 -0
  85. package/src/lib/document/components/request-document/request-document.component.ts +278 -0
  86. package/src/lib/document/components/sidebar/sidebar.component.html +75 -0
  87. package/src/lib/document/components/sidebar/sidebar.component.scss +157 -0
  88. package/src/lib/document/components/sidebar/sidebar.component.spec.ts +114 -0
  89. package/src/lib/document/components/sidebar/sidebar.component.ts +223 -0
  90. package/src/lib/document/components/user-list/user-list.component.html +33 -0
  91. package/src/lib/document/components/user-list/user-list.component.scss +118 -0
  92. package/src/lib/document/components/user-list/user-list.component.spec.ts +23 -0
  93. package/src/lib/document/components/user-list/user-list.component.ts +181 -0
  94. package/src/lib/document/constant/DOCUMENT_HISTORY.ts +52 -0
  95. package/src/lib/document/directives/document.directive.ts +32 -0
  96. package/src/lib/document/directives/permission.directive.spec.ts +0 -0
  97. package/src/lib/document/directives/permission.directive.ts +72 -0
  98. package/src/lib/document/document.module.ts +351 -0
  99. package/{lib/document/models/document-alert.model.d.ts → src/lib/document/models/document-alert.model.ts} +11 -4
  100. package/src/lib/document/models/document-category.model.ts +30 -0
  101. package/src/lib/document/models/document-history.model.ts +109 -0
  102. package/src/lib/document/models/document-list-response.model.ts +37 -0
  103. package/src/lib/document/models/document-type.model.ts +44 -0
  104. package/src/lib/document/models/document.model.ts +53 -0
  105. package/{lib/document/models/folder.model.d.ts → src/lib/document/models/folder.model.ts} +10 -4
  106. package/src/lib/document/models/status-data.model.ts +31 -0
  107. package/src/lib/document/models/uploaded-file-response.model.ts +7 -0
  108. package/src/lib/document/models/user-list.model.ts +10 -0
  109. package/src/lib/document/services/csv-parser.service.spec.ts +97 -0
  110. package/src/lib/document/services/csv-parser.service.ts +303 -0
  111. package/src/lib/document/services/document-actions.service.ts +125 -0
  112. package/src/lib/document/services/document-content-type.service.ts +193 -0
  113. package/src/lib/document/services/document-history-style.service.ts +138 -0
  114. package/src/lib/document/services/document-history.service.ts +129 -0
  115. package/src/lib/document/services/document-http.service.spec.ts +119 -0
  116. package/src/lib/document/services/document-http.service.ts +497 -0
  117. package/src/lib/document/services/document-list.service.ts +195 -0
  118. package/src/lib/document/services/document-menu.service.ts +277 -0
  119. package/src/lib/document/services/document-scroll.service.ts +138 -0
  120. package/src/lib/document/services/document-severity.service.ts +98 -0
  121. package/src/lib/document/services/document-table-builder.service.ts +82 -0
  122. package/src/lib/document/services/document-upload-business.service.ts +326 -0
  123. package/src/lib/document/services/document-upload-data.service.ts +82 -0
  124. package/src/lib/document/services/document-upload-form.service.ts +149 -0
  125. package/src/lib/document/services/document-upload.service.spec.ts +99 -0
  126. package/src/lib/document/services/document-upload.service.ts +209 -0
  127. package/src/lib/document/services/document-viewer.service.ts +279 -0
  128. package/src/lib/document/services/document-zoom.service.spec.ts +56 -0
  129. package/src/lib/document/services/document-zoom.service.ts +164 -0
  130. package/src/lib/document/services/document.service.ts +356 -0
  131. package/src/lib/document/services/eml-parser.service.ts +444 -0
  132. package/src/lib/document/services/excel-parser.service.spec.ts +66 -0
  133. package/src/lib/document/services/excel-parser.service.ts +483 -0
  134. package/src/lib/document/services/file-format.service.spec.ts +16 -0
  135. package/src/lib/document/services/file-format.service.ts +63 -0
  136. package/src/lib/document/services/status-calculator.service.ts +44 -0
  137. package/src/lib/document/services/user-list.service.ts +77 -0
  138. package/src/lib/document/state/document.query.ts +378 -0
  139. package/{lib/document/state/document.service.d.ts → src/lib/document/state/document.service.ts} +46 -15
  140. package/src/lib/document/state/document.state.ts +100 -0
  141. package/src/lib/document/state/document.store.ts +200 -0
  142. package/{public-api.d.ts → src/public-api.ts} +4 -0
  143. package/tsconfig.lib.json +15 -0
  144. package/tsconfig.lib.prod.json +11 -0
  145. package/tsconfig.spec.json +15 -0
  146. package/Shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +0 -44
  147. package/Shared/components/table-primary/table-primary.component.d.ts +0 -31
  148. package/Shared/components/table-primary/table-primary.model.d.ts +0 -19
  149. package/Shared/constant/ERROR.d.ts +0 -52
  150. package/Shared/constant/SHARED.d.ts +0 -546
  151. package/Shared/services/app-config.service.d.ts +0 -51
  152. package/Shared/services/session.service.d.ts +0 -46
  153. package/Shared/shared.module.d.ts +0 -14
  154. package/fesm2022/cat-documents-ng.mjs +0 -11392
  155. package/fesm2022/cat-documents-ng.mjs.map +0 -1
  156. package/index.d.ts +0 -5
  157. package/lib/document/components/document-actions/document-actions.component.d.ts +0 -78
  158. package/lib/document/components/document-container/document-container.component.d.ts +0 -162
  159. package/lib/document/components/document-content-viewer/document-content-viewer.component.d.ts +0 -291
  160. package/lib/document/components/document-history/document-history.component.d.ts +0 -160
  161. package/lib/document/components/document-list/document-list.component.d.ts +0 -299
  162. package/lib/document/components/document-list-item/document-list-item.component.d.ts +0 -28
  163. package/lib/document/components/document-search/document-search.component.d.ts +0 -77
  164. package/lib/document/components/document-status/document-status.component.d.ts +0 -24
  165. package/lib/document/components/document-upload/document-upload.component.d.ts +0 -321
  166. package/lib/document/components/document-viewer/document-viewer.component.d.ts +0 -137
  167. package/lib/document/components/document-zoom-controls/document-zoom-controls.component.d.ts +0 -33
  168. package/lib/document/components/documents-menu/documents-menu.component.d.ts +0 -110
  169. package/lib/document/components/folder-container/folder-container.component.d.ts +0 -162
  170. package/lib/document/components/linked-document/linked-document.component.d.ts +0 -39
  171. package/lib/document/components/request-document/request-document.component.d.ts +0 -69
  172. package/lib/document/components/sidebar/sidebar.component.d.ts +0 -109
  173. package/lib/document/components/user-list/user-list.component.d.ts +0 -34
  174. package/lib/document/constant/DOCUMENT_HISTORY.d.ts +0 -41
  175. package/lib/document/directives/document.directive.d.ts +0 -20
  176. package/lib/document/directives/permission.directive.d.ts +0 -38
  177. package/lib/document/document.module.d.ts +0 -60
  178. package/lib/document/models/document-category.model.d.ts +0 -24
  179. package/lib/document/models/document-history.model.d.ts +0 -94
  180. package/lib/document/models/document-list-response.model.d.ts +0 -33
  181. package/lib/document/models/document-type.model.d.ts +0 -37
  182. package/lib/document/models/document.model.d.ts +0 -44
  183. package/lib/document/models/status-data.model.d.ts +0 -27
  184. package/lib/document/models/uploaded-file-response.model.d.ts +0 -7
  185. package/lib/document/models/user-list.model.d.ts +0 -8
  186. package/lib/document/services/csv-parser.service.d.ts +0 -88
  187. package/lib/document/services/document-actions.service.d.ts +0 -48
  188. package/lib/document/services/document-content-type.service.d.ts +0 -85
  189. package/lib/document/services/document-history-style.service.d.ts +0 -34
  190. package/lib/document/services/document-history.service.d.ts +0 -42
  191. package/lib/document/services/document-http.service.d.ts +0 -179
  192. package/lib/document/services/document-list.service.d.ts +0 -74
  193. package/lib/document/services/document-menu.service.d.ts +0 -122
  194. package/lib/document/services/document-scroll.service.d.ts +0 -55
  195. package/lib/document/services/document-table-builder.service.d.ts +0 -38
  196. package/lib/document/services/document-upload-business.service.d.ts +0 -107
  197. package/lib/document/services/document-upload-data.service.d.ts +0 -40
  198. package/lib/document/services/document-upload-form.service.d.ts +0 -41
  199. package/lib/document/services/document-upload.service.d.ts +0 -99
  200. package/lib/document/services/document-viewer.service.d.ts +0 -97
  201. package/lib/document/services/document-zoom.service.d.ts +0 -81
  202. package/lib/document/services/document.service.d.ts +0 -161
  203. package/lib/document/services/eml-parser.service.d.ts +0 -116
  204. package/lib/document/services/excel-parser.service.d.ts +0 -169
  205. package/lib/document/services/file-format.service.d.ts +0 -34
  206. package/lib/document/services/status-calculator.service.d.ts +0 -20
  207. package/lib/document/services/user-list.service.d.ts +0 -29
  208. package/lib/document/state/document.query.d.ts +0 -243
  209. package/lib/document/state/document.state.d.ts +0 -61
  210. package/lib/document/state/document.store.d.ts +0 -56
@@ -0,0 +1,303 @@
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
+ }
@@ -0,0 +1,125 @@
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
+ }
@@ -0,0 +1,193 @@
1
+ import { Injectable } from '@angular/core';
2
+
3
+ /**
4
+ * Service for handling document content types and their mappings.
5
+ * Supports the content types: "xlsx","xls","doc","docx","pdf","jpg","jpeg","odt","csv","png","msg","eml"
6
+ * @class DocumentContentTypeService
7
+ * @typedef {DocumentContentTypeService}
8
+ */
9
+ @Injectable({
10
+ providedIn: 'root'
11
+ })
12
+ export class DocumentContentTypeService {
13
+
14
+ /**
15
+ * Mapping of file extensions to MIME types
16
+ * @type {Record<string, string>}
17
+ */
18
+ private readonly extensionToMimeType: Record<string, string> = {
19
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
20
+ 'xls': 'application/vnd.ms-excel',
21
+ 'doc': 'application/msword',
22
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
23
+ 'pdf': 'application/pdf',
24
+ 'jpg': 'image/jpeg',
25
+ 'jpeg': 'image/jpeg',
26
+ 'odt': 'application/vnd.oasis.opendocument.text',
27
+ 'csv': 'text/csv',
28
+ 'png': 'image/png',
29
+ 'msg': 'application/vnd.ms-outlook',
30
+ 'eml': 'message/rfc822'
31
+ };
32
+
33
+ /**
34
+ * Mapping of MIME types to file extensions
35
+ * @type {Record<string, string>}
36
+ */
37
+ private readonly mimeTypeToExtension: Record<string, string> = {
38
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
39
+ 'application/vnd.ms-excel': 'xls',
40
+ 'application/msword': 'doc',
41
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
42
+ 'application/pdf': 'pdf',
43
+ 'image/jpeg': 'jpg',
44
+ 'image/jpg': 'jpg',
45
+ 'application/vnd.oasis.opendocument.text': 'odt',
46
+ 'text/csv': 'csv',
47
+ 'image/png': 'png',
48
+ 'application/vnd.ms-outlook': 'msg',
49
+ 'message/rfc822': 'eml'
50
+ };
51
+
52
+ /**
53
+ * List of all supported file extensions
54
+ * @type {string[]}
55
+ */
56
+ readonly supportedExtensions: string[] = [
57
+ 'xlsx', 'xls', 'doc', 'docx', 'pdf', 'jpg', 'jpeg', 'odt', 'csv', 'png', 'msg', 'eml'
58
+ ];
59
+
60
+ /**
61
+ * List of all supported MIME types
62
+ * @type {string[]}
63
+ */
64
+ readonly supportedMimeTypes: string[] = [
65
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
66
+ 'application/vnd.ms-excel',
67
+ 'application/msword',
68
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
69
+ 'application/pdf',
70
+ 'image/jpeg',
71
+ 'image/jpg',
72
+ 'application/vnd.oasis.opendocument.text',
73
+ 'text/csv',
74
+ 'image/png',
75
+ 'application/vnd.ms-outlook',
76
+ 'message/rfc822'
77
+ ];
78
+
79
+ /**
80
+ * Gets the MIME type for a given file extension
81
+ * @param {string} extension - The file extension (with or without dot)
82
+ * @returns {string | undefined} The MIME type or undefined if not supported
83
+ */
84
+ getMimeType(extension: string): string | undefined {
85
+ const cleanExtension = extension.replace('.', '').toLowerCase();
86
+ return this.extensionToMimeType[cleanExtension];
87
+ }
88
+
89
+ /**
90
+ * Gets the file extension for a given MIME type
91
+ * @param {string} mimeType - The MIME type
92
+ * @returns {string | undefined} The file extension or undefined if not supported
93
+ */
94
+ getExtension(mimeType: string): string | undefined {
95
+ return this.mimeTypeToExtension[mimeType];
96
+ }
97
+
98
+ /**
99
+ * Checks if a file extension is supported
100
+ * @param {string} extension - The file extension (with or without dot)
101
+ * @returns {boolean} True if the extension is supported
102
+ */
103
+ isExtensionSupported(extension: string): boolean {
104
+ const cleanExtension = extension.replace('.', '').toLowerCase();
105
+ return this.supportedExtensions.includes(cleanExtension);
106
+ }
107
+
108
+ /**
109
+ * Checks if a MIME type is supported
110
+ * @param {string} mimeType - The MIME type
111
+ * @returns {boolean} True if the MIME type is supported
112
+ */
113
+ isMimeTypeSupported(mimeType: string): boolean {
114
+ return this.supportedMimeTypes.includes(mimeType);
115
+ }
116
+
117
+ /**
118
+ * Gets the file extension from a filename
119
+ * @param {string} filename - The filename
120
+ * @returns {string | undefined} The file extension or undefined if no extension found
121
+ */
122
+ getExtensionFromFilename(filename: string): string | undefined {
123
+ if (!filename || !filename.includes('.')) {
124
+ return undefined;
125
+ }
126
+ const parts = filename.split('.');
127
+ return parts[parts.length - 1].toLowerCase();
128
+ }
129
+
130
+ /**
131
+ * Gets the MIME type from a filename
132
+ * @param {string} filename - The filename
133
+ * @returns {string | undefined} The MIME type or undefined if not supported
134
+ */
135
+ getMimeTypeFromFilename(filename: string): string | undefined {
136
+ const extension = this.getExtensionFromFilename(filename);
137
+ return extension ? this.getMimeType(extension) : undefined;
138
+ }
139
+
140
+ /**
141
+ * Validates if a file can be uploaded based on its extension
142
+ * @param {string} filename - The filename to validate
143
+ * @returns {boolean} True if the file can be uploaded
144
+ */
145
+ canUploadFile(filename: string): boolean {
146
+ const extension = this.getExtensionFromFilename(filename);
147
+ return extension ? this.isExtensionSupported(extension) : false;
148
+ }
149
+
150
+ /**
151
+ * Gets a human-readable description for a content type
152
+ * @param {string} contentType - The content type (MIME type or extension)
153
+ * @returns {string} Human-readable description
154
+ */
155
+ getContentTypeDescription(contentType: string): string {
156
+ // Check if it's a MIME type first
157
+ if (this.isMimeTypeSupported(contentType)) {
158
+ const extension = this.getExtension(contentType);
159
+ return this.getExtensionDescription(extension || 'unknown');
160
+ }
161
+
162
+ // Check if it's an extension
163
+ if (this.isExtensionSupported(contentType)) {
164
+ return this.getExtensionDescription(contentType);
165
+ }
166
+
167
+ return 'Unknown Document Type';
168
+ }
169
+
170
+ /**
171
+ * Gets a human-readable description for a file extension
172
+ * @param {string} extension - The file extension
173
+ * @returns {string} Human-readable description
174
+ */
175
+ private getExtensionDescription(extension: string): string {
176
+ const descriptions: Record<string, string> = {
177
+ 'xlsx': 'Excel Spreadsheet (XLSX)',
178
+ 'xls': 'Excel Spreadsheet (XLS)',
179
+ 'doc': 'Word Document (DOC)',
180
+ 'docx': 'Word Document (DOCX)',
181
+ 'pdf': 'PDF Document',
182
+ 'jpg': 'JPEG Image',
183
+ 'jpeg': 'JPEG Image',
184
+ 'odt': 'OpenDocument Text',
185
+ 'csv': 'CSV File',
186
+ 'png': 'PNG Image',
187
+ 'msg': 'Outlook Message',
188
+ 'eml': 'Email Message'
189
+ };
190
+
191
+ return descriptions[extension] || 'Unknown File Type';
192
+ }
193
+ }