@serve.zone/dcrouter 5.0.2 → 5.0.3

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 (202) hide show
  1. package/dist_serve/bundle.js +30539 -0
  2. package/dist_serve/bundle.js.map +7 -0
  3. package/dist_serve/index.html +1 -0
  4. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  5. package/dist_ts/00_commitinfo_data.js +9 -0
  6. package/dist_ts/cache/classes.cache.cleaner.d.ts +47 -0
  7. package/dist_ts/cache/classes.cache.cleaner.js +130 -0
  8. package/dist_ts/cache/classes.cached.document.d.ts +76 -0
  9. package/dist_ts/cache/classes.cached.document.js +100 -0
  10. package/dist_ts/cache/classes.cachedb.d.ts +60 -0
  11. package/dist_ts/cache/classes.cachedb.js +125 -0
  12. package/dist_ts/cache/documents/classes.cached.email.d.ts +125 -0
  13. package/dist_ts/cache/documents/classes.cached.email.js +337 -0
  14. package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +119 -0
  15. package/dist_ts/cache/documents/classes.cached.ip.reputation.js +323 -0
  16. package/dist_ts/cache/documents/index.d.ts +2 -0
  17. package/dist_ts/cache/documents/index.js +3 -0
  18. package/dist_ts/cache/index.d.ts +4 -0
  19. package/dist_ts/cache/index.js +7 -0
  20. package/dist_ts/classes.dcrouter.d.ts +276 -0
  21. package/dist_ts/classes.dcrouter.js +1033 -0
  22. package/dist_ts/config/index.d.ts +1 -0
  23. package/dist_ts/config/index.js +3 -0
  24. package/dist_ts/config/validator.d.ts +104 -0
  25. package/dist_ts/config/validator.js +152 -0
  26. package/dist_ts/errors/base.errors.d.ts +224 -0
  27. package/dist_ts/errors/base.errors.js +320 -0
  28. package/dist_ts/errors/error-handler.d.ts +98 -0
  29. package/dist_ts/errors/error-handler.js +282 -0
  30. package/dist_ts/errors/error.codes.d.ts +115 -0
  31. package/dist_ts/errors/error.codes.js +136 -0
  32. package/dist_ts/errors/index.d.ts +54 -0
  33. package/dist_ts/errors/index.js +136 -0
  34. package/dist_ts/errors/reputation.errors.d.ts +183 -0
  35. package/dist_ts/errors/reputation.errors.js +292 -0
  36. package/dist_ts/index.d.ts +6 -0
  37. package/dist_ts/index.js +9 -0
  38. package/dist_ts/logger.d.ts +17 -0
  39. package/dist_ts/logger.js +76 -0
  40. package/dist_ts/monitoring/classes.metricscache.d.ts +32 -0
  41. package/dist_ts/monitoring/classes.metricscache.js +63 -0
  42. package/dist_ts/monitoring/classes.metricsmanager.d.ts +112 -0
  43. package/dist_ts/monitoring/classes.metricsmanager.js +446 -0
  44. package/dist_ts/monitoring/index.d.ts +1 -0
  45. package/dist_ts/monitoring/index.js +2 -0
  46. package/dist_ts/opsserver/classes.opsserver.d.ts +22 -0
  47. package/dist_ts/opsserver/classes.opsserver.js +56 -0
  48. package/dist_ts/opsserver/handlers/admin.handler.d.ts +31 -0
  49. package/dist_ts/opsserver/handlers/admin.handler.js +180 -0
  50. package/dist_ts/opsserver/handlers/config.handler.d.ts +9 -0
  51. package/dist_ts/opsserver/handlers/config.handler.js +67 -0
  52. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +12 -0
  53. package/dist_ts/opsserver/handlers/email-ops.handler.js +219 -0
  54. package/dist_ts/opsserver/handlers/index.d.ts +7 -0
  55. package/dist_ts/opsserver/handlers/index.js +8 -0
  56. package/dist_ts/opsserver/handlers/logs.handler.d.ts +10 -0
  57. package/dist_ts/opsserver/handlers/logs.handler.js +122 -0
  58. package/dist_ts/opsserver/handlers/radius.handler.d.ts +8 -0
  59. package/dist_ts/opsserver/handlers/radius.handler.js +296 -0
  60. package/dist_ts/opsserver/handlers/security.handler.d.ts +11 -0
  61. package/dist_ts/opsserver/handlers/security.handler.js +217 -0
  62. package/dist_ts/opsserver/handlers/stats.handler.d.ts +13 -0
  63. package/dist_ts/opsserver/handlers/stats.handler.js +366 -0
  64. package/dist_ts/opsserver/helpers/guards.d.ts +25 -0
  65. package/dist_ts/opsserver/helpers/guards.js +41 -0
  66. package/dist_ts/opsserver/index.d.ts +1 -0
  67. package/dist_ts/opsserver/index.js +2 -0
  68. package/dist_ts/paths.d.ts +14 -0
  69. package/dist_ts/paths.js +39 -0
  70. package/dist_ts/plugins.d.ts +78 -0
  71. package/dist_ts/plugins.js +112 -0
  72. package/dist_ts/radius/classes.accounting.manager.d.ts +218 -0
  73. package/dist_ts/radius/classes.accounting.manager.js +417 -0
  74. package/dist_ts/radius/classes.radius.server.d.ts +171 -0
  75. package/dist_ts/radius/classes.radius.server.js +385 -0
  76. package/dist_ts/radius/classes.vlan.manager.d.ts +128 -0
  77. package/dist_ts/radius/classes.vlan.manager.js +272 -0
  78. package/dist_ts/radius/index.d.ts +13 -0
  79. package/dist_ts/radius/index.js +14 -0
  80. package/dist_ts/security/classes.contentscanner.d.ts +160 -0
  81. package/dist_ts/security/classes.contentscanner.js +637 -0
  82. package/dist_ts/security/classes.ipreputationchecker.d.ts +150 -0
  83. package/dist_ts/security/classes.ipreputationchecker.js +512 -0
  84. package/dist_ts/security/classes.securitylogger.d.ts +140 -0
  85. package/dist_ts/security/classes.securitylogger.js +235 -0
  86. package/dist_ts/security/index.d.ts +3 -0
  87. package/dist_ts/security/index.js +4 -0
  88. package/dist_ts/sms/classes.smsservice.d.ts +15 -0
  89. package/dist_ts/sms/classes.smsservice.js +72 -0
  90. package/dist_ts/sms/config/sms.config.d.ts +93 -0
  91. package/dist_ts/sms/config/sms.config.js +2 -0
  92. package/dist_ts/sms/config/sms.schema.d.ts +5 -0
  93. package/dist_ts/sms/config/sms.schema.js +121 -0
  94. package/dist_ts/sms/index.d.ts +1 -0
  95. package/dist_ts/sms/index.js +2 -0
  96. package/dist_ts/storage/classes.storagemanager.d.ts +82 -0
  97. package/dist_ts/storage/classes.storagemanager.js +344 -0
  98. package/dist_ts/storage/index.d.ts +1 -0
  99. package/dist_ts/storage/index.js +3 -0
  100. package/dist_ts_interfaces/data/auth.d.ts +8 -0
  101. package/dist_ts_interfaces/data/auth.js +2 -0
  102. package/dist_ts_interfaces/data/index.d.ts +2 -0
  103. package/dist_ts_interfaces/data/index.js +3 -0
  104. package/dist_ts_interfaces/data/stats.d.ts +120 -0
  105. package/dist_ts_interfaces/data/stats.js +2 -0
  106. package/{ts_interfaces/index.ts → dist_ts_interfaces/index.d.ts} +1 -5
  107. package/dist_ts_interfaces/index.js +8 -0
  108. package/{ts_interfaces/plugins.ts → dist_ts_interfaces/plugins.d.ts} +1 -5
  109. package/dist_ts_interfaces/plugins.js +4 -0
  110. package/dist_ts_interfaces/requests/admin.d.ts +31 -0
  111. package/dist_ts_interfaces/requests/admin.js +3 -0
  112. package/dist_ts_interfaces/requests/combined.stats.d.ts +24 -0
  113. package/dist_ts_interfaces/requests/combined.stats.js +2 -0
  114. package/dist_ts_interfaces/requests/config.d.ts +13 -0
  115. package/dist_ts_interfaces/requests/config.js +3 -0
  116. package/dist_ts_interfaces/requests/email-ops.d.ts +139 -0
  117. package/dist_ts_interfaces/requests/email-ops.js +3 -0
  118. package/{ts_interfaces/requests/index.ts → dist_ts_interfaces/requests/index.d.ts} +1 -1
  119. package/dist_ts_interfaces/requests/index.js +8 -0
  120. package/dist_ts_interfaces/requests/logs.d.ts +34 -0
  121. package/dist_ts_interfaces/requests/logs.js +4 -0
  122. package/dist_ts_interfaces/requests/radius.d.ts +268 -0
  123. package/dist_ts_interfaces/requests/radius.js +3 -0
  124. package/dist_ts_interfaces/requests/stats.d.ts +131 -0
  125. package/dist_ts_interfaces/requests/stats.js +4 -0
  126. package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
  127. package/dist_ts_web/00_commitinfo_data.js +9 -0
  128. package/dist_ts_web/appstate.d.ts +96 -0
  129. package/dist_ts_web/appstate.js +587 -0
  130. package/dist_ts_web/elements/index.d.ts +8 -0
  131. package/dist_ts_web/elements/index.js +9 -0
  132. package/dist_ts_web/elements/ops-dashboard.d.ts +23 -0
  133. package/dist_ts_web/elements/ops-dashboard.js +271 -0
  134. package/dist_ts_web/elements/ops-view-config.d.ts +17 -0
  135. package/dist_ts_web/elements/ops-view-config.js +414 -0
  136. package/dist_ts_web/elements/ops-view-emails.d.ts +44 -0
  137. package/dist_ts_web/elements/ops-view-emails.js +880 -0
  138. package/dist_ts_web/elements/ops-view-logs.d.ts +13 -0
  139. package/dist_ts_web/elements/ops-view-logs.js +249 -0
  140. package/dist_ts_web/elements/ops-view-network.d.ts +65 -0
  141. package/dist_ts_web/elements/ops-view-network.js +579 -0
  142. package/dist_ts_web/elements/ops-view-overview.d.ts +14 -0
  143. package/dist_ts_web/elements/ops-view-overview.js +344 -0
  144. package/dist_ts_web/elements/ops-view-security.d.ts +21 -0
  145. package/dist_ts_web/elements/ops-view-security.js +568 -0
  146. package/dist_ts_web/elements/shared/css.d.ts +1 -0
  147. package/dist_ts_web/elements/shared/css.js +10 -0
  148. package/dist_ts_web/elements/shared/index.d.ts +2 -0
  149. package/dist_ts_web/elements/shared/index.js +3 -0
  150. package/dist_ts_web/elements/shared/ops-sectionheading.d.ts +5 -0
  151. package/dist_ts_web/elements/shared/ops-sectionheading.js +82 -0
  152. package/dist_ts_web/index.d.ts +1 -0
  153. package/dist_ts_web/index.js +10 -0
  154. package/dist_ts_web/plugins.d.ts +4 -0
  155. package/dist_ts_web/plugins.js +7 -0
  156. package/dist_ts_web/router.d.ts +25 -0
  157. package/dist_ts_web/router.js +165 -0
  158. package/package.json +14 -2
  159. package/ts/00_commitinfo_data.ts +1 -1
  160. package/ts_web/00_commitinfo_data.ts +1 -1
  161. package/.dockerignore +0 -1
  162. package/.gitea/workflows/docker_nottags.yaml +0 -71
  163. package/.gitea/workflows/docker_tags.yaml +0 -106
  164. package/.playwright-mcp/dcrouter-scrollbar-issue.png +0 -0
  165. package/.playwright-mcp/page-2026-02-01T23-10-23-737Z.png +0 -0
  166. package/.playwright-mcp/page-2026-02-01T23-11-19-449Z.png +0 -0
  167. package/.playwright-mcp/page-2026-02-01T23-12-03-126Z.png +0 -0
  168. package/.playwright-mcp/page-2026-02-01T23-12-15-576Z.png +0 -0
  169. package/.vscode/launch.json +0 -11
  170. package/.vscode/settings.json +0 -26
  171. package/Dockerfile +0 -46
  172. package/changelog.md +0 -350
  173. package/cli.child.js +0 -4
  174. package/cli.child.ts +0 -4
  175. package/cli.ts.js +0 -5
  176. package/html/index.html +0 -121
  177. package/test/readme.md +0 -443
  178. package/test/test.config.md +0 -175
  179. package/test/test.contentscanner.ts +0 -265
  180. package/test/test.dcrouter.email.ts +0 -159
  181. package/test/test.dns-server-config.ts +0 -140
  182. package/test/test.dns-socket-handler.ts +0 -148
  183. package/test/test.errors.ts +0 -274
  184. package/test/test.ipreputationchecker.ts +0 -179
  185. package/test/test.jwt-auth.ts +0 -131
  186. package/test/test.opsserver-api.ts +0 -84
  187. package/test/test.protected-endpoint.ts +0 -120
  188. package/test/test.storagemanager.ts +0 -289
  189. package/test_watch/devserver.ts +0 -35
  190. package/ts_interfaces/data/auth.ts +0 -8
  191. package/ts_interfaces/data/index.ts +0 -2
  192. package/ts_interfaces/data/stats.ts +0 -131
  193. package/ts_interfaces/readme.md +0 -205
  194. package/ts_interfaces/requests/admin.ts +0 -46
  195. package/ts_interfaces/requests/combined.stats.ts +0 -25
  196. package/ts_interfaces/requests/config.ts +0 -18
  197. package/ts_interfaces/requests/email-ops.ts +0 -239
  198. package/ts_interfaces/requests/logs.ts +0 -44
  199. package/ts_interfaces/requests/radius.ts +0 -329
  200. package/ts_interfaces/requests/stats.ts +0 -162
  201. package/ts_interfaces/tspublish.json +0 -3
  202. package/tsconfig.json +0 -12
