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.
Files changed (211) hide show
  1. package/README.md +322 -322
  2. package/Shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +44 -0
  3. package/Shared/components/table-primary/table-primary.component.d.ts +31 -0
  4. package/Shared/components/table-primary/table-primary.model.d.ts +19 -0
  5. package/Shared/constant/ERROR.d.ts +52 -0
  6. package/Shared/constant/SHARED.d.ts +546 -0
  7. package/{src/Shared/constant/URLS.ts → Shared/constant/URLS.d.ts} +25 -31
  8. package/Shared/services/app-config.service.d.ts +51 -0
  9. package/{src/Shared/services/global-error.handler.ts → Shared/services/global-error.handler.d.ts} +9 -11
  10. package/Shared/services/session.service.d.ts +46 -0
  11. package/Shared/shared.module.d.ts +14 -0
  12. package/fesm2022/cat-documents-ng.mjs +11405 -0
  13. package/fesm2022/cat-documents-ng.mjs.map +1 -0
  14. package/index.d.ts +5 -0
  15. package/lib/document/components/document-actions/document-actions.component.d.ts +78 -0
  16. package/lib/document/components/document-container/document-container.component.d.ts +162 -0
  17. package/lib/document/components/document-content-viewer/document-content-viewer.component.d.ts +291 -0
  18. package/lib/document/components/document-history/document-history.component.d.ts +160 -0
  19. package/lib/document/components/document-list/document-list.component.d.ts +299 -0
  20. package/lib/document/components/document-list-item/document-list-item.component.d.ts +28 -0
  21. package/lib/document/components/document-search/document-search.component.d.ts +77 -0
  22. package/lib/document/components/document-status/document-status.component.d.ts +24 -0
  23. package/lib/document/components/document-upload/document-upload.component.d.ts +321 -0
  24. package/lib/document/components/document-viewer/document-viewer.component.d.ts +137 -0
  25. package/lib/document/components/document-zoom-controls/document-zoom-controls.component.d.ts +33 -0
  26. package/lib/document/components/documents-menu/documents-menu.component.d.ts +110 -0
  27. package/{src/lib/document/components/folder-block/folder-block.component.ts → lib/document/components/folder-block/folder-block.component.d.ts} +12 -28
  28. package/lib/document/components/folder-container/folder-container.component.d.ts +162 -0
  29. package/lib/document/components/linked-document/linked-document.component.d.ts +39 -0
  30. package/lib/document/components/request-document/request-document.component.d.ts +69 -0
  31. package/lib/document/components/sidebar/sidebar.component.d.ts +109 -0
  32. package/lib/document/components/user-list/user-list.component.d.ts +34 -0
  33. package/lib/document/constant/DOCUMENT_HISTORY.d.ts +41 -0
  34. package/lib/document/directives/document.directive.d.ts +20 -0
  35. package/lib/document/directives/permission.directive.d.ts +38 -0
  36. package/lib/document/document.module.d.ts +60 -0
  37. package/{src/lib/document/models/document-alert.model.ts → lib/document/models/document-alert.model.d.ts} +4 -11
  38. package/lib/document/models/document-category.model.d.ts +24 -0
  39. package/lib/document/models/document-history.model.d.ts +94 -0
  40. package/lib/document/models/document-list-response.model.d.ts +33 -0
  41. package/lib/document/models/document-type.model.d.ts +37 -0
  42. package/lib/document/models/document.model.d.ts +44 -0
  43. package/{src/lib/document/models/folder.model.ts → lib/document/models/folder.model.d.ts} +4 -10
  44. package/lib/document/models/status-data.model.d.ts +27 -0
  45. package/lib/document/models/uploaded-file-response.model.d.ts +7 -0
  46. package/lib/document/models/user-list.model.d.ts +8 -0
  47. package/lib/document/services/csv-parser.service.d.ts +88 -0
  48. package/lib/document/services/document-actions.service.d.ts +48 -0
  49. package/lib/document/services/document-content-type.service.d.ts +85 -0
  50. package/lib/document/services/document-history-style.service.d.ts +34 -0
  51. package/lib/document/services/document-history.service.d.ts +42 -0
  52. package/lib/document/services/document-http.service.d.ts +179 -0
  53. package/lib/document/services/document-list.service.d.ts +74 -0
  54. package/lib/document/services/document-menu.service.d.ts +122 -0
  55. package/lib/document/services/document-scroll.service.d.ts +55 -0
  56. package/lib/document/services/document-table-builder.service.d.ts +38 -0
  57. package/lib/document/services/document-upload-business.service.d.ts +107 -0
  58. package/lib/document/services/document-upload-data.service.d.ts +40 -0
  59. package/lib/document/services/document-upload-form.service.d.ts +41 -0
  60. package/lib/document/services/document-upload.service.d.ts +99 -0
  61. package/lib/document/services/document-viewer.service.d.ts +97 -0
  62. package/lib/document/services/document-zoom.service.d.ts +81 -0
  63. package/lib/document/services/document.service.d.ts +161 -0
  64. package/lib/document/services/eml-parser.service.d.ts +116 -0
  65. package/lib/document/services/excel-parser.service.d.ts +169 -0
  66. package/lib/document/services/file-format.service.d.ts +34 -0
  67. package/lib/document/services/status-calculator.service.d.ts +20 -0
  68. package/lib/document/services/user-list.service.d.ts +29 -0
  69. package/lib/document/state/document.query.d.ts +243 -0
  70. package/{src/lib/document/state/document.service.ts → lib/document/state/document.service.d.ts} +15 -46
  71. package/lib/document/state/document.state.d.ts +61 -0
  72. package/lib/document/state/document.store.d.ts +56 -0
  73. package/package.json +11 -5
  74. package/{src/public-api.ts → public-api.d.ts} +0 -4
  75. package/ng-package.json +0 -10
  76. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.html +0 -3
  77. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.scss +0 -13
  78. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.spec.ts +0 -70
  79. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.ts +0 -133
  80. package/src/Shared/components/table-primary/table-primary.component.html +0 -66
  81. package/src/Shared/components/table-primary/table-primary.component.scss +0 -227
  82. package/src/Shared/components/table-primary/table-primary.component.spec.ts +0 -23
  83. package/src/Shared/components/table-primary/table-primary.component.ts +0 -143
  84. package/src/Shared/components/table-primary/table-primary.model.ts +0 -21
  85. package/src/Shared/constant/ERROR.ts +0 -55
  86. package/src/Shared/constant/PERMISSIONS.ts +0 -17
  87. package/src/Shared/constant/SHARED.ts +0 -936
  88. package/src/Shared/services/app-config.service.spec.ts +0 -19
  89. package/src/Shared/services/app-config.service.ts +0 -73
  90. package/src/Shared/services/session.service.spec.ts +0 -16
  91. package/src/Shared/services/session.service.ts +0 -76
  92. package/src/Shared/shared.module.ts +0 -25
  93. package/src/lib/document/components/csv-viewer/csv-viewer.component.ts +0 -1
  94. package/src/lib/document/components/document-actions/document-actions.component.html +0 -59
  95. package/src/lib/document/components/document-actions/document-actions.component.scss +0 -362
  96. package/src/lib/document/components/document-actions/document-actions.component.spec.ts +0 -297
  97. package/src/lib/document/components/document-actions/document-actions.component.ts +0 -163
  98. package/src/lib/document/components/document-container/document-container.component.html +0 -36
  99. package/src/lib/document/components/document-container/document-container.component.scss +0 -144
  100. package/src/lib/document/components/document-container/document-container.component.spec.ts +0 -110
  101. package/src/lib/document/components/document-container/document-container.component.ts +0 -363
  102. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.html +0 -332
  103. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.scss +0 -1877
  104. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.spec.ts +0 -258
  105. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.ts +0 -664
  106. package/src/lib/document/components/document-history/document-history.component.html +0 -96
  107. package/src/lib/document/components/document-history/document-history.component.scss +0 -392
  108. package/src/lib/document/components/document-history/document-history.component.spec.ts +0 -93
  109. package/src/lib/document/components/document-history/document-history.component.ts +0 -373
  110. package/src/lib/document/components/document-list/document-list.component.html +0 -46
  111. package/src/lib/document/components/document-list/document-list.component.scss +0 -513
  112. package/src/lib/document/components/document-list/document-list.component.spec.ts +0 -486
  113. package/src/lib/document/components/document-list/document-list.component.ts +0 -682
  114. package/src/lib/document/components/document-list-item/document-list-item.component.html +0 -36
  115. package/src/lib/document/components/document-list-item/document-list-item.component.scss +0 -34
  116. package/src/lib/document/components/document-list-item/document-list-item.component.spec.ts +0 -75
  117. package/src/lib/document/components/document-list-item/document-list-item.component.ts +0 -40
  118. package/src/lib/document/components/document-search/document-search.component.html +0 -64
  119. package/src/lib/document/components/document-search/document-search.component.scss +0 -206
  120. package/src/lib/document/components/document-search/document-search.component.spec.ts +0 -82
  121. package/src/lib/document/components/document-search/document-search.component.ts +0 -163
  122. package/src/lib/document/components/document-status/document-status.component.html +0 -31
  123. package/src/lib/document/components/document-status/document-status.component.scss +0 -192
  124. package/src/lib/document/components/document-status/document-status.component.spec.ts +0 -23
  125. package/src/lib/document/components/document-status/document-status.component.ts +0 -87
  126. package/src/lib/document/components/document-upload/document-upload.component.html +0 -160
  127. package/src/lib/document/components/document-upload/document-upload.component.scss +0 -235
  128. package/src/lib/document/components/document-upload/document-upload.component.spec.ts +0 -95
  129. package/src/lib/document/components/document-upload/document-upload.component.ts +0 -668
  130. package/src/lib/document/components/document-viewer/document-viewer.component.html +0 -50
  131. package/src/lib/document/components/document-viewer/document-viewer.component.scss +0 -187
  132. package/src/lib/document/components/document-viewer/document-viewer.component.spec.ts +0 -79
  133. package/src/lib/document/components/document-viewer/document-viewer.component.ts +0 -261
  134. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.html +0 -48
  135. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.scss +0 -320
  136. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.spec.ts +0 -59
  137. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.ts +0 -150
  138. package/src/lib/document/components/documents-menu/documents-menu.component.html +0 -44
  139. package/src/lib/document/components/documents-menu/documents-menu.component.scss +0 -363
  140. package/src/lib/document/components/documents-menu/documents-menu.component.spec.ts +0 -23
  141. package/src/lib/document/components/documents-menu/documents-menu.component.ts +0 -316
  142. package/src/lib/document/components/folder-block/folder-block.component.html +0 -46
  143. package/src/lib/document/components/folder-block/folder-block.component.scss +0 -9
  144. package/src/lib/document/components/folder-block/folder-block.component.spec.ts +0 -70
  145. package/src/lib/document/components/folder-container/folder-container.component.html +0 -56
  146. package/src/lib/document/components/folder-container/folder-container.component.scss +0 -20
  147. package/src/lib/document/components/folder-container/folder-container.component.spec.ts +0 -27
  148. package/src/lib/document/components/folder-container/folder-container.component.ts +0 -328
  149. package/src/lib/document/components/linked-document/linked-document.component.html +0 -23
  150. package/src/lib/document/components/linked-document/linked-document.component.scss +0 -10
  151. package/src/lib/document/components/linked-document/linked-document.component.spec.ts +0 -61
  152. package/src/lib/document/components/linked-document/linked-document.component.ts +0 -49
  153. package/src/lib/document/components/request-document/request-document.component.html +0 -86
  154. package/src/lib/document/components/request-document/request-document.component.scss +0 -16
  155. package/src/lib/document/components/request-document/request-document.component.ts +0 -278
  156. package/src/lib/document/components/sidebar/sidebar.component.html +0 -75
  157. package/src/lib/document/components/sidebar/sidebar.component.scss +0 -157
  158. package/src/lib/document/components/sidebar/sidebar.component.spec.ts +0 -114
  159. package/src/lib/document/components/sidebar/sidebar.component.ts +0 -223
  160. package/src/lib/document/components/user-list/user-list.component.html +0 -33
  161. package/src/lib/document/components/user-list/user-list.component.scss +0 -118
  162. package/src/lib/document/components/user-list/user-list.component.spec.ts +0 -23
  163. package/src/lib/document/components/user-list/user-list.component.ts +0 -181
  164. package/src/lib/document/constant/DOCUMENT_HISTORY.ts +0 -52
  165. package/src/lib/document/directives/document.directive.ts +0 -32
  166. package/src/lib/document/directives/permission.directive.spec.ts +0 -0
  167. package/src/lib/document/directives/permission.directive.ts +0 -72
  168. package/src/lib/document/document.module.ts +0 -351
  169. package/src/lib/document/models/document-category.model.ts +0 -30
  170. package/src/lib/document/models/document-history.model.ts +0 -109
  171. package/src/lib/document/models/document-list-response.model.ts +0 -37
  172. package/src/lib/document/models/document-type.model.ts +0 -44
  173. package/src/lib/document/models/document.model.ts +0 -53
  174. package/src/lib/document/models/status-data.model.ts +0 -31
  175. package/src/lib/document/models/uploaded-file-response.model.ts +0 -7
  176. package/src/lib/document/models/user-list.model.ts +0 -10
  177. package/src/lib/document/services/csv-parser.service.spec.ts +0 -97
  178. package/src/lib/document/services/csv-parser.service.ts +0 -303
  179. package/src/lib/document/services/document-actions.service.ts +0 -125
  180. package/src/lib/document/services/document-content-type.service.ts +0 -193
  181. package/src/lib/document/services/document-history-style.service.ts +0 -138
  182. package/src/lib/document/services/document-history.service.ts +0 -129
  183. package/src/lib/document/services/document-http.service.spec.ts +0 -119
  184. package/src/lib/document/services/document-http.service.ts +0 -497
  185. package/src/lib/document/services/document-list.service.ts +0 -195
  186. package/src/lib/document/services/document-menu.service.ts +0 -277
  187. package/src/lib/document/services/document-scroll.service.ts +0 -138
  188. package/src/lib/document/services/document-severity.service.ts +0 -98
  189. package/src/lib/document/services/document-table-builder.service.ts +0 -82
  190. package/src/lib/document/services/document-upload-business.service.ts +0 -326
  191. package/src/lib/document/services/document-upload-data.service.ts +0 -82
  192. package/src/lib/document/services/document-upload-form.service.ts +0 -149
  193. package/src/lib/document/services/document-upload.service.spec.ts +0 -99
  194. package/src/lib/document/services/document-upload.service.ts +0 -209
  195. package/src/lib/document/services/document-viewer.service.ts +0 -279
  196. package/src/lib/document/services/document-zoom.service.spec.ts +0 -56
  197. package/src/lib/document/services/document-zoom.service.ts +0 -164
  198. package/src/lib/document/services/document.service.ts +0 -356
  199. package/src/lib/document/services/eml-parser.service.ts +0 -444
  200. package/src/lib/document/services/excel-parser.service.spec.ts +0 -66
  201. package/src/lib/document/services/excel-parser.service.ts +0 -483
  202. package/src/lib/document/services/file-format.service.spec.ts +0 -16
  203. package/src/lib/document/services/file-format.service.ts +0 -63
  204. package/src/lib/document/services/status-calculator.service.ts +0 -44
  205. package/src/lib/document/services/user-list.service.ts +0 -77
  206. package/src/lib/document/state/document.query.ts +0 -378
  207. package/src/lib/document/state/document.state.ts +0 -100
  208. package/src/lib/document/state/document.store.ts +0 -200
  209. package/tsconfig.lib.json +0 -15
  210. package/tsconfig.lib.prod.json +0 -11
  211. package/tsconfig.spec.json +0 -15