@@ -0,0 +1,880 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { DeesElement, property, html, customElement, css, state, cssManager } from '@design.estate/dees-element';
36
+ import * as appstate from '../appstate.js';
37
+ import * as shared from './shared/index.js';
38
+ import * as interfaces from '../../dist_ts_interfaces/index.js';
39
+ import { appRouter } from '../router.js';
40
+ let OpsViewEmails = (() => {
41
+ let _classDecorators = [customElement('ops-view-emails')];
42
+ let _classDescriptor;
43
+ let _classExtraInitializers = [];
44
+ let _classThis;
45
+ let _classSuper = DeesElement;
46
+ let _selectedFolder_decorators;
47
+ let _selectedFolder_initializers = [];
48
+ let _selectedFolder_extraInitializers = [];
49
+ let _queuedEmails_decorators;
50
+ let _queuedEmails_initializers = [];
51
+ let _queuedEmails_extraInitializers = [];
52
+ let _sentEmails_decorators;
53
+ let _sentEmails_initializers = [];
54
+ let _sentEmails_extraInitializers = [];
55
+ let _failedEmails_decorators;
56
+ let _failedEmails_initializers = [];
57
+ let _failedEmails_extraInitializers = [];
58
+ let _securityIncidents_decorators;
59
+ let _securityIncidents_initializers = [];
60
+ let _securityIncidents_extraInitializers = [];
61
+ let _selectedEmail_decorators;
62
+ let _selectedEmail_initializers = [];
63
+ let _selectedEmail_extraInitializers = [];
64
+ let _selectedIncident_decorators;
65
+ let _selectedIncident_initializers = [];
66
+ let _selectedIncident_extraInitializers = [];
67
+ let _showCompose_decorators;
68
+ let _showCompose_initializers = [];
69
+ let _showCompose_extraInitializers = [];
70
+ let _isLoading_decorators;
71
+ let _isLoading_initializers = [];
72
+ let _isLoading_extraInitializers = [];
73
+ let _searchTerm_decorators;
74
+ let _searchTerm_initializers = [];
75
+ let _searchTerm_extraInitializers = [];
76
+ let _emailDomains_decorators;
77
+ let _emailDomains_initializers = [];
78
+ let _emailDomains_extraInitializers = [];
79
+ var OpsViewEmails = class extends _classSuper {
80
+ static { _classThis = this; }
81
+ static {
82
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
83
+ _selectedFolder_decorators = [state()];
84
+ _queuedEmails_decorators = [state()];
85
+ _sentEmails_decorators = [state()];
86
+ _failedEmails_decorators = [state()];
87
+ _securityIncidents_decorators = [state()];
88
+ _selectedEmail_decorators = [state()];
89
+ _selectedIncident_decorators = [state()];
90
+ _showCompose_decorators = [state()];
91
+ _isLoading_decorators = [state()];
92
+ _searchTerm_decorators = [state()];
93
+ _emailDomains_decorators = [state()];
94
+ __esDecorate(this, null, _selectedFolder_decorators, { kind: "accessor", name: "selectedFolder", static: false, private: false, access: { has: obj => "selectedFolder" in obj, get: obj => obj.selectedFolder, set: (obj, value) => { obj.selectedFolder = value; } }, metadata: _metadata }, _selectedFolder_initializers, _selectedFolder_extraInitializers);
95
+ __esDecorate(this, null, _queuedEmails_decorators, { kind: "accessor", name: "queuedEmails", static: false, private: false, access: { has: obj => "queuedEmails" in obj, get: obj => obj.queuedEmails, set: (obj, value) => { obj.queuedEmails = value; } }, metadata: _metadata }, _queuedEmails_initializers, _queuedEmails_extraInitializers);
96
+ __esDecorate(this, null, _sentEmails_decorators, { kind: "accessor", name: "sentEmails", static: false, private: false, access: { has: obj => "sentEmails" in obj, get: obj => obj.sentEmails, set: (obj, value) => { obj.sentEmails = value; } }, metadata: _metadata }, _sentEmails_initializers, _sentEmails_extraInitializers);
97
+ __esDecorate(this, null, _failedEmails_decorators, { kind: "accessor", name: "failedEmails", static: false, private: false, access: { has: obj => "failedEmails" in obj, get: obj => obj.failedEmails, set: (obj, value) => { obj.failedEmails = value; } }, metadata: _metadata }, _failedEmails_initializers, _failedEmails_extraInitializers);
98
+ __esDecorate(this, null, _securityIncidents_decorators, { kind: "accessor", name: "securityIncidents", static: false, private: false, access: { has: obj => "securityIncidents" in obj, get: obj => obj.securityIncidents, set: (obj, value) => { obj.securityIncidents = value; } }, metadata: _metadata }, _securityIncidents_initializers, _securityIncidents_extraInitializers);
99
+ __esDecorate(this, null, _selectedEmail_decorators, { kind: "accessor", name: "selectedEmail", static: false, private: false, access: { has: obj => "selectedEmail" in obj, get: obj => obj.selectedEmail, set: (obj, value) => { obj.selectedEmail = value; } }, metadata: _metadata }, _selectedEmail_initializers, _selectedEmail_extraInitializers);
100
+ __esDecorate(this, null, _selectedIncident_decorators, { kind: "accessor", name: "selectedIncident", static: false, private: false, access: { has: obj => "selectedIncident" in obj, get: obj => obj.selectedIncident, set: (obj, value) => { obj.selectedIncident = value; } }, metadata: _metadata }, _selectedIncident_initializers, _selectedIncident_extraInitializers);
101
+ __esDecorate(this, null, _showCompose_decorators, { kind: "accessor", name: "showCompose", static: false, private: false, access: { has: obj => "showCompose" in obj, get: obj => obj.showCompose, set: (obj, value) => { obj.showCompose = value; } }, metadata: _metadata }, _showCompose_initializers, _showCompose_extraInitializers);
102
+ __esDecorate(this, null, _isLoading_decorators, { kind: "accessor", name: "isLoading", static: false, private: false, access: { has: obj => "isLoading" in obj, get: obj => obj.isLoading, set: (obj, value) => { obj.isLoading = value; } }, metadata: _metadata }, _isLoading_initializers, _isLoading_extraInitializers);
103
+ __esDecorate(this, null, _searchTerm_decorators, { kind: "accessor", name: "searchTerm", static: false, private: false, access: { has: obj => "searchTerm" in obj, get: obj => obj.searchTerm, set: (obj, value) => { obj.searchTerm = value; } }, metadata: _metadata }, _searchTerm_initializers, _searchTerm_extraInitializers);
104
+ __esDecorate(this, null, _emailDomains_decorators, { kind: "accessor", name: "emailDomains", static: false, private: false, access: { has: obj => "emailDomains" in obj, get: obj => obj.emailDomains, set: (obj, value) => { obj.emailDomains = value; } }, metadata: _metadata }, _emailDomains_initializers, _emailDomains_extraInitializers);
105
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
106
+ OpsViewEmails = _classThis = _classDescriptor.value;
107
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
108
+ }
109
+ #selectedFolder_accessor_storage = __runInitializers(this, _selectedFolder_initializers, 'queued');
110
+ get selectedFolder() { return this.#selectedFolder_accessor_storage; }
111
+ set selectedFolder(value) { this.#selectedFolder_accessor_storage = value; }
112
+ #queuedEmails_accessor_storage = (__runInitializers(this, _selectedFolder_extraInitializers), __runInitializers(this, _queuedEmails_initializers, []));
113
+ get queuedEmails() { return this.#queuedEmails_accessor_storage; }
114
+ set queuedEmails(value) { this.#queuedEmails_accessor_storage = value; }
115
+ #sentEmails_accessor_storage = (__runInitializers(this, _queuedEmails_extraInitializers), __runInitializers(this, _sentEmails_initializers, []));
116
+ get sentEmails() { return this.#sentEmails_accessor_storage; }
117
+ set sentEmails(value) { this.#sentEmails_accessor_storage = value; }
118
+ #failedEmails_accessor_storage = (__runInitializers(this, _sentEmails_extraInitializers), __runInitializers(this, _failedEmails_initializers, []));
119
+ get failedEmails() { return this.#failedEmails_accessor_storage; }
120
+ set failedEmails(value) { this.#failedEmails_accessor_storage = value; }
121
+ #securityIncidents_accessor_storage = (__runInitializers(this, _failedEmails_extraInitializers), __runInitializers(this, _securityIncidents_initializers, []));
122
+ get securityIncidents() { return this.#securityIncidents_accessor_storage; }
123
+ set securityIncidents(value) { this.#securityIncidents_accessor_storage = value; }
124
+ #selectedEmail_accessor_storage = (__runInitializers(this, _securityIncidents_extraInitializers), __runInitializers(this, _selectedEmail_initializers, null));
125
+ get selectedEmail() { return this.#selectedEmail_accessor_storage; }
126
+ set selectedEmail(value) { this.#selectedEmail_accessor_storage = value; }
127
+ #selectedIncident_accessor_storage = (__runInitializers(this, _selectedEmail_extraInitializers), __runInitializers(this, _selectedIncident_initializers, null));
128
+ get selectedIncident() { return this.#selectedIncident_accessor_storage; }
129
+ set selectedIncident(value) { this.#selectedIncident_accessor_storage = value; }
130
+ #showCompose_accessor_storage = (__runInitializers(this, _selectedIncident_extraInitializers), __runInitializers(this, _showCompose_initializers, false));
131
+ get showCompose() { return this.#showCompose_accessor_storage; }
132
+ set showCompose(value) { this.#showCompose_accessor_storage = value; }
133
+ #isLoading_accessor_storage = (__runInitializers(this, _showCompose_extraInitializers), __runInitializers(this, _isLoading_initializers, false));
134
+ get isLoading() { return this.#isLoading_accessor_storage; }
135
+ set isLoading(value) { this.#isLoading_accessor_storage = value; }
136
+ #searchTerm_accessor_storage = (__runInitializers(this, _isLoading_extraInitializers), __runInitializers(this, _searchTerm_initializers, ''));
137
+ get searchTerm() { return this.#searchTerm_accessor_storage; }
138
+ set searchTerm(value) { this.#searchTerm_accessor_storage = value; }
139
+ #emailDomains_accessor_storage = (__runInitializers(this, _searchTerm_extraInitializers), __runInitializers(this, _emailDomains_initializers, []));
140
+ get emailDomains() { return this.#emailDomains_accessor_storage; }
141
+ set emailDomains(value) { this.#emailDomains_accessor_storage = value; }
142
+ stateSubscription = __runInitializers(this, _emailDomains_extraInitializers);
143
+ constructor() {
144
+ super();
145
+ this.loadData();
146
+ this.loadEmailDomains();
147
+ }
148
+ async connectedCallback() {
149
+ await super.connectedCallback();
150
+ // Subscribe to state changes
151
+ this.stateSubscription = appstate.emailOpsStatePart.state.subscribe((state) => {
152
+ this.queuedEmails = state.queuedEmails;
153
+ this.sentEmails = state.sentEmails;
154
+ this.failedEmails = state.failedEmails;
155
+ this.securityIncidents = state.securityIncidents;
156
+ this.isLoading = state.isLoading;
157
+ // Sync folder from state (e.g., when URL changes)
158
+ if (state.currentView !== this.selectedFolder) {
159
+ this.selectedFolder = state.currentView;
160
+ this.loadFolderData(state.currentView);
161
+ }
162
+ });
163
+ }
164
+ async disconnectedCallback() {
165
+ await super.disconnectedCallback();
166
+ if (this.stateSubscription) {
167
+ this.stateSubscription.unsubscribe();
168
+ }
169
+ }
170
+ static styles = [
171
+ cssManager.defaultStyles,
172
+ shared.viewHostCss,
173
+ css `
174
+ :host {
175
+ display: block;
176
+ height: 100%;
177
+ }
178
+
179
+ .emailLayout {
180
+ display: flex;
181
+ gap: 16px;
182
+ height: 100%;
183
+ min-height: 600px;
184
+ }
185
+
186
+ .sidebar {
187
+ flex-shrink: 0;
188
+ width: 280px;
189
+ }
190
+
191
+ .mainArea {
192
+ flex: 1;
193
+ display: flex;
194
+ flex-direction: column;
195
+ gap: 16px;
196
+ overflow: hidden;
197
+ }
198
+
199
+ .emailToolbar {
200
+ display: flex;
201
+ align-items: center;
202
+ gap: 12px;
203
+ flex-wrap: wrap;
204
+ }
205
+
206
+ .searchBox {
207
+ flex: 1;
208
+ min-width: 200px;
209
+ max-width: 400px;
210
+ }
211
+
212
+ .emailList {
213
+ flex: 1;
214
+ overflow: hidden;
215
+ }
216
+
217
+ .emailPreview {
218
+ flex: 1;
219
+ display: flex;
220
+ flex-direction: column;
221
+ background: ${cssManager.bdTheme('#fff', '#222')};
222
+ border: 1px solid ${cssManager.bdTheme('#e9ecef', '#333')};
223
+ border-radius: 8px;
224
+ overflow: hidden;
225
+ }
226
+
227
+ .emailHeader {
228
+ padding: 24px;
229
+ border-bottom: 1px solid ${cssManager.bdTheme('#e9ecef', '#333')};
230
+ }
231
+
232
+ .emailSubject {
233
+ font-size: 24px;
234
+ font-weight: 600;
235
+ margin-bottom: 16px;
236
+ color: ${cssManager.bdTheme('#333', '#ccc')};
237
+ }
238
+
239
+ .emailMeta {
240
+ display: flex;
241
+ flex-direction: column;
242
+ gap: 8px;
243
+ font-size: 14px;
244
+ color: ${cssManager.bdTheme('#666', '#999')};
245
+ }
246
+
247
+ .emailMetaRow {
248
+ display: flex;
249
+ gap: 8px;
250
+ }
251
+
252
+ .emailMetaLabel {
253
+ font-weight: 600;
254
+ min-width: 80px;
255
+ }
256
+
257
+ .emailBody {
258
+ flex: 1;
259
+ padding: 24px;
260
+ overflow-y: auto;
261
+ font-size: 15px;
262
+ line-height: 1.6;
263
+ }
264
+
265
+ .emailActions {
266
+ display: flex;
267
+ gap: 8px;
268
+ padding: 16px 24px;
269
+ border-top: 1px solid ${cssManager.bdTheme('#e9ecef', '#333')};
270
+ background: ${cssManager.bdTheme('#fafafa', '#1a1a1a')};
271
+ }
272
+
273
+ .emptyState {
274
+ display: flex;
275
+ flex-direction: column;
276
+ align-items: center;
277
+ justify-content: center;
278
+ height: 400px;
279
+ color: ${cssManager.bdTheme('#999', '#666')};
280
+ }
281
+
282
+ .emptyIcon {
283
+ font-size: 64px;
284
+ margin-bottom: 16px;
285
+ opacity: 0.3;
286
+ }
287
+
288
+ .emptyText {
289
+ font-size: 18px;
290
+ }
291
+
292
+ .status-pending {
293
+ color: ${cssManager.bdTheme('#f59e0b', '#fbbf24')};
294
+ }
295
+
296
+ .status-processing {
297
+ color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
298
+ }
299
+
300
+ .status-delivered {
301
+ color: ${cssManager.bdTheme('#10b981', '#34d399')};
302
+ }
303
+
304
+ .status-failed {
305
+ color: ${cssManager.bdTheme('#ef4444', '#f87171')};
306
+ }
307
+
308
+ .status-deferred {
309
+ color: ${cssManager.bdTheme('#f97316', '#fb923c')};
310
+ }
311
+
312
+ .severity-info {
313
+ color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
314
+ }
315
+
316
+ .severity-warn {
317
+ color: ${cssManager.bdTheme('#f59e0b', '#fbbf24')};
318
+ }
319
+
320
+ .severity-error {
321
+ color: ${cssManager.bdTheme('#ef4444', '#f87171')};
322
+ }
323
+
324
+ .severity-critical {
325
+ color: ${cssManager.bdTheme('#dc2626', '#ef4444')};
326
+ font-weight: bold;
327
+ }
328
+
329
+ .incidentDetails {
330
+ padding: 24px;
331
+ background: ${cssManager.bdTheme('#fff', '#222')};
332
+ border: 1px solid ${cssManager.bdTheme('#e9ecef', '#333')};
333
+ border-radius: 8px;
334
+ }
335
+
336
+ .incidentHeader {
337
+ display: flex;
338
+ justify-content: space-between;
339
+ align-items: flex-start;
340
+ margin-bottom: 16px;
341
+ }
342
+
343
+ .incidentTitle {
344
+ font-size: 20px;
345
+ font-weight: 600;
346
+ }
347
+
348
+ .incidentMeta {
349
+ display: grid;
350
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
351
+ gap: 12px;
352
+ margin-top: 16px;
353
+ }
354
+
355
+ .incidentField {
356
+ padding: 12px;
357
+ background: ${cssManager.bdTheme('#f8f9fa', '#1a1a1a')};
358
+ border-radius: 6px;
359
+ }
360
+
361
+ .incidentFieldLabel {
362
+ font-size: 12px;
363
+ color: ${cssManager.bdTheme('#666', '#999')};
364
+ margin-bottom: 4px;
365
+ }
366
+
367
+ .incidentFieldValue {
368
+ font-size: 14px;
369
+ word-break: break-all;
370
+ }
371
+ `,
372
+ ];
373
+ render() {
374
+ if (this.selectedEmail) {
375
+ return this.renderEmailDetail();
376
+ }
377
+ if (this.selectedIncident) {
378
+ return this.renderIncidentDetail();
379
+ }
380
+ return html `
381
+ <ops-sectionheading>Email Operations</ops-sectionheading>
382
+
383
+ <!-- Toolbar -->
384
+ <div class="emailToolbar" style="margin-bottom: 16px;">
385
+ <dees-button @click=${() => this.openComposeModal()} type="highlighted">
386
+ <dees-icon icon="lucide:penLine" slot="iconSlot"></dees-icon>
387
+ Compose
388
+ </dees-button>
389
+
390
+ <dees-input-text
391
+ class="searchBox"
392
+ placeholder="Search..."
393
+ .value=${this.searchTerm}
394
+ @input=${(e) => this.searchTerm = e.target.value}
395
+ >
396
+ <dees-icon icon="lucide:search" slot="iconSlot"></dees-icon>
397
+ </dees-input-text>
398
+
399
+ <dees-button @click=${() => this.refreshData()}>
400
+ ${this.isLoading ? html `<dees-spinner slot="iconSlot" size="small"></dees-spinner>` : html `<dees-icon slot="iconSlot" icon="lucide:refreshCw"></dees-icon>`}
401
+ Refresh
402
+ </dees-button>
403
+
404
+ <div style="margin-left: auto; display: flex; gap: 8px;">
405
+ <dees-button-group>
406
+ <dees-button
407
+ @click=${() => this.selectFolder('queued')}
408
+ .type=${this.selectedFolder === 'queued' ? 'highlighted' : 'normal'}
409
+ >
410
+ Queued ${this.queuedEmails.length > 0 ? `(${this.queuedEmails.length})` : ''}
411
+ </dees-button>
412
+ <dees-button
413
+ @click=${() => this.selectFolder('sent')}
414
+ .type=${this.selectedFolder === 'sent' ? 'highlighted' : 'normal'}
415
+ >
416
+ Sent
417
+ </dees-button>
418
+ <dees-button
419
+ @click=${() => this.selectFolder('failed')}
420
+ .type=${this.selectedFolder === 'failed' ? 'highlighted' : 'normal'}
421
+ >
422
+ Failed ${this.failedEmails.length > 0 ? `(${this.failedEmails.length})` : ''}
423
+ </dees-button>
424
+ <dees-button
425
+ @click=${() => this.selectFolder('security')}
426
+ .type=${this.selectedFolder === 'security' ? 'highlighted' : 'normal'}
427
+ >
428
+ Security ${this.securityIncidents.length > 0 ? `(${this.securityIncidents.length})` : ''}
429
+ </dees-button>
430
+ </dees-button-group>
431
+ </div>
432
+ </div>
433
+
434
+ ${this.renderContent()}
435
+ `;
436
+ }
437
+ renderContent() {
438
+ switch (this.selectedFolder) {
439
+ case 'queued':
440
+ return this.renderEmailTable(this.queuedEmails, 'Queued Emails', 'Emails waiting to be delivered');
441
+ case 'sent':
442
+ return this.renderEmailTable(this.sentEmails, 'Sent Emails', 'Successfully delivered emails');
443
+ case 'failed':
444
+ return this.renderEmailTable(this.failedEmails, 'Failed Emails', 'Emails that failed to deliver', true);
445
+ case 'security':
446
+ return this.renderSecurityIncidents();
447
+ default:
448
+ return this.renderEmptyState('Select a folder');
449
+ }
450
+ }
451
+ renderEmailTable(emails, heading1, heading2, showResend = false) {
452
+ const filteredEmails = this.filterEmails(emails);
453
+ if (filteredEmails.length === 0) {
454
+ return this.renderEmptyState(`No emails in ${this.selectedFolder}`);
455
+ }
456
+ const actions = [
457
+ {
458
+ name: 'View Details',
459
+ iconName: 'lucide:eye',
460
+ type: ['doubleClick', 'inRow'],
461
+ actionFunc: async (actionData) => {
462
+ this.selectedEmail = actionData.item;
463
+ }
464
+ }
465
+ ];
466
+ if (showResend) {
467
+ actions.push({
468
+ name: 'Resend',
469
+ iconName: 'lucide:send',
470
+ type: ['inRow'],
471
+ actionFunc: async (actionData) => {
472
+ await this.resendEmail(actionData.item.id);
473
+ }
474
+ });
475
+ }
476
+ return html `
477
+ <dees-table
478
+ .data=${filteredEmails}
479
+ .displayFunction=${(email) => ({
480
+ 'Status': html `<span class="status-${email.status}">${email.status}</span>`,
481
+ 'From': email.from || 'N/A',
482
+ 'To': email.to?.join(', ') || 'N/A',
483
+ 'Subject': email.subject || 'No subject',
484
+ 'Attempts': email.attempts,
485
+ 'Created': this.formatDate(email.createdAt),
486
+ })}
487
+ .dataActions=${actions}
488
+ .selectionMode=${'single'}
489
+ heading1=${heading1}
490
+ heading2=${`${filteredEmails.length} emails - ${heading2}`}
491
+ ></dees-table>
492
+ `;
493
+ }
494
+ renderSecurityIncidents() {
495
+ const incidents = this.securityIncidents;
496
+ if (incidents.length === 0) {
497
+ return this.renderEmptyState('No security incidents');
498
+ }
499
+ return html `
500
+ <dees-table
501
+ .data=${incidents}
502
+ .displayFunction=${(incident) => ({
503
+ 'Severity': html `<span class="severity-${incident.level}">${incident.level.toUpperCase()}</span>`,
504
+ 'Type': incident.type,
505
+ 'Message': incident.message,
506
+ 'IP': incident.ipAddress || 'N/A',
507
+ 'Domain': incident.domain || 'N/A',
508
+ 'Time': this.formatDate(incident.timestamp),
509
+ })}
510
+ .dataActions=${[
511
+ {
512
+ name: 'View Details',
513
+ iconName: 'lucide:eye',
514
+ type: ['doubleClick', 'inRow'],
515
+ actionFunc: async (actionData) => {
516
+ this.selectedIncident = actionData.item;
517
+ }
518
+ }
519
+ ]}
520
+ .selectionMode=${'single'}
521
+ heading1="Security Incidents"
522
+ heading2=${`${incidents.length} incidents`}
523
+ ></dees-table>
524
+ `;
525
+ }
526
+ renderEmailDetail() {
527
+ if (!this.selectedEmail)
528
+ return '';
529
+ return html `
530
+ <ops-sectionheading>Email Details</ops-sectionheading>
531
+ <div class="emailLayout">
532
+ <div class="sidebar">
533
+ <dees-windowbox>
534
+ <dees-button @click=${() => this.selectedEmail = null} type="secondary" style="width: 100%;">
535
+ <dees-icon icon="lucide:arrowLeft" slot="iconSlot"></dees-icon>
536
+ Back to List
537
+ </dees-button>
538
+ </dees-windowbox>
539
+ </div>
540
+ <div class="mainArea">
541
+ <div class="emailPreview">
542
+ <div class="emailHeader">
543
+ <div class="emailSubject">${this.selectedEmail.subject || 'No subject'}</div>
544
+ <div class="emailMeta">
545
+ <div class="emailMetaRow">
546
+ <span class="emailMetaLabel">Status:</span>
547
+ <span class="status-${this.selectedEmail.status}">${this.selectedEmail.status}</span>
548
+ </div>
549
+ <div class="emailMetaRow">
550
+ <span class="emailMetaLabel">From:</span>
551
+ <span>${this.selectedEmail.from || 'N/A'}</span>
552
+ </div>
553
+ <div class="emailMetaRow">
554
+ <span class="emailMetaLabel">To:</span>
555
+ <span>${this.selectedEmail.to?.join(', ') || 'N/A'}</span>
556
+ </div>
557
+ <div class="emailMetaRow">
558
+ <span class="emailMetaLabel">Mode:</span>
559
+ <span>${this.selectedEmail.processingMode}</span>
560
+ </div>
561
+ <div class="emailMetaRow">
562
+ <span class="emailMetaLabel">Attempts:</span>
563
+ <span>${this.selectedEmail.attempts}</span>
564
+ </div>
565
+ <div class="emailMetaRow">
566
+ <span class="emailMetaLabel">Created:</span>
567
+ <span>${new Date(this.selectedEmail.createdAt).toLocaleString()}</span>
568
+ </div>
569
+ ${this.selectedEmail.deliveredAt ? html `
570
+ <div class="emailMetaRow">
571
+ <span class="emailMetaLabel">Delivered:</span>
572
+ <span>${new Date(this.selectedEmail.deliveredAt).toLocaleString()}</span>
573
+ </div>
574
+ ` : ''}
575
+ ${this.selectedEmail.lastError ? html `
576
+ <div class="emailMetaRow">
577
+ <span class="emailMetaLabel">Last Error:</span>
578
+ <span style="color: #ef4444;">${this.selectedEmail.lastError}</span>
579
+ </div>
580
+ ` : ''}
581
+ </div>
582
+ </div>
583
+
584
+ <div class="emailActions">
585
+ ${this.selectedEmail.status === 'failed' ? html `
586
+ <dees-button @click=${() => this.resendEmail(this.selectedEmail.id)} type="highlighted">
587
+ <dees-icon icon="lucide:send" slot="iconSlot"></dees-icon>
588
+ Resend
589
+ </dees-button>
590
+ ` : ''}
591
+ <dees-button @click=${() => this.selectedEmail = null}>
592
+ <dees-icon icon="lucide:x" slot="iconSlot"></dees-icon>
593
+ Close
594
+ </dees-button>
595
+ </div>
596
+ </div>
597
+ </div>
598
+ </div>
599
+ `;
600
+ }
601
+ renderIncidentDetail() {
602
+ if (!this.selectedIncident)
603
+ return '';
604
+ const incident = this.selectedIncident;
605
+ return html `
606
+ <ops-sectionheading>Security Incident Details</ops-sectionheading>
607
+ <div style="margin-bottom: 16px;">
608
+ <dees-button @click=${() => this.selectedIncident = null} type="secondary">
609
+ <dees-icon icon="lucide:arrowLeft" slot="iconSlot"></dees-icon>
610
+ Back to List
611
+ </dees-button>
612
+ </div>
613
+ <div class="incidentDetails">
614
+ <div class="incidentHeader">
615
+ <div>
616
+ <div class="incidentTitle">${incident.message}</div>
617
+ <div style="margin-top: 8px; color: #666;">
618
+ ${new Date(incident.timestamp).toLocaleString()}
619
+ </div>
620
+ </div>
621
+ <span class="severity-${incident.level}" style="font-size: 16px; padding: 4px 12px; background: rgba(0,0,0,0.1); border-radius: 4px;">
622
+ ${incident.level.toUpperCase()}
623
+ </span>
624
+ </div>
625
+
626
+ <div class="incidentMeta">
627
+ <div class="incidentField">
628
+ <div class="incidentFieldLabel">Type</div>
629
+ <div class="incidentFieldValue">${incident.type}</div>
630
+ </div>
631
+ ${incident.ipAddress ? html `
632
+ <div class="incidentField">
633
+ <div class="incidentFieldLabel">IP Address</div>
634
+ <div class="incidentFieldValue">${incident.ipAddress}</div>
635
+ </div>
636
+ ` : ''}
637
+ ${incident.domain ? html `
638
+ <div class="incidentField">
639
+ <div class="incidentFieldLabel">Domain</div>
640
+ <div class="incidentFieldValue">${incident.domain}</div>
641
+ </div>
642
+ ` : ''}
643
+ ${incident.emailId ? html `
644
+ <div class="incidentField">
645
+ <div class="incidentFieldLabel">Email ID</div>
646
+ <div class="incidentFieldValue">${incident.emailId}</div>
647
+ </div>
648
+ ` : ''}
649
+ ${incident.userId ? html `
650
+ <div class="incidentField">
651
+ <div class="incidentFieldLabel">User ID</div>
652
+ <div class="incidentFieldValue">${incident.userId}</div>
653
+ </div>
654
+ ` : ''}
655
+ ${incident.action ? html `
656
+ <div class="incidentField">
657
+ <div class="incidentFieldLabel">Action</div>
658
+ <div class="incidentFieldValue">${incident.action}</div>
659
+ </div>
660
+ ` : ''}
661
+ ${incident.result ? html `
662
+ <div class="incidentField">
663
+ <div class="incidentFieldLabel">Result</div>
664
+ <div class="incidentFieldValue">${incident.result}</div>
665
+ </div>
666
+ ` : ''}
667
+ ${incident.success !== undefined ? html `
668
+ <div class="incidentField">
669
+ <div class="incidentFieldLabel">Success</div>
670
+ <div class="incidentFieldValue">${incident.success ? 'Yes' : 'No'}</div>
671
+ </div>
672
+ ` : ''}
673
+ </div>
674
+
675
+ ${incident.details ? html `
676
+ <div style="margin-top: 24px;">
677
+ <div class="incidentFieldLabel" style="margin-bottom: 8px;">Details</div>
678
+ <pre style="background: #1a1a1a; color: #e5e5e5; padding: 16px; border-radius: 6px; overflow-x: auto; font-size: 13px;">
679
+ ${JSON.stringify(incident.details, null, 2)}
680
+ </pre>
681
+ </div>
682
+ ` : ''}
683
+ </div>
684
+ `;
685
+ }
686
+ renderEmptyState(message) {
687
+ return html `
688
+ <div class="emptyState">
689
+ <dees-icon class="emptyIcon" icon="lucide:inbox"></dees-icon>
690
+ <div class="emptyText">${message}</div>
691
+ </div>
692
+ `;
693
+ }
694
+ async openComposeModal() {
695
+ const { DeesModal } = await import('@design.estate/dees-catalog');
696
+ // Ensure domains are loaded before opening modal
697
+ if (this.emailDomains.length === 0) {
698
+ await this.loadEmailDomains();
699
+ }
700
+ await DeesModal.createAndShow({
701
+ heading: 'New Email',
702
+ width: 'large',
703
+ content: html `
704
+ <div>
705
+ <dees-form @formData=${async (e) => {
706
+ await this.sendEmail(e.detail);
707
+ const modals = document.querySelectorAll('dees-modal');
708
+ modals.forEach(m => m.destroy?.());
709
+ }}>
710
+ <div style="display: flex; gap: 8px; align-items: flex-end;">
711
+ <dees-input-text
712
+ key="fromUsername"
713
+ label="From"
714
+ placeholder="username"
715
+ .value=${'admin'}
716
+ required
717
+ style="flex: 1;"
718
+ ></dees-input-text>
719
+ <span style="padding-bottom: 12px; font-size: 18px; color: #666;">@</span>
720
+ <dees-input-dropdown
721
+ key="fromDomain"
722
+ label=" "
723
+ .options=${this.emailDomains.length > 0
724
+ ? this.emailDomains.map(domain => ({ key: domain, value: domain }))
725
+ : [{ key: 'dcrouter.local', value: 'dcrouter.local' }]}
726
+ .selectedKey=${this.emailDomains[0] || 'dcrouter.local'}
727
+ required
728
+ style="flex: 1;"
729
+ ></dees-input-dropdown>
730
+ </div>
731
+
732
+ <dees-input-tags
733
+ key="to"
734
+ label="To"
735
+ placeholder="Enter recipient email addresses..."
736
+ required
737
+ ></dees-input-tags>
738
+
739
+ <dees-input-tags
740
+ key="cc"
741
+ label="CC"
742
+ placeholder="Enter CC recipients..."
743
+ ></dees-input-tags>
744
+
745
+ <dees-input-text
746
+ key="subject"
747
+ label="Subject"
748
+ placeholder="Enter email subject..."
749
+ required
750
+ ></dees-input-text>
751
+
752
+ <dees-input-wysiwyg
753
+ key="body"
754
+ label="Message"
755
+ outputFormat="html"
756
+ ></dees-input-wysiwyg>
757
+ </dees-form>
758
+ </div>
759
+ `,
760
+ menuOptions: [
761
+ {
762
+ name: 'Send',
763
+ iconName: 'lucide:send',
764
+ action: async (modalArg) => {
765
+ const form = modalArg.shadowRoot?.querySelector('dees-form');
766
+ form?.submit();
767
+ }
768
+ },
769
+ {
770
+ name: 'Cancel',
771
+ iconName: 'lucide:x',
772
+ action: async (modalArg) => await modalArg.destroy()
773
+ }
774
+ ]
775
+ });
776
+ }
777
+ filterEmails(emails) {
778
+ if (!this.searchTerm) {
779
+ return emails;
780
+ }
781
+ const search = this.searchTerm.toLowerCase();
782
+ return emails.filter(e => (e.subject?.toLowerCase().includes(search)) ||
783
+ (e.from?.toLowerCase().includes(search)) ||
784
+ (e.to?.some(t => t.toLowerCase().includes(search))));
785
+ }
786
+ selectFolder(folder) {
787
+ // Use router for navigation to update URL
788
+ appRouter.navigateToEmailFolder(folder);
789
+ // Clear selections
790
+ this.selectedEmail = null;
791
+ this.selectedIncident = null;
792
+ }
793
+ formatDate(timestamp) {
794
+ const date = new Date(timestamp);
795
+ const now = new Date();
796
+ const diff = now.getTime() - date.getTime();
797
+ const hours = diff / (1000 * 60 * 60);
798
+ if (hours < 24) {
799
+ return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
800
+ }
801
+ else if (hours < 168) { // 7 days
802
+ return date.toLocaleDateString([], { weekday: 'short', hour: '2-digit', minute: '2-digit' });
803
+ }
804
+ else {
805
+ return date.toLocaleDateString([], { month: 'short', day: 'numeric' });
806
+ }
807
+ }
808
+ async loadData() {
809
+ this.isLoading = true;
810
+ await this.loadFolderData(this.selectedFolder);
811
+ this.isLoading = false;
812
+ }
813
+ async loadFolderData(folder) {
814
+ switch (folder) {
815
+ case 'queued':
816
+ await appstate.emailOpsStatePart.dispatchAction(appstate.fetchQueuedEmailsAction, null);
817
+ break;
818
+ case 'sent':
819
+ await appstate.emailOpsStatePart.dispatchAction(appstate.fetchSentEmailsAction, null);
820
+ break;
821
+ case 'failed':
822
+ await appstate.emailOpsStatePart.dispatchAction(appstate.fetchFailedEmailsAction, null);
823
+ break;
824
+ case 'security':
825
+ await appstate.emailOpsStatePart.dispatchAction(appstate.fetchSecurityIncidentsAction, null);
826
+ break;
827
+ }
828
+ }
829
+ async loadEmailDomains() {
830
+ try {
831
+ await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
832
+ const config = appstate.configStatePart.getState().config;
833
+ if (config?.email?.domains && Array.isArray(config.email.domains) && config.email.domains.length > 0) {
834
+ this.emailDomains = config.email.domains;
835
+ }
836
+ else {
837
+ this.emailDomains = ['dcrouter.local'];
838
+ }
839
+ }
840
+ catch (error) {
841
+ console.error('Failed to load email domains:', error);
842
+ this.emailDomains = ['dcrouter.local'];
843
+ }
844
+ }
845
+ async refreshData() {
846
+ this.isLoading = true;
847
+ await this.loadFolderData(this.selectedFolder);
848
+ this.isLoading = false;
849
+ }
850
+ async sendEmail(formData) {
851
+ try {
852
+ console.log('Sending email:', formData);
853
+ // TODO: Implement actual email sending via API
854
+ // For now, just log the data
855
+ const fromEmail = `${formData.fromUsername || 'admin'}@${formData.fromDomain || this.emailDomains[0] || 'dcrouter.local'}`;
856
+ console.log('From:', fromEmail);
857
+ console.log('To:', formData.to);
858
+ console.log('Subject:', formData.subject);
859
+ }
860
+ catch (error) {
861
+ console.error('Failed to send email', error);
862
+ }
863
+ }
864
+ async resendEmail(emailId) {
865
+ try {
866
+ await appstate.emailOpsStatePart.dispatchAction(appstate.resendEmailAction, emailId);
867
+ this.selectedEmail = null;
868
+ }
869
+ catch (error) {
870
+ console.error('Failed to resend email:', error);
871
+ }
872
+ }
873
+ static {
874
+ __runInitializers(_classThis, _classExtraInitializers);
875
+ }
876
+ };
877
+ return OpsViewEmails = _classThis;
878
+ })();
879
+ export { OpsViewEmails };
880
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctZW1haWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL2VsZW1lbnRzL29wcy12aWV3LWVtYWlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBdUIsR0FBRyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0SSxPQUFPLEtBQUssUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUM7QUFDNUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNoRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0lBVzVCLGFBQWE7NEJBRHpCLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQzs7OztzQkFDRSxXQUFXOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzZCQUFuQixTQUFRLFdBQVc7Ozs7MENBQzNDLEtBQUssRUFBRTt3Q0FHUCxLQUFLLEVBQUU7c0NBR1AsS0FBSyxFQUFFO3dDQUdQLEtBQUssRUFBRTs2Q0FHUCxLQUFLLEVBQUU7eUNBR1AsS0FBSyxFQUFFOzRDQUdQLEtBQUssRUFBRTt1Q0FHUCxLQUFLLEVBQUU7cUNBR1AsS0FBSyxFQUFFO3NDQUdQLEtBQUssRUFBRTt3Q0FHUCxLQUFLLEVBQUU7WUE3QlIsK0xBQVMsY0FBYyw2QkFBZCxjQUFjLHVHQUEwQjtZQUdqRCx5TEFBUyxZQUFZLDZCQUFaLFlBQVksbUdBQTZDO1lBR2xFLG1MQUFTLFVBQVUsNkJBQVYsVUFBVSwrRkFBNkM7WUFHaEUseUxBQVMsWUFBWSw2QkFBWixZQUFZLG1HQUE2QztZQUdsRSx3TUFBUyxpQkFBaUIsNkJBQWpCLGlCQUFpQiw2R0FBK0M7WUFHekUsNExB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