@@ -1,444 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
3
- import { Observable, throwError } from 'rxjs';
4
- import { HttpClient, HttpHeaders } from '@angular/common/http';
5
- import { catchError, map } from 'rxjs/operators';
6
-
7
- /**
8
- * Interface for parsed email data
9
- */
10
- export interface ParsedEmailData {
11
- from: string;
12
- to: string;
13
- cc?: string;
14
- subject: string;
15
- date: string;
16
- body: string;
17
- isHtml: boolean;
18
- attachments?: EmailAttachment[];
19
- }
20
-
21
- /**
22
- * Interface for email attachments
23
- */
24
- export interface EmailAttachment {
25
- filename: string;
26
- contentType: string;
27
- size: number;
28
- }
29
-
30
- /**
31
- * Service for parsing EML (email message) files
32
- * Handles both plain text and HTML email content
33
- */
34
- @Injectable({
35
- providedIn: 'root'
36
- })
37
- export class EmlParserService {
38
-
39
- constructor(
40
- private sanitizer: DomSanitizer,
41
- private http: HttpClient
42
- ) { }
43
-
44
- /**
45
- * Parses EML file content
46
- * @param emlContent - Raw EML file content as string
47
- * @returns Parsed email data
48
- */
49
- parseEmlData(emlContent: string): ParsedEmailData | null {
50
- try {
51
- const lines = emlContent.split(/\r?\n/);
52
- const headers = this.parseHeaders(lines);
53
- const body = this.parseBody(lines);
54
-
55
- return {
56
- from: this.cleanEmailAddress(headers['from'] || 'Unknown'),
57
- to: this.cleanEmailAddress(headers['to'] || 'Unknown'),
58
- cc: headers['cc'] ? this.cleanEmailAddress(headers['cc']) : undefined,
59
- subject: this.decodeHeader(headers['subject'] || 'No Subject'),
60
- date: this.formatDate(headers['date'] || ''),
61
- body: body.content,
62
- isHtml: body.isHtml,
63
- attachments: this.parseAttachments(emlContent)
64
- };
65
- } catch (error) {
66
- console.error('Error parsing EML file:', error);
67
- return null;
68
- }
69
- }
70
-
71
- /**
72
- * Parses email headers from EML content
73
- * @param lines - Lines of the EML file
74
- * @returns Object containing parsed headers
75
- */
76
- private parseHeaders(lines: string[]): { [key: string]: string } {
77
- const headers: { [key: string]: string } = {};
78
- let currentHeader = '';
79
- let currentValue = '';
80
-
81
- for (const line of lines) {
82
- // Empty line indicates end of headers
83
- if (line.trim() === '') {
84
- if (currentHeader) {
85
- headers[currentHeader.toLowerCase()] = currentValue.trim();
86
- }
87
- break;
88
- }
89
-
90
- // Check if line is a new header (starts without whitespace and contains ':')
91
- if (line.match(/^[\w-]+:/) && !line.startsWith(' ') && !line.startsWith('\t')) {
92
- // Save previous header if exists
93
- if (currentHeader) {
94
- headers[currentHeader.toLowerCase()] = currentValue.trim();
95
- }
96
-
97
- // Parse new header
98
- const colonIndex = line.indexOf(':');
99
- currentHeader = line.substring(0, colonIndex).trim();
100
- currentValue = line.substring(colonIndex + 1).trim();
101
- } else if (currentHeader && (line.startsWith(' ') || line.startsWith('\t'))) {
102
- // Continuation of previous header (folded header)
103
- currentValue += ' ' + line.trim();
104
- }
105
- }
106
-
107
- return headers;
108
- }
109
-
110
- /**
111
- * Parses the email body from EML content
112
- * @param lines - Lines of the EML file
113
- * @returns Object containing body content and format information
114
- */
115
- private parseBody(lines: string[]): { content: string, isHtml: boolean } {
116
- let inBody = false;
117
- let bodyLines: string[] = [];
118
- let contentType = 'text/plain';
119
- let boundary = '';
120
- let isBase64 = false;
121
- let isQuotedPrintable = false;
122
-
123
- // Find Content-Type and boundary
124
- for (let i = 0; i < lines.length; i++) {
125
- const line = lines[i];
126
-
127
- if (line.toLowerCase().startsWith('content-type:')) {
128
- contentType = line.toLowerCase().includes('text/html') ? 'text/html' : 'text/plain';
129
-
130
- // Check for multipart boundary
131
- const boundaryMatch = line.match(/boundary="?([^";\s]+)"?/i);
132
- if (boundaryMatch) {
133
- boundary = boundaryMatch[1];
134
- }
135
- }
136
-
137
- if (line.toLowerCase().startsWith('content-transfer-encoding:')) {
138
- isBase64 = line.toLowerCase().includes('base64');
139
- isQuotedPrintable = line.toLowerCase().includes('quoted-printable');
140
- }
141
-
142
- // Empty line marks start of body
143
- if (line.trim() === '' && !inBody) {
144
- inBody = true;
145
- continue;
146
- }
147
-
148
- if (inBody) {
149
- bodyLines.push(line);
150
- }
151
- }
152
-
153
- // If multipart, extract the relevant part
154
- if (boundary) {
155
- bodyLines = this.extractMultipartBody(bodyLines.join('\n'), boundary, contentType);
156
- }
157
-
158
- let bodyContent = bodyLines.join('\n').trim();
159
-
160
- // Decode body if necessary
161
- if (isBase64) {
162
- try {
163
- bodyContent = atob(bodyContent.replace(/\s/g, ''));
164
- } catch (e) {
165
- console.warn('Failed to decode base64 content');
166
- }
167
- } else if (isQuotedPrintable) {
168
- bodyContent = this.decodeQuotedPrintable(bodyContent);
169
- }
170
-
171
- // Clean up HTML if present
172
- if (contentType === 'text/html') {
173
- bodyContent = this.sanitizeHtmlContent(bodyContent);
174
- }
175
-
176
- return {
177
- content: bodyContent || 'No content available',
178
- isHtml: contentType === 'text/html'
179
- };
180
- }
181
-
182
- /**
183
- * Extracts body from multipart email
184
- * @param content - Email content
185
- * @param boundary - Multipart boundary string
186
- * @param preferredType - Preferred content type
187
- * @returns Array of body lines
188
- */
189
- private extractMultipartBody(content: string, boundary: string, preferredType: string): string[] {
190
- const parts = content.split('--' + boundary);
191
-
192
- for (const part of parts) {
193
- const lines = part.split(/\r?\n/);
194
- let partContentType = 'text/plain';
195
- let isBase64 = false;
196
- let isQuotedPrintable = false;
197
- let inPartBody = false;
198
- const partBodyLines: string[] = [];
199
-
200
- for (let i = 0; i < lines.length; i++) {
201
- const line = lines[i];
202
-
203
- if (line.toLowerCase().startsWith('content-type:')) {
204
- partContentType = line.toLowerCase().includes('text/html') ? 'text/html' : 'text/plain';
205
- }
206
-
207
- if (line.toLowerCase().startsWith('content-transfer-encoding:')) {
208
- isBase64 = line.toLowerCase().includes('base64');
209
- isQuotedPrintable = line.toLowerCase().includes('quoted-printable');
210
- }
211
-
212
- if (line.trim() === '' && !inPartBody) {
213
- inPartBody = true;
214
- continue;
215
- }
216
-
217
- if (inPartBody) {
218
- partBodyLines.push(line);
219
- }
220
- }
221
-
222
- // If this part matches our preferred content type, use it
223
- if (partContentType === preferredType && partBodyLines.length > 0) {
224
- let bodyContent = partBodyLines.join('\n');
225
-
226
- if (isBase64) {
227
- try {
228
- bodyContent = atob(bodyContent.replace(/\s/g, ''));
229
- } catch (e) {
230
- console.warn('Failed to decode base64 part');
231
- }
232
- } else if (isQuotedPrintable) {
233
- bodyContent = this.decodeQuotedPrintable(bodyContent);
234
- }
235
-
236
- return [bodyContent];
237
- }
238
- }
239
-
240
- // Fallback: return first non-empty part
241
- for (const part of parts) {
242
- const lines = part.split(/\r?\n/);
243
- const bodyLines = lines.filter(line => line.trim() !== '').slice(3); // Skip headers
244
- if (bodyLines.length > 0) {
245
- return bodyLines;
246
- }
247
- }
248
-
249
- return [];
250
- }
251
-
252
- /**
253
- * Decodes quoted-printable encoded content
254
- * @param content - Quoted-printable encoded string
255
- * @returns Decoded string
256
- */
257
- private decodeQuotedPrintable(content: string): string {
258
- return content
259
- .replace(/=\r?\n/g, '') // Remove soft line breaks
260
- .replace(/=([0-9A-F]{2})/gi, (match, hex) => {
261
- return String.fromCharCode(parseInt(hex, 16));
262
- });
263
- }
264
-
265
- /**
266
- * Sanitizes HTML content for safe display
267
- * @param html - Raw HTML content
268
- * @returns Sanitized HTML
269
- */
270
- private sanitizeHtmlContent(html: string): string {
271
- // Basic sanitization - remove script tags and dangerous attributes
272
- let sanitized = html
273
- .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
274
- .replace(/on\w+\s*=\s*["'][^"']*["']/gi, '')
275
- .replace(/javascript:/gi, '');
276
-
277
- return sanitized;
278
- }
279
-
280
- /**
281
- * Parses attachment information from EML content
282
- * @param emlContent - Raw EML content
283
- * @returns Array of attachment information
284
- */
285
- private parseAttachments(emlContent: string): EmailAttachment[] {
286
- const attachments: EmailAttachment[] = [];
287
- const attachmentRegex = /Content-Disposition:\s*attachment[^;]*;\s*filename="?([^"\r\n]+)"?/gi;
288
- let match;
289
-
290
- while ((match = attachmentRegex.exec(emlContent)) !== null) {
291
- attachments.push({
292
- filename: match[1],
293
- contentType: 'application/octet-stream',
294
- size: 0
295
- });
296
- }
297
-
298
- return attachments;
299
- }
300
-
301
- /**
302
- * Cleans and formats email addresses
303
- * @param email - Raw email address string
304
- * @returns Cleaned email address
305
- */
306
- private cleanEmailAddress(email: string): string {
307
- // Remove quotes and extra whitespace
308
- let cleaned = email.replace(/['"]/g, '').trim();
309
-
310
- // Extract email from format: "Name <email@example.com>"
311
- const emailMatch = cleaned.match(/<([^>]+)>/);
312
- if (emailMatch) {
313
- const name = cleaned.substring(0, cleaned.indexOf('<')).trim();
314
- const address = emailMatch[1];
315
- return name ? `${name} <${address}>` : address;
316
- }
317
-
318
- return cleaned;
319
- }
320
-
321
- /**
322
- * Decodes encoded email headers (RFC 2047)
323
- * @param header - Encoded header string
324
- * @returns Decoded header string
325
- */
326
- private decodeHeader(header: string): string {
327
- // Decode RFC 2047 encoded words (=?charset?encoding?text?=)
328
- return header.replace(/=\?([^?]+)\?([BQ])\?([^?]+)\?=/gi, (match, charset, encoding, text) => {
329
- try {
330
- if (encoding.toUpperCase() === 'B') {
331
- // Base64 encoding
332
- return atob(text);
333
- } else if (encoding.toUpperCase() === 'Q') {
334
- // Quoted-printable encoding
335
- return this.decodeQuotedPrintable(text.replace(/_/g, ' '));
336
- }
337
- } catch (e) {
338
- console.warn('Failed to decode header:', match);
339
- }
340
- return match;
341
- });
342
- }
343
-
344
- /**
345
- * Formats email date to readable format
346
- * @param dateStr - Raw date string from email
347
- * @returns Formatted date string
348
- */
349
- private formatDate(dateStr: string): string {
350
- try {
351
- const date = new Date(dateStr);
352
- if (isNaN(date.getTime())) {
353
- return dateStr || 'Unknown date';
354
- }
355
- return date.toLocaleString('en-GB', {
356
- day: '2-digit',
357
- month: 'short',
358
- year: 'numeric',
359
- hour: '2-digit',
360
- minute: '2-digit'
361
- });
362
- } catch (e) {
363
- return dateStr || 'Unknown date';
364
- }
365
- }
366
-
367
- /**
368
- * Sanitizes HTML for Angular display
369
- * @param html - HTML string
370
- * @returns SafeHtml for Angular templates
371
- */
372
- getSafeHtml(html: string): SafeHtml {
373
- return this.sanitizer.sanitize(1, html) || '';
374
- }
375
-
376
- /**
377
- * Downloads and parses an EML file from a URL
378
- * @param documentUrl - URL of the EML file
379
- * @returns Observable of parsed email data
380
- */
381
- loadAndParseEmail(documentUrl: string): Observable<ParsedEmailData> {
382
- console.log('EmlParserService: Loading email from URL:', documentUrl);
383
-
384
- return this.downloadEmailFile(documentUrl).pipe(
385
- map((emlContent: string) => {
386
- console.log('EmlParserService: Email downloaded, size:', emlContent?.length || 0, 'bytes');
387
-
388
- if (!emlContent || emlContent.trim().length === 0) {
389
- throw new Error('Email file is empty or could not be loaded');
390
- }
391
-
392
- const parsedData = this.parseEmlData(emlContent);
393
- if (!parsedData) {
394
- throw new Error('Failed to parse email data');
395
- }
396
-
397
- console.log('EmlParserService: Email parsed successfully:', parsedData);
398
- return parsedData;
399
- }),
400
- catchError((error) => {
401
- console.error('EmlParserService: Error loading/parsing email:', error);
402
- return throwError(() => new Error(error.message || 'Failed to load or parse email file'));
403
- })
404
- );
405
- }
406
-
407
- /**
408
- * Downloads an email file with appropriate authentication handling
409
- * @param documentUrl - URL of the email file
410
- * @returns Observable of file content as text
411
- */
412
- private downloadEmailFile(documentUrl: string): Observable<string> {
413
- // Check if it's Azure Blob Storage URL
414
- const isAzureBlobStorage = documentUrl.includes('.blob.core.windows.net');
415
-
416
- if (isAzureBlobStorage) {
417
- // For Azure Blob Storage, don't send Authorization header
418
- // The URL should contain a SAS token or the blob should be publicly accessible
419
- return this.http.get(documentUrl, {
420
- responseType: 'text'
421
- }).pipe(
422
- catchError((error) => {
423
- console.error('Error downloading email from blob storage:', error);
424
- return throwError(() => new Error('Failed to download email file. Please check if the file URL is valid and accessible.'));
425
- })
426
- );
427
- } else {
428
- // For other storage types, use Bearer token authentication
429
- const Authorization = `Bearer d8764575-d713-4e31-aeb0-29ea31057461`;
430
- return this.http.get(documentUrl, {
431
- headers: new HttpHeaders({
432
- 'Authorization': Authorization
433
- }),
434
- responseType: 'text'
435
- }).pipe(
436
- catchError((error) => {
437
- console.error('Error downloading email file:', error);
438
- return throwError(() => new Error('Failed to download email file. Please check authentication.'));
439
- })
440
- );
441
- }
442
- }
443
- }
444
-
@@ -1,66 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { ExcelParserService } from './excel-parser.service';
3
-
4
- describe('ExcelParserService', () => {
5
- let service: ExcelParserService;
6
-
7
- beforeEach(() => {
8
- TestBed.configureTestingModule({});
9
- service = TestBed.inject(ExcelParserService);
10
- });
11
-
12
- it('should be created', () => {
13
- expect(service).toBeTruthy();
14
- });
15
-
16
- it('should convert RGB to hex correctly', () => {
17
- // Test 6-character format
18
- expect(service['rgbToHex']('ED7D31')).toBe('#ed7d31');
19
-
20
- // Test 8-character format
21
- expect(service['rgbToHex']('FFFF0000')).toBe('#ff0000');
22
-
23
- // Test invalid input
24
- expect(service['rgbToHex']('')).toBe('');
25
- expect(service['rgbToHex']('12345')).toBe('');
26
- });
27
-
28
- it('should convert theme colors correctly', () => {
29
- expect(service['themeToHex'](0)).toBe('#000000'); // Black
30
- expect(service['themeToHex'](1)).toBe('#FFFFFF'); // White
31
- expect(service['themeToHex'](2)).toBe('#FF0000'); // Red
32
- });
33
-
34
- it('should convert indexed colors correctly', () => {
35
- expect(service['indexedToHex'](0)).toBe('#000000'); // Black
36
- expect(service['indexedToHex'](1)).toBe('#FFFFFF'); // White
37
- expect(service['indexedToHex'](64)).toBe('#ED7D31'); // Orange
38
- });
39
-
40
- it('should ensure data consistency', () => {
41
- const testData = [
42
- { cells: [{ value: 'A1' }, { value: 'B1' }] },
43
- { cells: [{ value: 'A2' }] }
44
- ];
45
-
46
- const result = service.ensureDataConsistency(testData);
47
-
48
- expect(result.length).toBe(2);
49
- expect(result[0].cells.length).toBe(3); // Padded to min 3 columns
50
- expect(result[1].cells.length).toBe(3); // Padded to min 3 columns
51
- });
52
-
53
- it('should convert to legacy format', () => {
54
- const testData = [
55
- { cells: [{ value: 'A1' }, { value: 'B1' }] },
56
- { cells: [{ value: 'A2' }, { value: 'B2' }] }
57
- ];
58
-
59
- const result = service.convertToLegacyFormat(testData);
60
-
61
- expect(result).toEqual([
62
- ['A1', 'B1'],
63
- ['A2', 'B2']
64
- ]);
65
- });
66
- });