@isaiahiroko/tilmart-ngx-apps-admin 0.2.0 → 0.2.2

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 (107) hide show
  1. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-articles.module-OeLRnPwN.mjs → isaiahiroko-tilmart-ngx-apps-admin-articles.module-Cpx9BZcg.mjs} +5 -5
  2. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-articles.module-OeLRnPwN.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-articles.module-Cpx9BZcg.mjs.map} +1 -1
  3. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-attribute-templates.module-CwQnW1cH.mjs +239 -0
  4. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-attribute-templates.module-CwQnW1cH.mjs.map +1 -0
  5. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-audit.module-C9gvw8X2.mjs → isaiahiroko-tilmart-ngx-apps-admin-audit.module-D5YaCThD.mjs} +6 -6
  6. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-audit.module-C9gvw8X2.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-audit.module-D5YaCThD.mjs.map} +1 -1
  7. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-banners.module-KSapnx6Y.mjs +76 -0
  8. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-banners.module-KSapnx6Y.mjs.map +1 -0
  9. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-brands.module-7I0ni-tQ.mjs +70 -0
  10. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-brands.module-7I0ni-tQ.mjs.map +1 -0
  11. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-DoxDNaNn.mjs +538 -0
  12. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-DoxDNaNn.mjs.map +1 -0
  13. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-categories.module-OTUfenf0.mjs +94 -0
  14. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-categories.module-OTUfenf0.mjs.map +1 -0
  15. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-claims.module-Dk9mz7Wj.mjs +137 -0
  16. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-claims.module-Dk9mz7Wj.mjs.map +1 -0
  17. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-compatibility-rules.module-xN-JUWwp.mjs → isaiahiroko-tilmart-ngx-apps-admin-compatibility-rules.module-JiFnNJj_.mjs} +6 -6
  18. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-compatibility-rules.module-xN-JUWwp.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-compatibility-rules.module-JiFnNJj_.mjs.map} +1 -1
  19. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-content.module-DLdKAUqc.mjs → isaiahiroko-tilmart-ngx-apps-admin-content.module-Bx6Zj0WX.mjs} +5 -5
  20. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-content.module-DLdKAUqc.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-content.module-Bx6Zj0WX.mjs.map} +1 -1
  21. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-coupons.module-CoRh6Hxq.mjs +85 -0
  22. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-coupons.module-CoRh6Hxq.mjs.map +1 -0
  23. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-customers.module-CslGiOdq.mjs +123 -0
  24. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-customers.module-CslGiOdq.mjs.map +1 -0
  25. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-data-quality.module-Bfgh3zE5.mjs → isaiahiroko-tilmart-ngx-apps-admin-data-quality.module-CvFmMoJe.mjs} +6 -6
  26. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-data-quality.module-Bfgh3zE5.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-data-quality.module-CvFmMoJe.mjs.map} +1 -1
  27. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-data-requests.module-C6tPNlup.mjs → isaiahiroko-tilmart-ngx-apps-admin-data-requests.module-CuZwNVPO.mjs} +6 -6
  28. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-data-requests.module-C6tPNlup.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-data-requests.module-CuZwNVPO.mjs.map} +1 -1
  29. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-flash-sales.module-BPRnC17l.mjs +83 -0
  30. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-flash-sales.module-BPRnC17l.mjs.map +1 -0
  31. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-homepage.module-BZ3UmxE3.mjs → isaiahiroko-tilmart-ngx-apps-admin-homepage.module-vtAoIwSu.mjs} +5 -5
  32. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-homepage.module-BZ3UmxE3.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-homepage.module-vtAoIwSu.mjs.map} +1 -1
  33. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-inbox.module-BZDTa1L-.mjs → isaiahiroko-tilmart-ngx-apps-admin-inbox.module-CRkfjWQT.mjs} +6 -6
  34. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-inbox.module-BZDTa1L-.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-inbox.module-CRkfjWQT.mjs.map} +1 -1
  35. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-list-page.base-Cl7JZ-Tp.mjs +66 -0
  36. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-list-page.base-Cl7JZ-Tp.mjs.map +1 -0
  37. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-macros.module-BO4bdER2.mjs → isaiahiroko-tilmart-ngx-apps-admin-macros.module-CElxL9W4.mjs} +5 -5
  38. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-macros.module-BO4bdER2.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-macros.module-CElxL9W4.mjs.map} +1 -1
  39. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-moderation.module-CZOCrias.mjs → isaiahiroko-tilmart-ngx-apps-admin-moderation.module-PGmFX7nk.mjs} +6 -6
  40. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-moderation.module-CZOCrias.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-moderation.module-PGmFX7nk.mjs.map} +1 -1
  41. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-navigation.module-DoKzzRgn.mjs → isaiahiroko-tilmart-ngx-apps-admin-navigation.module-De1Cvqqa.mjs} +6 -6
  42. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-navigation.module-DoKzzRgn.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-navigation.module-De1Cvqqa.mjs.map} +1 -1
  43. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-order-board.module-DIOjhptn.mjs → isaiahiroko-tilmart-ngx-apps-admin-order-board.module-CmLNiEEP.mjs} +4 -4
  44. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-order-board.module-DIOjhptn.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-order-board.module-CmLNiEEP.mjs.map} +1 -1
  45. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-orders.module-Ddw49QW0.mjs → isaiahiroko-tilmart-ngx-apps-admin-orders.module-Cfeb0QjH.mjs} +15 -33
  46. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-orders.module-Cfeb0QjH.mjs.map +1 -0
  47. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-payments.module-DstLDYM7.mjs +114 -0
  48. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-payments.module-DstLDYM7.mjs.map +1 -0
  49. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-promotions.module-DG03OY1q.mjs +94 -0
  50. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-promotions.module-DG03OY1q.mjs.map +1 -0
  51. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-queues.module-K-zYYVFy.mjs → isaiahiroko-tilmart-ngx-apps-admin-queues.module-D7iLwX0A.mjs} +6 -6
  52. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-queues.module-K-zYYVFy.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-queues.module-D7iLwX0A.mjs.map} +1 -1
  53. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-redirects.module-oQw5Xo5T.mjs +78 -0
  54. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-redirects.module-oQw5Xo5T.mjs.map +1 -0
  55. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-referrals.module-QLNhuh7q.mjs → isaiahiroko-tilmart-ngx-apps-admin-referrals.module-BIAY4L_u.mjs} +9 -34
  56. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-referrals.module-BIAY4L_u.mjs.map +1 -0
  57. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-reports.module-DBZov0We.mjs → isaiahiroko-tilmart-ngx-apps-admin-reports.module-DORiIVLQ.mjs} +5 -5
  58. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-reports.module-DBZov0We.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-reports.module-DORiIVLQ.mjs.map} +1 -1
  59. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-returns.module-C9Iu9CX6.mjs +163 -0
  60. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-returns.module-C9Iu9CX6.mjs.map +1 -0
  61. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-routes.module-CGBBHwId.mjs +81 -0
  62. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-routes.module-CGBBHwId.mjs.map +1 -0
  63. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-settings.module-Cz6xPNwB.mjs +318 -0
  64. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-settings.module-Cz6xPNwB.mjs.map +1 -0
  65. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-shipments.module-XuaOKr8v.mjs → isaiahiroko-tilmart-ngx-apps-admin-shipments.module-Cs5CLamm.mjs} +13 -32
  66. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-shipments.module-Cs5CLamm.mjs.map +1 -0
  67. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-simple-crud.base-C8SPw14H.mjs +140 -0
  68. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-simple-crud.base-C8SPw14H.mjs.map +1 -0
  69. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-stock.module-Bt9W1oGR.mjs +102 -0
  70. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-stock.module-Bt9W1oGR.mjs.map +1 -0
  71. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-trace.module-Pwr-82Rc.mjs → isaiahiroko-tilmart-ngx-apps-admin-trace.module-9sRlGZCC.mjs} +6 -6
  72. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-trace.module-Pwr-82Rc.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-trace.module-9sRlGZCC.mjs.map} +1 -1
  73. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-users.module-Bx_7fI2g.mjs → isaiahiroko-tilmart-ngx-apps-admin-users.module-C31RJJJ_.mjs} +9 -34
  74. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-users.module-C31RJJJ_.mjs.map +1 -0
  75. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin.mjs +96 -72
  76. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin.mjs.map +1 -1
  77. package/package.json +1 -1
  78. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-baskets.module-_lHPl1dT.mjs +0 -294
  79. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-baskets.module-_lHPl1dT.mjs.map +0 -1
  80. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-Bvx2tVOi.mjs +0 -224
  81. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-catalog.module-Bvx2tVOi.mjs.map +0 -1
  82. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-claims.module-Ccsd8Yx3.mjs +0 -106
  83. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-claims.module-Ccsd8Yx3.mjs.map +0 -1
  84. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-coupons.module-CQNCSlsd.mjs +0 -106
  85. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-coupons.module-CQNCSlsd.mjs.map +0 -1
  86. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-customers.module-12XdV9zo.mjs +0 -106
  87. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-customers.module-12XdV9zo.mjs.map +0 -1
  88. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-orders.module-Ddw49QW0.mjs.map +0 -1
  89. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-payments.module-BhqAtTZs.mjs +0 -106
  90. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-payments.module-BhqAtTZs.mjs.map +0 -1
  91. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-procurement.module-qXW-g0pf.mjs +0 -274
  92. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-procurement.module-qXW-g0pf.mjs.map +0 -1
  93. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-promotions.module-DG9uTDqX.mjs +0 -106
  94. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-promotions.module-DG9uTDqX.mjs.map +0 -1
  95. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-redirects.module-Hm2dO_bC.mjs +0 -106
  96. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-redirects.module-Hm2dO_bC.mjs.map +0 -1
  97. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-referrals.module-QLNhuh7q.mjs.map +0 -1
  98. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-returns.module-Bd2gdo6_.mjs +0 -106
  99. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-returns.module-Bd2gdo6_.mjs.map +0 -1
  100. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-routes.module-BkVY06ci.mjs +0 -105
  101. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-routes.module-BkVY06ci.mjs.map +0 -1
  102. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-settings.module-DKeZTldO.mjs +0 -222
  103. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-settings.module-DKeZTldO.mjs.map +0 -1
  104. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-shipments.module-XuaOKr8v.mjs.map +0 -1
  105. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-stock.module-DYiAkF7E.mjs +0 -107
  106. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-stock.module-DYiAkF7E.mjs.map +0 -1
  107. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-users.module-Bx_7fI2g.mjs.map +0 -1
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Component, NgModule } from '@angular/core';
3
- import * as i1$2 from '@angular/router';
3
+ import * as i1$1 from '@angular/router';
4
4
  import { RouterModule } from '@angular/router';
5
5
  import { BaseDirective, using, notify, SharedModule } from '@thescaffold/ngx-core';
6
- import * as i1$1 from '@thescaffold/ngx-ui';
6
+ import * as i2 from '@thescaffold/ngx-ui';
7
7
  import { ElementsModule } from '@thescaffold/ngx-ui';
8
8
  import { takeUntil, forkJoin, catchError, of, firstValueFrom } from 'rxjs';
9
9
  import * as i1 from '@angular/forms';
@@ -373,7 +373,7 @@ class HomepageComponent extends BaseDirective {
373
373
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
374
374
  }
375
375
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: HomepageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
376
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: HomepageComponent, isStandalone: false, selector: "x-homepage", usesInheritance: true, ngImport: i0, template: "<div class=\"x-hc-head\">\n <div>\n <div class=\"x-hc-title\">Homepage composer</div>\n <div class=\"x-hc-sub\">Drag to reorder the modules that build a storefront page.</div>\n </div>\n <div class=\"x-hc-head-controls\">\n <label class=\"x-hc-page-field\">\n Page\n <input\n type=\"text\"\n [ngModel]=\"page\"\n (ngModelChange)=\"changePage($event)\"\n placeholder=\"home\"\n />\n </label>\n <button\n type=\"button\"\n class=\"x-hc-btn\"\n [class.x-hc-btn-active]=\"previewMode\"\n (click)=\"previewMode = !previewMode\"\n >\n {{ previewMode ? 'Exit preview' : 'Preview' }}\n </button>\n </div>\n</div>\n\n@if (loading) {\n <x-element-loader></x-element-loader>\n} @else {\n @if (!previewMode) {\n <div class=\"x-hc-add\">\n <select [(ngModel)]=\"newType\">\n @for (t of types; track t.value) {\n <option [value]=\"t.value\">{{ t.label }}</option>\n }\n </select>\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"addModule()\">\n Add module\n </button>\n </div>\n }\n\n @if (!orderedModules.length) {\n <div class=\"x-hc-empty\">No modules on this page yet.</div>\n }\n\n @if (previewMode) {\n <div class=\"x-hc-preview\">\n @for (m of previewModules; track m.id) {\n <div class=\"x-hc-preview-block\">\n <span class=\"x-hc-preview-type\">{{ typeLabel(m.type) }}</span>\n <span class=\"x-hc-preview-title\">{{ m.title || previewLine(m) }}</span>\n </div>\n } @empty {\n <div class=\"x-hc-empty\">Nothing live on this page right now.</div>\n }\n </div>\n } @else {\n <div class=\"x-hc-list\">\n @for (m of orderedModules; track m.id; let i = $index) {\n <div\n class=\"x-hc-item\"\n [class.x-hc-item-off]=\"!m.enabled\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(i)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(i)\"\n >\n <div class=\"x-hc-item-main\">\n <span class=\"x-hc-grip\" title=\"Drag to reorder\">\u283F</span>\n <div class=\"x-hc-order\">\n <button type=\"button\" (click)=\"moveUp(i)\" [disabled]=\"i === 0\">\u25B2</button>\n <button type=\"button\" (click)=\"moveDown(i)\" [disabled]=\"i === orderedModules.length - 1\">\u25BC</button>\n </div>\n <div class=\"x-hc-item-body\">\n <div class=\"x-hc-item-row\">\n <span class=\"x-hc-type\">{{ typeLabel(m.type) }}</span>\n @if (m.title) {\n <span class=\"x-hc-item-title\">{{ m.title }}</span>\n }\n @if (scheduleLine(m)) {\n <span class=\"x-hc-sched\">{{ scheduleLine(m) }}</span>\n }\n </div>\n <div class=\"x-hc-item-preview\">{{ previewLine(m) }}</div>\n </div>\n <div class=\"x-hc-item-actions\">\n <button type=\"button\" class=\"x-hc-toggle\" (click)=\"toggleEnabled(m)\">\n {{ m.enabled ? 'On' : 'Off' }}\n </button>\n <button type=\"button\" class=\"x-hc-link\" (click)=\"editModule(m)\">Edit</button>\n <button type=\"button\" class=\"x-hc-link x-hc-danger\" (click)=\"removeModule(m)\">Delete</button>\n </div>\n </div>\n\n @if (editing?.id === m.id) {\n <div class=\"x-hc-edit\">\n <label class=\"x-hc-f\">\n Title\n <input type=\"text\" [(ngModel)]=\"editModel.title\" />\n </label>\n @for (field of typeDef(m.type)?.fields ?? []; track field.key) {\n <label class=\"x-hc-f\">\n {{ field.label }}\n @if (field.kind === 'text') {\n <textarea rows=\"3\" [(ngModel)]=\"editModel.config[field.key]\"></textarea>\n } @else {\n <input\n [type]=\"field.kind === 'num' ? 'number' : 'text'\"\n [(ngModel)]=\"editModel.config[field.key]\"\n />\n }\n </label>\n }\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Starts\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.startsAt\" />\n </label>\n <label class=\"x-hc-f\">\n Ends\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.endsAt\" />\n </label>\n </div>\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Channel IDs\n <input type=\"text\" [(ngModel)]=\"editModel.channelIds\" placeholder=\"blank = all\" />\n </label>\n <label class=\"x-hc-f\">\n Segment IDs\n <input type=\"text\" [(ngModel)]=\"editModel.segmentIds\" placeholder=\"blank = all\" />\n </label>\n </div>\n <div class=\"x-hc-edit-actions\">\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"saveEdit()\">Save</button>\n <button type=\"button\" class=\"x-hc-btn\" (click)=\"cancelEdit()\">Cancel</button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n\n<style>\n .x-hc-head {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n }\n .x-hc-title { font-size: 24px; font-weight: 800; color: var(--color-text); }\n .x-hc-sub { font-size: 13.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-head-controls { display: flex; gap: 10px; align-items: flex-end; }\n .x-hc-page-field {\n display: flex; flex-direction: column; gap: 4px;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.4px;\n }\n .x-hc-page-field input, .x-hc-add select, .x-hc-f input, .x-hc-f textarea {\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: 6px 10px;\n font-size: 13px;\n background: var(--color-surface);\n color: var(--color-text);\n }\n .x-hc-add { display: flex; gap: 10px; margin-bottom: 16px; }\n .x-hc-btn {\n border: 1px solid var(--color-border);\n background: transparent;\n border-radius: var(--radius-md);\n padding: 6px 14px;\n font-size: 12.5px;\n font-weight: 700;\n cursor: pointer;\n color: var(--color-text-muted);\n }\n .x-hc-btn-primary { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-btn-active { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-empty { font-size: 14px; color: var(--color-text-muted); }\n .x-hc-list { display: flex; flex-direction: column; gap: 10px; max-width: 860px; }\n .x-hc-item {\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n padding: 12px 14px;\n }\n .x-hc-item-off { opacity: 0.55; }\n .x-hc-item-main { display: flex; align-items: center; gap: 12px; }\n .x-hc-grip { cursor: grab; color: var(--color-text-muted); font-size: 16px; }\n .x-hc-order { display: flex; flex-direction: column; }\n .x-hc-order button {\n border: 0; background: transparent; cursor: pointer;\n color: var(--color-text-muted); font-size: 10px; line-height: 1.1; padding: 1px 3px;\n }\n .x-hc-order button:disabled { opacity: 0.3; cursor: default; }\n .x-hc-item-body { flex: 1; min-width: 0; }\n .x-hc-item-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }\n .x-hc-type {\n font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;\n font-size: 11px; color: var(--color-accent-hover);\n }\n .x-hc-item-title { font-size: 13.5px; font-weight: 600; color: var(--color-text); }\n .x-hc-sched { font-size: 11px; color: var(--color-text-muted); }\n .x-hc-item-preview { font-size: 12.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-item-actions { display: flex; gap: 8px; align-items: center; }\n .x-hc-toggle {\n border: 1px solid var(--color-border); border-radius: var(--radius-sm);\n background: transparent; padding: 3px 10px; font-size: 11.5px; font-weight: 700;\n cursor: pointer; color: var(--color-text-muted);\n }\n .x-hc-link {\n border: 0; background: transparent; cursor: pointer;\n font-size: 12px; font-weight: 700; color: var(--color-accent-hover);\n }\n .x-hc-danger { color: var(--color-danger, #c0362c); }\n .x-hc-edit {\n margin-top: 12px; padding-top: 12px;\n border-top: 1px solid var(--color-border);\n display: flex; flex-direction: column; gap: 10px;\n }\n .x-hc-f {\n display: flex; flex-direction: column; gap: 4px; flex: 1;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n }\n .x-hc-f-row { display: flex; gap: 10px; }\n .x-hc-edit-actions { display: flex; gap: 8px; }\n .x-hc-preview { display: flex; flex-direction: column; gap: 6px; max-width: 860px; }\n .x-hc-preview-block {\n border: 1px dashed var(--color-border-strong);\n border-radius: var(--radius-md);\n padding: 18px 16px;\n display: flex; flex-direction: column; gap: 4px;\n background: var(--color-surface);\n }\n .x-hc-preview-type {\n font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--color-accent-hover);\n }\n .x-hc-preview-title { font-size: 14px; color: var(--color-text); }\n</style>\n", styles: [".x-hc-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:20px;flex-wrap:wrap}.x-hc-title{font-size:24px;font-weight:800;color:var(--color-text)}.x-hc-sub{font-size:13.5px;color:var(--color-text-muted);margin-top:2px}.x-hc-head-controls{display:flex;gap:10px;align-items:flex-end}.x-hc-page-field{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700;text-transform:uppercase;letter-spacing:.4px}.x-hc-page-field input,.x-hc-add select,.x-hc-f input,.x-hc-f textarea{border:1px solid var(--color-border);border-radius:var(--radius-md);padding:6px 10px;font-size:13px;background:var(--color-surface);color:var(--color-text)}.x-hc-add{display:flex;gap:10px;margin-bottom:16px}.x-hc-btn{border:1px solid var(--color-border);background:transparent;border-radius:var(--radius-md);padding:6px 14px;font-size:12.5px;font-weight:700;cursor:pointer;color:var(--color-text-muted)}.x-hc-btn-primary,.x-hc-btn-active{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-hc-empty{font-size:14px;color:var(--color-text-muted)}.x-hc-list{display:flex;flex-direction:column;gap:10px;max-width:860px}.x-hc-item{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px 14px}.x-hc-item-off{opacity:.55}.x-hc-item-main{display:flex;align-items:center;gap:12px}.x-hc-grip{cursor:grab;color:var(--color-text-muted);font-size:16px}.x-hc-order{display:flex;flex-direction:column}.x-hc-order button{border:0;background:transparent;cursor:pointer;color:var(--color-text-muted);font-size:10px;line-height:1.1;padding:1px 3px}.x-hc-order button:disabled{opacity:.3;cursor:default}.x-hc-item-body{flex:1;min-width:0}.x-hc-item-row{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}.x-hc-type{font-weight:800;text-transform:uppercase;letter-spacing:.4px;font-size:11px;color:var(--color-accent-hover)}.x-hc-item-title{font-size:13.5px;font-weight:600;color:var(--color-text)}.x-hc-sched{font-size:11px;color:var(--color-text-muted)}.x-hc-item-preview{font-size:12.5px;color:var(--color-text-muted);margin-top:2px}.x-hc-item-actions{display:flex;gap:8px;align-items:center}.x-hc-toggle{border:1px solid var(--color-border);border-radius:var(--radius-sm);background:transparent;padding:3px 10px;font-size:11.5px;font-weight:700;cursor:pointer;color:var(--color-text-muted)}.x-hc-link{border:0;background:transparent;cursor:pointer;font-size:12px;font-weight:700;color:var(--color-accent-hover)}.x-hc-danger{color:var(--color-danger, #c0362c)}.x-hc-edit{margin-top:12px;padding-top:12px;border-top:1px solid var(--color-border);display:flex;flex-direction:column;gap:10px}.x-hc-f{display:flex;flex-direction:column;gap:4px;flex:1;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-hc-f-row{display:flex;gap:10px}.x-hc-edit-actions{display:flex;gap:8px}.x-hc-preview{display:flex;flex-direction:column;gap:6px;max-width:860px}.x-hc-preview-block{border:1px dashed var(--color-border-strong);border-radius:var(--radius-md);padding:18px 16px;display:flex;flex-direction:column;gap:4px;background:var(--color-surface)}.x-hc-preview-type{font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.5px;color:var(--color-accent-hover)}.x-hc-preview-title{font-size:14px;color:var(--color-text)}\n"], dependencies: [{ kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1$1.LoaderComponent, selector: "x-element-loader", inputs: ["data"] }] }); }
376
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: HomepageComponent, isStandalone: false, selector: "x-homepage", usesInheritance: true, ngImport: i0, template: "<div class=\"x-hc-head\">\n <div>\n <div class=\"x-hc-title\">Homepage composer</div>\n <div class=\"x-hc-sub\">Drag to reorder the modules that build a storefront page.</div>\n </div>\n <div class=\"x-hc-head-controls\">\n <label class=\"x-hc-page-field\">\n Page\n <input\n type=\"text\"\n [ngModel]=\"page\"\n (ngModelChange)=\"changePage($event)\"\n placeholder=\"home\"\n />\n </label>\n <button\n type=\"button\"\n class=\"x-hc-btn\"\n [class.x-hc-btn-active]=\"previewMode\"\n (click)=\"previewMode = !previewMode\"\n >\n {{ previewMode ? 'Exit preview' : 'Preview' }}\n </button>\n </div>\n</div>\n\n@if (loading) {\n <x-element-loader></x-element-loader>\n} @else {\n @if (!previewMode) {\n <div class=\"x-hc-add\">\n <select [(ngModel)]=\"newType\">\n @for (t of types; track t.value) {\n <option [value]=\"t.value\">{{ t.label }}</option>\n }\n </select>\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"addModule()\">\n Add module\n </button>\n </div>\n }\n\n @if (!orderedModules.length) {\n <div class=\"x-hc-empty\">No modules on this page yet.</div>\n }\n\n @if (previewMode) {\n <div class=\"x-hc-preview\">\n @for (m of previewModules; track m.id) {\n <div class=\"x-hc-preview-block\">\n <span class=\"x-hc-preview-type\">{{ typeLabel(m.type) }}</span>\n <span class=\"x-hc-preview-title\">{{ m.title || previewLine(m) }}</span>\n </div>\n } @empty {\n <div class=\"x-hc-empty\">Nothing live on this page right now.</div>\n }\n </div>\n } @else {\n <div class=\"x-hc-list\">\n @for (m of orderedModules; track m.id; let i = $index) {\n <div\n class=\"x-hc-item\"\n [class.x-hc-item-off]=\"!m.enabled\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(i)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(i)\"\n >\n <div class=\"x-hc-item-main\">\n <span class=\"x-hc-grip\" title=\"Drag to reorder\">\u283F</span>\n <div class=\"x-hc-order\">\n <button type=\"button\" (click)=\"moveUp(i)\" [disabled]=\"i === 0\">\u25B2</button>\n <button type=\"button\" (click)=\"moveDown(i)\" [disabled]=\"i === orderedModules.length - 1\">\u25BC</button>\n </div>\n <div class=\"x-hc-item-body\">\n <div class=\"x-hc-item-row\">\n <span class=\"x-hc-type\">{{ typeLabel(m.type) }}</span>\n @if (m.title) {\n <span class=\"x-hc-item-title\">{{ m.title }}</span>\n }\n @if (scheduleLine(m)) {\n <span class=\"x-hc-sched\">{{ scheduleLine(m) }}</span>\n }\n </div>\n <div class=\"x-hc-item-preview\">{{ previewLine(m) }}</div>\n </div>\n <div class=\"x-hc-item-actions\">\n <button type=\"button\" class=\"x-hc-toggle\" (click)=\"toggleEnabled(m)\">\n {{ m.enabled ? 'On' : 'Off' }}\n </button>\n <button type=\"button\" class=\"x-hc-link\" (click)=\"editModule(m)\">Edit</button>\n <button type=\"button\" class=\"x-hc-link x-hc-danger\" (click)=\"removeModule(m)\">Delete</button>\n </div>\n </div>\n\n @if (editing?.id === m.id) {\n <div class=\"x-hc-edit\">\n <label class=\"x-hc-f\">\n Title\n <input type=\"text\" [(ngModel)]=\"editModel.title\" />\n </label>\n @for (field of typeDef(m.type)?.fields ?? []; track field.key) {\n <label class=\"x-hc-f\">\n {{ field.label }}\n @if (field.kind === 'text') {\n <textarea rows=\"3\" [(ngModel)]=\"editModel.config[field.key]\"></textarea>\n } @else {\n <input\n [type]=\"field.kind === 'num' ? 'number' : 'text'\"\n [(ngModel)]=\"editModel.config[field.key]\"\n />\n }\n </label>\n }\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Starts\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.startsAt\" />\n </label>\n <label class=\"x-hc-f\">\n Ends\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.endsAt\" />\n </label>\n </div>\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Channel IDs\n <input type=\"text\" [(ngModel)]=\"editModel.channelIds\" placeholder=\"blank = all\" />\n </label>\n <label class=\"x-hc-f\">\n Segment IDs\n <input type=\"text\" [(ngModel)]=\"editModel.segmentIds\" placeholder=\"blank = all\" />\n </label>\n </div>\n <div class=\"x-hc-edit-actions\">\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"saveEdit()\">Save</button>\n <button type=\"button\" class=\"x-hc-btn\" (click)=\"cancelEdit()\">Cancel</button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n\n<style>\n .x-hc-head {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n }\n .x-hc-title { font-size: 24px; font-weight: 800; color: var(--color-text); }\n .x-hc-sub { font-size: 13.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-head-controls { display: flex; gap: 10px; align-items: flex-end; }\n .x-hc-page-field {\n display: flex; flex-direction: column; gap: 4px;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.4px;\n }\n .x-hc-page-field input, .x-hc-add select, .x-hc-f input, .x-hc-f textarea {\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: 6px 10px;\n font-size: 13px;\n background: var(--color-surface);\n color: var(--color-text);\n }\n .x-hc-add { display: flex; gap: 10px; margin-bottom: 16px; }\n .x-hc-btn {\n border: 1px solid var(--color-border);\n background: transparent;\n border-radius: var(--radius-md);\n padding: 6px 14px;\n font-size: 12.5px;\n font-weight: 700;\n cursor: pointer;\n color: var(--color-text-muted);\n }\n .x-hc-btn-primary { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-btn-active { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-empty { font-size: 14px; color: var(--color-text-muted); }\n .x-hc-list { display: flex; flex-direction: column; gap: 10px; max-width: 860px; }\n .x-hc-item {\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n padding: 12px 14px;\n }\n .x-hc-item-off { opacity: 0.55; }\n .x-hc-item-main { display: flex; align-items: center; gap: 12px; }\n .x-hc-grip { cursor: grab; color: var(--color-text-muted); font-size: 16px; }\n .x-hc-order { display: flex; flex-direction: column; }\n .x-hc-order button {\n border: 0; background: transparent; cursor: pointer;\n color: var(--color-text-muted); font-size: 10px; line-height: 1.1; padding: 1px 3px;\n }\n .x-hc-order button:disabled { opacity: 0.3; cursor: default; }\n .x-hc-item-body { flex: 1; min-width: 0; }\n .x-hc-item-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }\n .x-hc-type {\n font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;\n font-size: 11px; color: var(--color-accent-hover);\n }\n .x-hc-item-title { font-size: 13.5px; font-weight: 600; color: var(--color-text); }\n .x-hc-sched { font-size: 11px; color: var(--color-text-muted); }\n .x-hc-item-preview { font-size: 12.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-item-actions { display: flex; gap: 8px; align-items: center; }\n .x-hc-toggle {\n border: 1px solid var(--color-border); border-radius: var(--radius-sm);\n background: transparent; padding: 3px 10px; font-size: 11.5px; font-weight: 700;\n cursor: pointer; color: var(--color-text-muted);\n }\n .x-hc-link {\n border: 0; background: transparent; cursor: pointer;\n font-size: 12px; font-weight: 700; color: var(--color-accent-hover);\n }\n .x-hc-danger { color: var(--color-danger, #c0362c); }\n .x-hc-edit {\n margin-top: 12px; padding-top: 12px;\n border-top: 1px solid var(--color-border);\n display: flex; flex-direction: column; gap: 10px;\n }\n .x-hc-f {\n display: flex; flex-direction: column; gap: 4px; flex: 1;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n }\n .x-hc-f-row { display: flex; gap: 10px; }\n .x-hc-edit-actions { display: flex; gap: 8px; }\n .x-hc-preview { display: flex; flex-direction: column; gap: 6px; max-width: 860px; }\n .x-hc-preview-block {\n border: 1px dashed var(--color-border-strong);\n border-radius: var(--radius-md);\n padding: 18px 16px;\n display: flex; flex-direction: column; gap: 4px;\n background: var(--color-surface);\n }\n .x-hc-preview-type {\n font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--color-accent-hover);\n }\n .x-hc-preview-title { font-size: 14px; color: var(--color-text); }\n</style>\n", styles: [".x-hc-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:20px;flex-wrap:wrap}.x-hc-title{font-size:24px;font-weight:800;color:var(--color-text)}.x-hc-sub{font-size:13.5px;color:var(--color-text-muted);margin-top:2px}.x-hc-head-controls{display:flex;gap:10px;align-items:flex-end}.x-hc-page-field{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700;text-transform:uppercase;letter-spacing:.4px}.x-hc-page-field input,.x-hc-add select,.x-hc-f input,.x-hc-f textarea{border:1px solid var(--color-border);border-radius:var(--radius-md);padding:6px 10px;font-size:13px;background:var(--color-surface);color:var(--color-text)}.x-hc-add{display:flex;gap:10px;margin-bottom:16px}.x-hc-btn{border:1px solid var(--color-border);background:transparent;border-radius:var(--radius-md);padding:6px 14px;font-size:12.5px;font-weight:700;cursor:pointer;color:var(--color-text-muted)}.x-hc-btn-primary,.x-hc-btn-active{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-hc-empty{font-size:14px;color:var(--color-text-muted)}.x-hc-list{display:flex;flex-direction:column;gap:10px;max-width:860px}.x-hc-item{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px 14px}.x-hc-item-off{opacity:.55}.x-hc-item-main{display:flex;align-items:center;gap:12px}.x-hc-grip{cursor:grab;color:var(--color-text-muted);font-size:16px}.x-hc-order{display:flex;flex-direction:column}.x-hc-order button{border:0;background:transparent;cursor:pointer;color:var(--color-text-muted);font-size:10px;line-height:1.1;padding:1px 3px}.x-hc-order button:disabled{opacity:.3;cursor:default}.x-hc-item-body{flex:1;min-width:0}.x-hc-item-row{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}.x-hc-type{font-weight:800;text-transform:uppercase;letter-spacing:.4px;font-size:11px;color:var(--color-accent-hover)}.x-hc-item-title{font-size:13.5px;font-weight:600;color:var(--color-text)}.x-hc-sched{font-size:11px;color:var(--color-text-muted)}.x-hc-item-preview{font-size:12.5px;color:var(--color-text-muted);margin-top:2px}.x-hc-item-actions{display:flex;gap:8px;align-items:center}.x-hc-toggle{border:1px solid var(--color-border);border-radius:var(--radius-sm);background:transparent;padding:3px 10px;font-size:11.5px;font-weight:700;cursor:pointer;color:var(--color-text-muted)}.x-hc-link{border:0;background:transparent;cursor:pointer;font-size:12px;font-weight:700;color:var(--color-accent-hover)}.x-hc-danger{color:var(--color-danger, #c0362c)}.x-hc-edit{margin-top:12px;padding-top:12px;border-top:1px solid var(--color-border);display:flex;flex-direction:column;gap:10px}.x-hc-f{display:flex;flex-direction:column;gap:4px;flex:1;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-hc-f-row{display:flex;gap:10px}.x-hc-edit-actions{display:flex;gap:8px}.x-hc-preview{display:flex;flex-direction:column;gap:6px;max-width:860px}.x-hc-preview-block{border:1px dashed var(--color-border-strong);border-radius:var(--radius-md);padding:18px 16px;display:flex;flex-direction:column;gap:4px;background:var(--color-surface)}.x-hc-preview-type{font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.5px;color:var(--color-accent-hover)}.x-hc-preview-title{font-size:14px;color:var(--color-text)}\n"], dependencies: [{ kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.LoaderComponent, selector: "x-element-loader", inputs: ["data"] }] }); }
377
377
  }
378
378
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: HomepageComponent, decorators: [{
379
379
  type: Component,
@@ -383,7 +383,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
383
383
  class HomepageModule {
384
384
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: HomepageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
385
385
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.16", ngImport: i0, type: HomepageModule, declarations: [HomepageComponent], imports: [SharedModule,
386
- ElementsModule, i1$2.RouterModule] }); }
386
+ ElementsModule, i1$1.RouterModule] }); }
387
387
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: HomepageModule, imports: [SharedModule,
388
388
  ElementsModule,
389
389
  RouterModule.forChild([{ path: '', component: HomepageComponent }])] }); }
@@ -401,4 +401,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
401
401
  }] });
402
402
 
403
403
  export { HomepageModule };
404
- //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-homepage.module-BZ3UmxE3.mjs.map
404
+ //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-homepage.module-vtAoIwSu.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-homepage.module-BZ3UmxE3.mjs","sources":["../../../projects/admin/src/lib/pages/homepage/homepage.component.ts","../../../projects/admin/src/lib/pages/homepage/homepage.component.html","../../../projects/admin/src/lib/pages/homepage/homepage.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { BaseDirective, notify, using } from '@thescaffold/ngx-core';\nimport { catchError, firstValueFrom, forkJoin, of, takeUntil } from 'rxjs';\n\ninterface ModuleVm {\n id: string;\n page: string;\n type: string;\n title?: string;\n position: number;\n config: Record<string, any>;\n channelIds?: string[];\n segmentIds?: string[];\n startsAt?: string;\n endsAt?: string;\n enabled: boolean;\n}\n\ninterface TypeDef {\n value: string;\n label: string;\n // Config fields this type carries. `ids` = comma-separated id list,\n // `id` = single id, `num` = number, `text` = free text / html.\n fields: { key: string; label: string; kind: 'ids' | 'id' | 'num' | 'text' }[];\n}\n\n// P6.7, PROMO-06 / TRD §9.2 — the homepage composer. A drag-ordered list\n// of `MerchandisingModule` rows for a page, each with a type-aware config\n// editor, schedule and targeting, plus a resolved preview line (ids →\n// names) and a page-shape preview mode. The storefront renderer is P6.8.\nconst TYPES: TypeDef[] = [\n {\n value: 'hero_carousel',\n label: 'Hero carousel',\n fields: [{ key: 'bannerIds', label: 'Banner IDs', kind: 'ids' }],\n },\n {\n value: 'promo_banner',\n label: 'Promo banner',\n fields: [{ key: 'bannerIds', label: 'Banner IDs', kind: 'ids' }],\n },\n {\n value: 'product_rail',\n label: 'Product rail',\n fields: [\n { key: 'categoryId', label: 'From category ID', kind: 'id' },\n { key: 'productIds', label: 'Or explicit product IDs', kind: 'ids' },\n { key: 'limit', label: 'Max items', kind: 'num' },\n ],\n },\n {\n value: 'category_grid',\n label: 'Category grid',\n fields: [{ key: 'categoryIds', label: 'Category IDs', kind: 'ids' }],\n },\n {\n value: 'brand_strip',\n label: 'Brand strip',\n fields: [{ key: 'brandIds', label: 'Brand IDs', kind: 'ids' }],\n },\n {\n value: 'flash_sale_rail',\n label: 'Flash sale rail',\n fields: [{ key: 'flashSaleId', label: 'Flash sale ID (blank = all live)', kind: 'id' }],\n },\n {\n value: 'article_rail',\n label: 'Article rail',\n fields: [\n { key: 'articleIds', label: 'Article IDs', kind: 'ids' },\n { key: 'limit', label: 'Max items', kind: 'num' },\n ],\n },\n {\n value: 'rich_text',\n label: 'Rich text',\n fields: [{ key: 'html', label: 'HTML', kind: 'text' }],\n },\n { value: 'newsletter', label: 'Newsletter signup', fields: [] },\n { value: 'trust_bar', label: 'Trust bar', fields: [] },\n];\n\n@Component({\n standalone: false,\n selector: 'x-homepage',\n templateUrl: './homepage.component.html',\n})\nexport class HomepageComponent extends BaseDirective {\n private readonly source = this.apiService.on('apps/commerce/merchandising-module');\n\n readonly types = TYPES;\n\n page = 'home';\n loading = true;\n modules: ModuleVm[] = [];\n previewMode = false;\n\n newType = TYPES[0].value;\n\n editing?: ModuleVm;\n editModel: {\n title: string;\n startsAt: string;\n endsAt: string;\n channelIds: string;\n segmentIds: string;\n config: Record<string, string>;\n } = this.blankEditModel();\n\n private dragIndex: number | null = null;\n\n // id → name lookups for the preview line.\n private productName = new Map<string, string>();\n private categoryName = new Map<string, string>();\n private brandName = new Map<string, string>();\n private bannerName = new Map<string, string>();\n private flashSaleName = new Map<string, string>();\n\n override init = () => {\n this.loadLookups();\n this.load();\n };\n\n typeLabel(value: string): string {\n return TYPES.find((t) => t.value === value)?.label ?? value;\n }\n\n typeDef(value: string): TypeDef | undefined {\n return TYPES.find((t) => t.value === value);\n }\n\n get orderedModules(): ModuleVm[] {\n return [...this.modules].sort((a, b) => a.position - b.position);\n }\n\n get previewModules(): ModuleVm[] {\n const now = Date.now();\n return this.orderedModules.filter(\n (m) =>\n m.enabled &&\n (!m.startsAt || Date.parse(m.startsAt) <= now) &&\n (!m.endsAt || Date.parse(m.endsAt) >= now),\n );\n }\n\n load(): void {\n this.loading = true;\n this.source\n .getMany({ page: this.page, perPage: 200 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((res: any) => {\n this.modules = ((res?.data ?? []) as ModuleVm[])\n .filter((m) => m.page === this.page)\n .map((m) => ({ ...m, config: m.config ?? {} }))\n .sort((a, b) => a.position - b.position);\n this.loading = false;\n }),\n );\n }\n\n changePage(page: string): void {\n this.page = page.trim() || 'home';\n this.cancelEdit();\n this.load();\n }\n\n private loadLookups(): void {\n forkJoin({\n products: this.apiService\n .on('apps/commerce/product')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n categories: this.apiService\n .on('apps/commerce/category')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n brands: this.apiService\n .on('apps/commerce/brand')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n banners: this.apiService\n .on('apps/commerce/banner')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n flashSales: this.apiService\n .on('apps/commerce/flash-sale')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n })\n .pipe(takeUntil(this.$))\n .subscribe(\n using((res: any) => {\n for (const p of res?.products?.data ?? []) this.productName.set(p.id, p.name);\n for (const c of res?.categories?.data ?? []) this.categoryName.set(c.id, c.name);\n for (const b of res?.brands?.data ?? []) this.brandName.set(b.id, b.name);\n for (const b of res?.banners?.data ?? [])\n this.bannerName.set(b.id, b.title || b.slot || b.id);\n for (const f of res?.flashSales?.data ?? []) this.flashSaleName.set(f.id, f.name);\n }),\n );\n }\n\n previewLine(m: ModuleVm): string {\n const c: any = m.config ?? {};\n const names = (ids: any, map: Map<string, string>) =>\n (Array.isArray(ids) ? ids : [])\n .map((id: string) => map.get(id) ?? id)\n .filter(Boolean);\n\n switch (m.type) {\n case 'hero_carousel':\n case 'promo_banner': {\n const list = names(c.bannerIds, this.bannerName);\n return list.length ? `${list.length} banner(s): ${list.join(', ')}` : 'No banners set';\n }\n case 'product_rail': {\n if (c.categoryId) {\n const cat = this.categoryName.get(c.categoryId) ?? c.categoryId;\n return `Top ${c.limit || 12} from ${cat}`;\n }\n const list = names(c.productIds, this.productName);\n return list.length ? `${list.length} product(s): ${list.join(', ')}` : 'No products set';\n }\n case 'category_grid': {\n const list = names(c.categoryIds, this.categoryName);\n return list.length ? list.join(', ') : 'No categories set';\n }\n case 'brand_strip': {\n const list = names(c.brandIds, this.brandName);\n return list.length ? list.join(', ') : 'No brands set';\n }\n case 'flash_sale_rail':\n return c.flashSaleId\n ? this.flashSaleName.get(c.flashSaleId) ?? c.flashSaleId\n : 'All live flash sales';\n case 'article_rail': {\n const n = Array.isArray(c.articleIds) ? c.articleIds.length : 0;\n return n ? `${n} article(s)` : `Latest ${c.limit || 6} articles`;\n }\n case 'rich_text':\n return (c.html ? String(c.html).replace(/<[^>]+>/g, ' ').trim().slice(0, 80) : '') || 'Empty';\n default:\n return '—';\n }\n }\n\n scheduleLine(m: ModuleVm): string {\n if (!m.startsAt && !m.endsAt) return '';\n const fmt = (v?: string) => (v ? new Date(v).toLocaleDateString() : '…');\n return `${fmt(m.startsAt)} → ${fmt(m.endsAt)}`;\n }\n\n // ── ordering ──────────────────────────────────────────────────────\n\n onDragStart(index: number): void {\n this.dragIndex = index;\n }\n\n onDragOver(event: DragEvent): void {\n event.preventDefault();\n }\n\n onDrop(targetIndex: number): void {\n if (this.dragIndex === null || this.dragIndex === targetIndex) return;\n const ordered = this.orderedModules;\n const [moved] = ordered.splice(this.dragIndex, 1);\n ordered.splice(targetIndex, 0, moved);\n this.dragIndex = null;\n void this.persistOrder(ordered);\n }\n\n moveUp(index: number): void {\n if (index <= 0) return;\n const ordered = this.orderedModules;\n [ordered[index - 1], ordered[index]] = [ordered[index], ordered[index - 1]];\n void this.persistOrder(ordered);\n }\n\n moveDown(index: number): void {\n const ordered = this.orderedModules;\n if (index >= ordered.length - 1) return;\n [ordered[index + 1], ordered[index]] = [ordered[index], ordered[index + 1]];\n void this.persistOrder(ordered);\n }\n\n private async persistOrder(ordered: ModuleVm[]): Promise<void> {\n const changed: ModuleVm[] = [];\n ordered.forEach((m, i) => {\n if (m.position !== i) {\n m.position = i;\n changed.push(m);\n }\n });\n this.modules = ordered;\n try {\n await Promise.all(\n changed.map((m) =>\n firstValueFrom(this.source.update(m.id, { position: m.position } as any)),\n ),\n );\n } catch {\n notify('Could not save the new order.', undefined, 'error');\n this.load();\n }\n }\n\n // ── add / toggle / delete ─────────────────────────────────────────\n\n async addModule(): Promise<void> {\n try {\n await firstValueFrom(\n this.source.create({\n page: this.page,\n type: this.newType,\n position: this.modules.length,\n config: {},\n enabled: false,\n } as any),\n );\n notify('Module added.', undefined, 'success');\n this.load();\n } catch {\n notify('Could not add the module.', undefined, 'error');\n }\n }\n\n async toggleEnabled(m: ModuleVm): Promise<void> {\n const next = !m.enabled;\n try {\n await firstValueFrom(this.source.update(m.id, { enabled: next } as any));\n m.enabled = next;\n } catch {\n notify('Could not update the module.', undefined, 'error');\n }\n }\n\n async removeModule(m: ModuleVm): Promise<void> {\n try {\n await firstValueFrom(this.source.remove(m.id));\n this.modules = this.modules.filter((x) => x.id !== m.id);\n if (this.editing?.id === m.id) this.cancelEdit();\n notify('Module removed.', undefined, 'success');\n } catch {\n notify('Could not remove the module.', undefined, 'error');\n }\n }\n\n // ── edit ──────────────────────────────────────────────────────────\n\n editModule(m: ModuleVm): void {\n this.editing = m;\n const config: Record<string, string> = {};\n for (const field of this.typeDef(m.type)?.fields ?? []) {\n const value = (m.config ?? {})[field.key];\n config[field.key] = Array.isArray(value) ? value.join(', ') : value != null ? String(value) : '';\n }\n this.editModel = {\n title: m.title ?? '',\n startsAt: this.toLocalInput(m.startsAt),\n endsAt: this.toLocalInput(m.endsAt),\n channelIds: (m.channelIds ?? []).join(', '),\n segmentIds: (m.segmentIds ?? []).join(', '),\n config,\n };\n }\n\n cancelEdit(): void {\n this.editing = undefined;\n this.editModel = this.blankEditModel();\n }\n\n async saveEdit(): Promise<void> {\n if (!this.editing) return;\n const def = this.typeDef(this.editing.type);\n const config: Record<string, any> = { ...(this.editing.config ?? {}) };\n for (const field of def?.fields ?? []) {\n const raw = (this.editModel.config[field.key] ?? '').trim();\n if (field.kind === 'ids') {\n config[field.key] = raw ? raw.split(',').map((s) => s.trim()).filter(Boolean) : [];\n } else if (field.kind === 'num') {\n config[field.key] = raw ? Number(raw) : undefined;\n } else {\n config[field.key] = raw || undefined;\n }\n }\n const csv = (s: string) => s.split(',').map((x) => x.trim()).filter(Boolean);\n const body = {\n title: this.editModel.title.trim() || undefined,\n startsAt: this.editModel.startsAt ? new Date(this.editModel.startsAt).toISOString() : null,\n endsAt: this.editModel.endsAt ? new Date(this.editModel.endsAt).toISOString() : null,\n channelIds: csv(this.editModel.channelIds),\n segmentIds: csv(this.editModel.segmentIds),\n config,\n };\n try {\n await firstValueFrom(this.source.update(this.editing.id, body as any));\n Object.assign(this.editing, {\n title: body.title,\n startsAt: body.startsAt ?? undefined,\n endsAt: body.endsAt ?? undefined,\n channelIds: body.channelIds,\n segmentIds: body.segmentIds,\n config,\n });\n notify('Module saved.', undefined, 'success');\n this.cancelEdit();\n } catch {\n notify('Could not save the module.', undefined, 'error');\n }\n }\n\n private blankEditModel() {\n return {\n title: '',\n startsAt: '',\n endsAt: '',\n channelIds: '',\n segmentIds: '',\n config: {} as Record<string, string>,\n };\n }\n\n private toLocalInput(iso?: string): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n }\n}\n","<div class=\"x-hc-head\">\n <div>\n <div class=\"x-hc-title\">Homepage composer</div>\n <div class=\"x-hc-sub\">Drag to reorder the modules that build a storefront page.</div>\n </div>\n <div class=\"x-hc-head-controls\">\n <label class=\"x-hc-page-field\">\n Page\n <input\n type=\"text\"\n [ngModel]=\"page\"\n (ngModelChange)=\"changePage($event)\"\n placeholder=\"home\"\n />\n </label>\n <button\n type=\"button\"\n class=\"x-hc-btn\"\n [class.x-hc-btn-active]=\"previewMode\"\n (click)=\"previewMode = !previewMode\"\n >\n {{ previewMode ? 'Exit preview' : 'Preview' }}\n </button>\n </div>\n</div>\n\n@if (loading) {\n <x-element-loader></x-element-loader>\n} @else {\n @if (!previewMode) {\n <div class=\"x-hc-add\">\n <select [(ngModel)]=\"newType\">\n @for (t of types; track t.value) {\n <option [value]=\"t.value\">{{ t.label }}</option>\n }\n </select>\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"addModule()\">\n Add module\n </button>\n </div>\n }\n\n @if (!orderedModules.length) {\n <div class=\"x-hc-empty\">No modules on this page yet.</div>\n }\n\n @if (previewMode) {\n <div class=\"x-hc-preview\">\n @for (m of previewModules; track m.id) {\n <div class=\"x-hc-preview-block\">\n <span class=\"x-hc-preview-type\">{{ typeLabel(m.type) }}</span>\n <span class=\"x-hc-preview-title\">{{ m.title || previewLine(m) }}</span>\n </div>\n } @empty {\n <div class=\"x-hc-empty\">Nothing live on this page right now.</div>\n }\n </div>\n } @else {\n <div class=\"x-hc-list\">\n @for (m of orderedModules; track m.id; let i = $index) {\n <div\n class=\"x-hc-item\"\n [class.x-hc-item-off]=\"!m.enabled\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(i)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(i)\"\n >\n <div class=\"x-hc-item-main\">\n <span class=\"x-hc-grip\" title=\"Drag to reorder\">⠿</span>\n <div class=\"x-hc-order\">\n <button type=\"button\" (click)=\"moveUp(i)\" [disabled]=\"i === 0\">▲</button>\n <button type=\"button\" (click)=\"moveDown(i)\" [disabled]=\"i === orderedModules.length - 1\">▼</button>\n </div>\n <div class=\"x-hc-item-body\">\n <div class=\"x-hc-item-row\">\n <span class=\"x-hc-type\">{{ typeLabel(m.type) }}</span>\n @if (m.title) {\n <span class=\"x-hc-item-title\">{{ m.title }}</span>\n }\n @if (scheduleLine(m)) {\n <span class=\"x-hc-sched\">{{ scheduleLine(m) }}</span>\n }\n </div>\n <div class=\"x-hc-item-preview\">{{ previewLine(m) }}</div>\n </div>\n <div class=\"x-hc-item-actions\">\n <button type=\"button\" class=\"x-hc-toggle\" (click)=\"toggleEnabled(m)\">\n {{ m.enabled ? 'On' : 'Off' }}\n </button>\n <button type=\"button\" class=\"x-hc-link\" (click)=\"editModule(m)\">Edit</button>\n <button type=\"button\" class=\"x-hc-link x-hc-danger\" (click)=\"removeModule(m)\">Delete</button>\n </div>\n </div>\n\n @if (editing?.id === m.id) {\n <div class=\"x-hc-edit\">\n <label class=\"x-hc-f\">\n Title\n <input type=\"text\" [(ngModel)]=\"editModel.title\" />\n </label>\n @for (field of typeDef(m.type)?.fields ?? []; track field.key) {\n <label class=\"x-hc-f\">\n {{ field.label }}\n @if (field.kind === 'text') {\n <textarea rows=\"3\" [(ngModel)]=\"editModel.config[field.key]\"></textarea>\n } @else {\n <input\n [type]=\"field.kind === 'num' ? 'number' : 'text'\"\n [(ngModel)]=\"editModel.config[field.key]\"\n />\n }\n </label>\n }\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Starts\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.startsAt\" />\n </label>\n <label class=\"x-hc-f\">\n Ends\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.endsAt\" />\n </label>\n </div>\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Channel IDs\n <input type=\"text\" [(ngModel)]=\"editModel.channelIds\" placeholder=\"blank = all\" />\n </label>\n <label class=\"x-hc-f\">\n Segment IDs\n <input type=\"text\" [(ngModel)]=\"editModel.segmentIds\" placeholder=\"blank = all\" />\n </label>\n </div>\n <div class=\"x-hc-edit-actions\">\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"saveEdit()\">Save</button>\n <button type=\"button\" class=\"x-hc-btn\" (click)=\"cancelEdit()\">Cancel</button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n\n<style>\n .x-hc-head {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n }\n .x-hc-title { font-size: 24px; font-weight: 800; color: var(--color-text); }\n .x-hc-sub { font-size: 13.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-head-controls { display: flex; gap: 10px; align-items: flex-end; }\n .x-hc-page-field {\n display: flex; flex-direction: column; gap: 4px;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.4px;\n }\n .x-hc-page-field input, .x-hc-add select, .x-hc-f input, .x-hc-f textarea {\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: 6px 10px;\n font-size: 13px;\n background: var(--color-surface);\n color: var(--color-text);\n }\n .x-hc-add { display: flex; gap: 10px; margin-bottom: 16px; }\n .x-hc-btn {\n border: 1px solid var(--color-border);\n background: transparent;\n border-radius: var(--radius-md);\n padding: 6px 14px;\n font-size: 12.5px;\n font-weight: 700;\n cursor: pointer;\n color: var(--color-text-muted);\n }\n .x-hc-btn-primary { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-btn-active { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-empty { font-size: 14px; color: var(--color-text-muted); }\n .x-hc-list { display: flex; flex-direction: column; gap: 10px; max-width: 860px; }\n .x-hc-item {\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n padding: 12px 14px;\n }\n .x-hc-item-off { opacity: 0.55; }\n .x-hc-item-main { display: flex; align-items: center; gap: 12px; }\n .x-hc-grip { cursor: grab; color: var(--color-text-muted); font-size: 16px; }\n .x-hc-order { display: flex; flex-direction: column; }\n .x-hc-order button {\n border: 0; background: transparent; cursor: pointer;\n color: var(--color-text-muted); font-size: 10px; line-height: 1.1; padding: 1px 3px;\n }\n .x-hc-order button:disabled { opacity: 0.3; cursor: default; }\n .x-hc-item-body { flex: 1; min-width: 0; }\n .x-hc-item-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }\n .x-hc-type {\n font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;\n font-size: 11px; color: var(--color-accent-hover);\n }\n .x-hc-item-title { font-size: 13.5px; font-weight: 600; color: var(--color-text); }\n .x-hc-sched { font-size: 11px; color: var(--color-text-muted); }\n .x-hc-item-preview { font-size: 12.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-item-actions { display: flex; gap: 8px; align-items: center; }\n .x-hc-toggle {\n border: 1px solid var(--color-border); border-radius: var(--radius-sm);\n background: transparent; padding: 3px 10px; font-size: 11.5px; font-weight: 700;\n cursor: pointer; color: var(--color-text-muted);\n }\n .x-hc-link {\n border: 0; background: transparent; cursor: pointer;\n font-size: 12px; font-weight: 700; color: var(--color-accent-hover);\n }\n .x-hc-danger { color: var(--color-danger, #c0362c); }\n .x-hc-edit {\n margin-top: 12px; padding-top: 12px;\n border-top: 1px solid var(--color-border);\n display: flex; flex-direction: column; gap: 10px;\n }\n .x-hc-f {\n display: flex; flex-direction: column; gap: 4px; flex: 1;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n }\n .x-hc-f-row { display: flex; gap: 10px; }\n .x-hc-edit-actions { display: flex; gap: 8px; }\n .x-hc-preview { display: flex; flex-direction: column; gap: 6px; max-width: 860px; }\n .x-hc-preview-block {\n border: 1px dashed var(--color-border-strong);\n border-radius: var(--radius-md);\n padding: 18px 16px;\n display: flex; flex-direction: column; gap: 4px;\n background: var(--color-surface);\n }\n .x-hc-preview-type {\n font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--color-accent-hover);\n }\n .x-hc-preview-title { font-size: 14px; color: var(--color-text); }\n</style>\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule } from '@thescaffold/ngx-ui';\nimport { HomepageComponent } from './homepage.component';\n\n@NgModule({\n declarations: [HomepageComponent],\n imports: [\n SharedModule,\n ElementsModule,\n RouterModule.forChild([{ path: '', component: HomepageComponent }]),\n ],\n})\nexport class HomepageModule {}\n"],"names":["i2","i1"],"mappings":"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"}
1
+ {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-homepage.module-vtAoIwSu.mjs","sources":["../../../projects/admin/src/lib/pages/homepage/homepage.component.ts","../../../projects/admin/src/lib/pages/homepage/homepage.component.html","../../../projects/admin/src/lib/pages/homepage/homepage.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { BaseDirective, notify, using } from '@thescaffold/ngx-core';\nimport { catchError, firstValueFrom, forkJoin, of, takeUntil } from 'rxjs';\n\ninterface ModuleVm {\n id: string;\n page: string;\n type: string;\n title?: string;\n position: number;\n config: Record<string, any>;\n channelIds?: string[];\n segmentIds?: string[];\n startsAt?: string;\n endsAt?: string;\n enabled: boolean;\n}\n\ninterface TypeDef {\n value: string;\n label: string;\n // Config fields this type carries. `ids` = comma-separated id list,\n // `id` = single id, `num` = number, `text` = free text / html.\n fields: { key: string; label: string; kind: 'ids' | 'id' | 'num' | 'text' }[];\n}\n\n// P6.7, PROMO-06 / TRD §9.2 — the homepage composer. A drag-ordered list\n// of `MerchandisingModule` rows for a page, each with a type-aware config\n// editor, schedule and targeting, plus a resolved preview line (ids →\n// names) and a page-shape preview mode. The storefront renderer is P6.8.\nconst TYPES: TypeDef[] = [\n {\n value: 'hero_carousel',\n label: 'Hero carousel',\n fields: [{ key: 'bannerIds', label: 'Banner IDs', kind: 'ids' }],\n },\n {\n value: 'promo_banner',\n label: 'Promo banner',\n fields: [{ key: 'bannerIds', label: 'Banner IDs', kind: 'ids' }],\n },\n {\n value: 'product_rail',\n label: 'Product rail',\n fields: [\n { key: 'categoryId', label: 'From category ID', kind: 'id' },\n { key: 'productIds', label: 'Or explicit product IDs', kind: 'ids' },\n { key: 'limit', label: 'Max items', kind: 'num' },\n ],\n },\n {\n value: 'category_grid',\n label: 'Category grid',\n fields: [{ key: 'categoryIds', label: 'Category IDs', kind: 'ids' }],\n },\n {\n value: 'brand_strip',\n label: 'Brand strip',\n fields: [{ key: 'brandIds', label: 'Brand IDs', kind: 'ids' }],\n },\n {\n value: 'flash_sale_rail',\n label: 'Flash sale rail',\n fields: [{ key: 'flashSaleId', label: 'Flash sale ID (blank = all live)', kind: 'id' }],\n },\n {\n value: 'article_rail',\n label: 'Article rail',\n fields: [\n { key: 'articleIds', label: 'Article IDs', kind: 'ids' },\n { key: 'limit', label: 'Max items', kind: 'num' },\n ],\n },\n {\n value: 'rich_text',\n label: 'Rich text',\n fields: [{ key: 'html', label: 'HTML', kind: 'text' }],\n },\n { value: 'newsletter', label: 'Newsletter signup', fields: [] },\n { value: 'trust_bar', label: 'Trust bar', fields: [] },\n];\n\n@Component({\n standalone: false,\n selector: 'x-homepage',\n templateUrl: './homepage.component.html',\n})\nexport class HomepageComponent extends BaseDirective {\n private readonly source = this.apiService.on('apps/commerce/merchandising-module');\n\n readonly types = TYPES;\n\n page = 'home';\n loading = true;\n modules: ModuleVm[] = [];\n previewMode = false;\n\n newType = TYPES[0].value;\n\n editing?: ModuleVm;\n editModel: {\n title: string;\n startsAt: string;\n endsAt: string;\n channelIds: string;\n segmentIds: string;\n config: Record<string, string>;\n } = this.blankEditModel();\n\n private dragIndex: number | null = null;\n\n // id → name lookups for the preview line.\n private productName = new Map<string, string>();\n private categoryName = new Map<string, string>();\n private brandName = new Map<string, string>();\n private bannerName = new Map<string, string>();\n private flashSaleName = new Map<string, string>();\n\n override init = () => {\n this.loadLookups();\n this.load();\n };\n\n typeLabel(value: string): string {\n return TYPES.find((t) => t.value === value)?.label ?? value;\n }\n\n typeDef(value: string): TypeDef | undefined {\n return TYPES.find((t) => t.value === value);\n }\n\n get orderedModules(): ModuleVm[] {\n return [...this.modules].sort((a, b) => a.position - b.position);\n }\n\n get previewModules(): ModuleVm[] {\n const now = Date.now();\n return this.orderedModules.filter(\n (m) =>\n m.enabled &&\n (!m.startsAt || Date.parse(m.startsAt) <= now) &&\n (!m.endsAt || Date.parse(m.endsAt) >= now),\n );\n }\n\n load(): void {\n this.loading = true;\n this.source\n .getMany({ page: this.page, perPage: 200 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((res: any) => {\n this.modules = ((res?.data ?? []) as ModuleVm[])\n .filter((m) => m.page === this.page)\n .map((m) => ({ ...m, config: m.config ?? {} }))\n .sort((a, b) => a.position - b.position);\n this.loading = false;\n }),\n );\n }\n\n changePage(page: string): void {\n this.page = page.trim() || 'home';\n this.cancelEdit();\n this.load();\n }\n\n private loadLookups(): void {\n forkJoin({\n products: this.apiService\n .on('apps/commerce/product')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n categories: this.apiService\n .on('apps/commerce/category')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n brands: this.apiService\n .on('apps/commerce/brand')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n banners: this.apiService\n .on('apps/commerce/banner')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n flashSales: this.apiService\n .on('apps/commerce/flash-sale')\n .getMany({ perPage: 500 } as any)\n .pipe(catchError(() => of({ data: [] }))),\n })\n .pipe(takeUntil(this.$))\n .subscribe(\n using((res: any) => {\n for (const p of res?.products?.data ?? []) this.productName.set(p.id, p.name);\n for (const c of res?.categories?.data ?? []) this.categoryName.set(c.id, c.name);\n for (const b of res?.brands?.data ?? []) this.brandName.set(b.id, b.name);\n for (const b of res?.banners?.data ?? [])\n this.bannerName.set(b.id, b.title || b.slot || b.id);\n for (const f of res?.flashSales?.data ?? []) this.flashSaleName.set(f.id, f.name);\n }),\n );\n }\n\n previewLine(m: ModuleVm): string {\n const c: any = m.config ?? {};\n const names = (ids: any, map: Map<string, string>) =>\n (Array.isArray(ids) ? ids : [])\n .map((id: string) => map.get(id) ?? id)\n .filter(Boolean);\n\n switch (m.type) {\n case 'hero_carousel':\n case 'promo_banner': {\n const list = names(c.bannerIds, this.bannerName);\n return list.length ? `${list.length} banner(s): ${list.join(', ')}` : 'No banners set';\n }\n case 'product_rail': {\n if (c.categoryId) {\n const cat = this.categoryName.get(c.categoryId) ?? c.categoryId;\n return `Top ${c.limit || 12} from ${cat}`;\n }\n const list = names(c.productIds, this.productName);\n return list.length ? `${list.length} product(s): ${list.join(', ')}` : 'No products set';\n }\n case 'category_grid': {\n const list = names(c.categoryIds, this.categoryName);\n return list.length ? list.join(', ') : 'No categories set';\n }\n case 'brand_strip': {\n const list = names(c.brandIds, this.brandName);\n return list.length ? list.join(', ') : 'No brands set';\n }\n case 'flash_sale_rail':\n return c.flashSaleId\n ? this.flashSaleName.get(c.flashSaleId) ?? c.flashSaleId\n : 'All live flash sales';\n case 'article_rail': {\n const n = Array.isArray(c.articleIds) ? c.articleIds.length : 0;\n return n ? `${n} article(s)` : `Latest ${c.limit || 6} articles`;\n }\n case 'rich_text':\n return (c.html ? String(c.html).replace(/<[^>]+>/g, ' ').trim().slice(0, 80) : '') || 'Empty';\n default:\n return '—';\n }\n }\n\n scheduleLine(m: ModuleVm): string {\n if (!m.startsAt && !m.endsAt) return '';\n const fmt = (v?: string) => (v ? new Date(v).toLocaleDateString() : '…');\n return `${fmt(m.startsAt)} → ${fmt(m.endsAt)}`;\n }\n\n // ── ordering ──────────────────────────────────────────────────────\n\n onDragStart(index: number): void {\n this.dragIndex = index;\n }\n\n onDragOver(event: DragEvent): void {\n event.preventDefault();\n }\n\n onDrop(targetIndex: number): void {\n if (this.dragIndex === null || this.dragIndex === targetIndex) return;\n const ordered = this.orderedModules;\n const [moved] = ordered.splice(this.dragIndex, 1);\n ordered.splice(targetIndex, 0, moved);\n this.dragIndex = null;\n void this.persistOrder(ordered);\n }\n\n moveUp(index: number): void {\n if (index <= 0) return;\n const ordered = this.orderedModules;\n [ordered[index - 1], ordered[index]] = [ordered[index], ordered[index - 1]];\n void this.persistOrder(ordered);\n }\n\n moveDown(index: number): void {\n const ordered = this.orderedModules;\n if (index >= ordered.length - 1) return;\n [ordered[index + 1], ordered[index]] = [ordered[index], ordered[index + 1]];\n void this.persistOrder(ordered);\n }\n\n private async persistOrder(ordered: ModuleVm[]): Promise<void> {\n const changed: ModuleVm[] = [];\n ordered.forEach((m, i) => {\n if (m.position !== i) {\n m.position = i;\n changed.push(m);\n }\n });\n this.modules = ordered;\n try {\n await Promise.all(\n changed.map((m) =>\n firstValueFrom(this.source.update(m.id, { position: m.position } as any)),\n ),\n );\n } catch {\n notify('Could not save the new order.', undefined, 'error');\n this.load();\n }\n }\n\n // ── add / toggle / delete ─────────────────────────────────────────\n\n async addModule(): Promise<void> {\n try {\n await firstValueFrom(\n this.source.create({\n page: this.page,\n type: this.newType,\n position: this.modules.length,\n config: {},\n enabled: false,\n } as any),\n );\n notify('Module added.', undefined, 'success');\n this.load();\n } catch {\n notify('Could not add the module.', undefined, 'error');\n }\n }\n\n async toggleEnabled(m: ModuleVm): Promise<void> {\n const next = !m.enabled;\n try {\n await firstValueFrom(this.source.update(m.id, { enabled: next } as any));\n m.enabled = next;\n } catch {\n notify('Could not update the module.', undefined, 'error');\n }\n }\n\n async removeModule(m: ModuleVm): Promise<void> {\n try {\n await firstValueFrom(this.source.remove(m.id));\n this.modules = this.modules.filter((x) => x.id !== m.id);\n if (this.editing?.id === m.id) this.cancelEdit();\n notify('Module removed.', undefined, 'success');\n } catch {\n notify('Could not remove the module.', undefined, 'error');\n }\n }\n\n // ── edit ──────────────────────────────────────────────────────────\n\n editModule(m: ModuleVm): void {\n this.editing = m;\n const config: Record<string, string> = {};\n for (const field of this.typeDef(m.type)?.fields ?? []) {\n const value = (m.config ?? {})[field.key];\n config[field.key] = Array.isArray(value) ? value.join(', ') : value != null ? String(value) : '';\n }\n this.editModel = {\n title: m.title ?? '',\n startsAt: this.toLocalInput(m.startsAt),\n endsAt: this.toLocalInput(m.endsAt),\n channelIds: (m.channelIds ?? []).join(', '),\n segmentIds: (m.segmentIds ?? []).join(', '),\n config,\n };\n }\n\n cancelEdit(): void {\n this.editing = undefined;\n this.editModel = this.blankEditModel();\n }\n\n async saveEdit(): Promise<void> {\n if (!this.editing) return;\n const def = this.typeDef(this.editing.type);\n const config: Record<string, any> = { ...(this.editing.config ?? {}) };\n for (const field of def?.fields ?? []) {\n const raw = (this.editModel.config[field.key] ?? '').trim();\n if (field.kind === 'ids') {\n config[field.key] = raw ? raw.split(',').map((s) => s.trim()).filter(Boolean) : [];\n } else if (field.kind === 'num') {\n config[field.key] = raw ? Number(raw) : undefined;\n } else {\n config[field.key] = raw || undefined;\n }\n }\n const csv = (s: string) => s.split(',').map((x) => x.trim()).filter(Boolean);\n const body = {\n title: this.editModel.title.trim() || undefined,\n startsAt: this.editModel.startsAt ? new Date(this.editModel.startsAt).toISOString() : null,\n endsAt: this.editModel.endsAt ? new Date(this.editModel.endsAt).toISOString() : null,\n channelIds: csv(this.editModel.channelIds),\n segmentIds: csv(this.editModel.segmentIds),\n config,\n };\n try {\n await firstValueFrom(this.source.update(this.editing.id, body as any));\n Object.assign(this.editing, {\n title: body.title,\n startsAt: body.startsAt ?? undefined,\n endsAt: body.endsAt ?? undefined,\n channelIds: body.channelIds,\n segmentIds: body.segmentIds,\n config,\n });\n notify('Module saved.', undefined, 'success');\n this.cancelEdit();\n } catch {\n notify('Could not save the module.', undefined, 'error');\n }\n }\n\n private blankEditModel() {\n return {\n title: '',\n startsAt: '',\n endsAt: '',\n channelIds: '',\n segmentIds: '',\n config: {} as Record<string, string>,\n };\n }\n\n private toLocalInput(iso?: string): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n }\n}\n","<div class=\"x-hc-head\">\n <div>\n <div class=\"x-hc-title\">Homepage composer</div>\n <div class=\"x-hc-sub\">Drag to reorder the modules that build a storefront page.</div>\n </div>\n <div class=\"x-hc-head-controls\">\n <label class=\"x-hc-page-field\">\n Page\n <input\n type=\"text\"\n [ngModel]=\"page\"\n (ngModelChange)=\"changePage($event)\"\n placeholder=\"home\"\n />\n </label>\n <button\n type=\"button\"\n class=\"x-hc-btn\"\n [class.x-hc-btn-active]=\"previewMode\"\n (click)=\"previewMode = !previewMode\"\n >\n {{ previewMode ? 'Exit preview' : 'Preview' }}\n </button>\n </div>\n</div>\n\n@if (loading) {\n <x-element-loader></x-element-loader>\n} @else {\n @if (!previewMode) {\n <div class=\"x-hc-add\">\n <select [(ngModel)]=\"newType\">\n @for (t of types; track t.value) {\n <option [value]=\"t.value\">{{ t.label }}</option>\n }\n </select>\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"addModule()\">\n Add module\n </button>\n </div>\n }\n\n @if (!orderedModules.length) {\n <div class=\"x-hc-empty\">No modules on this page yet.</div>\n }\n\n @if (previewMode) {\n <div class=\"x-hc-preview\">\n @for (m of previewModules; track m.id) {\n <div class=\"x-hc-preview-block\">\n <span class=\"x-hc-preview-type\">{{ typeLabel(m.type) }}</span>\n <span class=\"x-hc-preview-title\">{{ m.title || previewLine(m) }}</span>\n </div>\n } @empty {\n <div class=\"x-hc-empty\">Nothing live on this page right now.</div>\n }\n </div>\n } @else {\n <div class=\"x-hc-list\">\n @for (m of orderedModules; track m.id; let i = $index) {\n <div\n class=\"x-hc-item\"\n [class.x-hc-item-off]=\"!m.enabled\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(i)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(i)\"\n >\n <div class=\"x-hc-item-main\">\n <span class=\"x-hc-grip\" title=\"Drag to reorder\">⠿</span>\n <div class=\"x-hc-order\">\n <button type=\"button\" (click)=\"moveUp(i)\" [disabled]=\"i === 0\">▲</button>\n <button type=\"button\" (click)=\"moveDown(i)\" [disabled]=\"i === orderedModules.length - 1\">▼</button>\n </div>\n <div class=\"x-hc-item-body\">\n <div class=\"x-hc-item-row\">\n <span class=\"x-hc-type\">{{ typeLabel(m.type) }}</span>\n @if (m.title) {\n <span class=\"x-hc-item-title\">{{ m.title }}</span>\n }\n @if (scheduleLine(m)) {\n <span class=\"x-hc-sched\">{{ scheduleLine(m) }}</span>\n }\n </div>\n <div class=\"x-hc-item-preview\">{{ previewLine(m) }}</div>\n </div>\n <div class=\"x-hc-item-actions\">\n <button type=\"button\" class=\"x-hc-toggle\" (click)=\"toggleEnabled(m)\">\n {{ m.enabled ? 'On' : 'Off' }}\n </button>\n <button type=\"button\" class=\"x-hc-link\" (click)=\"editModule(m)\">Edit</button>\n <button type=\"button\" class=\"x-hc-link x-hc-danger\" (click)=\"removeModule(m)\">Delete</button>\n </div>\n </div>\n\n @if (editing?.id === m.id) {\n <div class=\"x-hc-edit\">\n <label class=\"x-hc-f\">\n Title\n <input type=\"text\" [(ngModel)]=\"editModel.title\" />\n </label>\n @for (field of typeDef(m.type)?.fields ?? []; track field.key) {\n <label class=\"x-hc-f\">\n {{ field.label }}\n @if (field.kind === 'text') {\n <textarea rows=\"3\" [(ngModel)]=\"editModel.config[field.key]\"></textarea>\n } @else {\n <input\n [type]=\"field.kind === 'num' ? 'number' : 'text'\"\n [(ngModel)]=\"editModel.config[field.key]\"\n />\n }\n </label>\n }\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Starts\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.startsAt\" />\n </label>\n <label class=\"x-hc-f\">\n Ends\n <input type=\"datetime-local\" [(ngModel)]=\"editModel.endsAt\" />\n </label>\n </div>\n <div class=\"x-hc-f-row\">\n <label class=\"x-hc-f\">\n Channel IDs\n <input type=\"text\" [(ngModel)]=\"editModel.channelIds\" placeholder=\"blank = all\" />\n </label>\n <label class=\"x-hc-f\">\n Segment IDs\n <input type=\"text\" [(ngModel)]=\"editModel.segmentIds\" placeholder=\"blank = all\" />\n </label>\n </div>\n <div class=\"x-hc-edit-actions\">\n <button type=\"button\" class=\"x-hc-btn x-hc-btn-primary\" (click)=\"saveEdit()\">Save</button>\n <button type=\"button\" class=\"x-hc-btn\" (click)=\"cancelEdit()\">Cancel</button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n}\n\n<style>\n .x-hc-head {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n }\n .x-hc-title { font-size: 24px; font-weight: 800; color: var(--color-text); }\n .x-hc-sub { font-size: 13.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-head-controls { display: flex; gap: 10px; align-items: flex-end; }\n .x-hc-page-field {\n display: flex; flex-direction: column; gap: 4px;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n text-transform: uppercase; letter-spacing: 0.4px;\n }\n .x-hc-page-field input, .x-hc-add select, .x-hc-f input, .x-hc-f textarea {\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n padding: 6px 10px;\n font-size: 13px;\n background: var(--color-surface);\n color: var(--color-text);\n }\n .x-hc-add { display: flex; gap: 10px; margin-bottom: 16px; }\n .x-hc-btn {\n border: 1px solid var(--color-border);\n background: transparent;\n border-radius: var(--radius-md);\n padding: 6px 14px;\n font-size: 12.5px;\n font-weight: 700;\n cursor: pointer;\n color: var(--color-text-muted);\n }\n .x-hc-btn-primary { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-btn-active { border-color: var(--color-accent); color: var(--color-accent-hover); }\n .x-hc-empty { font-size: 14px; color: var(--color-text-muted); }\n .x-hc-list { display: flex; flex-direction: column; gap: 10px; max-width: 860px; }\n .x-hc-item {\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n padding: 12px 14px;\n }\n .x-hc-item-off { opacity: 0.55; }\n .x-hc-item-main { display: flex; align-items: center; gap: 12px; }\n .x-hc-grip { cursor: grab; color: var(--color-text-muted); font-size: 16px; }\n .x-hc-order { display: flex; flex-direction: column; }\n .x-hc-order button {\n border: 0; background: transparent; cursor: pointer;\n color: var(--color-text-muted); font-size: 10px; line-height: 1.1; padding: 1px 3px;\n }\n .x-hc-order button:disabled { opacity: 0.3; cursor: default; }\n .x-hc-item-body { flex: 1; min-width: 0; }\n .x-hc-item-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }\n .x-hc-type {\n font-weight: 800; text-transform: uppercase; letter-spacing: 0.4px;\n font-size: 11px; color: var(--color-accent-hover);\n }\n .x-hc-item-title { font-size: 13.5px; font-weight: 600; color: var(--color-text); }\n .x-hc-sched { font-size: 11px; color: var(--color-text-muted); }\n .x-hc-item-preview { font-size: 12.5px; color: var(--color-text-muted); margin-top: 2px; }\n .x-hc-item-actions { display: flex; gap: 8px; align-items: center; }\n .x-hc-toggle {\n border: 1px solid var(--color-border); border-radius: var(--radius-sm);\n background: transparent; padding: 3px 10px; font-size: 11.5px; font-weight: 700;\n cursor: pointer; color: var(--color-text-muted);\n }\n .x-hc-link {\n border: 0; background: transparent; cursor: pointer;\n font-size: 12px; font-weight: 700; color: var(--color-accent-hover);\n }\n .x-hc-danger { color: var(--color-danger, #c0362c); }\n .x-hc-edit {\n margin-top: 12px; padding-top: 12px;\n border-top: 1px solid var(--color-border);\n display: flex; flex-direction: column; gap: 10px;\n }\n .x-hc-f {\n display: flex; flex-direction: column; gap: 4px; flex: 1;\n font-size: 11.5px; color: var(--color-text-muted); font-weight: 700;\n }\n .x-hc-f-row { display: flex; gap: 10px; }\n .x-hc-edit-actions { display: flex; gap: 8px; }\n .x-hc-preview { display: flex; flex-direction: column; gap: 6px; max-width: 860px; }\n .x-hc-preview-block {\n border: 1px dashed var(--color-border-strong);\n border-radius: var(--radius-md);\n padding: 18px 16px;\n display: flex; flex-direction: column; gap: 4px;\n background: var(--color-surface);\n }\n .x-hc-preview-type {\n font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px;\n color: var(--color-accent-hover);\n }\n .x-hc-preview-title { font-size: 14px; color: var(--color-text); }\n</style>\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule } from '@thescaffold/ngx-ui';\nimport { HomepageComponent } from './homepage.component';\n\n@NgModule({\n declarations: [HomepageComponent],\n imports: [\n SharedModule,\n ElementsModule,\n RouterModule.forChild([{ path: '', component: HomepageComponent }]),\n ],\n})\nexport class HomepageModule {}\n"],"names":["i1"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Component, NgModule } from '@angular/core';
3
- import * as i1$3 from '@angular/router';
3
+ import * as i1$2 from '@angular/router';
4
4
  import { RouterModule } from '@angular/router';
5
5
  import * as i1 from '@thescaffold/ngx-core';
6
6
  import { BaseDirective, using, notify, SharedModule } from '@thescaffold/ngx-core';
7
- import * as i1$2 from '@thescaffold/ngx-ui';
7
+ import * as i2 from '@thescaffold/ngx-ui';
8
8
  import { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';
9
9
  import { takeUntil, firstValueFrom } from 'rxjs';
10
10
  import * as i1$1 from '@angular/forms';
11
- import * as i2 from '@angular/common';
11
+ import * as i3 from '@angular/common';
12
12
 
13
13
  const PRIORITIES = ['urgent', 'high', 'normal', 'low'];
14
14
  const STATUSES = ['open', 'in_progress', 'resolved', 'closed'];
@@ -256,7 +256,7 @@ class InboxComponent extends BaseDirective {
256
256
  }
257
257
  }
258
258
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: InboxComponent, deps: [{ token: i1.ControlService }], target: i0.ɵɵFactoryTarget.Component }); }
259
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: InboxComponent, isStandalone: false, selector: "x-inbox", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div>\n <div class=\"x-page-title\">Support inbox</div>\n <div class=\"x-page-subtitle\">\n Every contact channel in one queue \u2014 WhatsApp, phone, email, web form.\n </div>\n </div>\n <button type=\"button\" class=\"x-ib-new-btn\" (click)=\"newOpen = !newOpen\">\n {{ newOpen ? 'Cancel' : 'Log a ticket' }}\n </button>\n</div>\n\n@if (newOpen) {\n <form class=\"x-ib-new\" (ngSubmit)=\"createTicket()\">\n <div class=\"x-ib-new-row\">\n <select [(ngModel)]=\"draft.channel\" name=\"channel\">\n <option value=\"phone\">Phone</option>\n <option value=\"email\">Email</option>\n <option value=\"web\">Web form</option>\n <option value=\"walk_in\">Walk-in</option>\n </select>\n <input placeholder=\"Subject\" [(ngModel)]=\"draft.subject\" name=\"subject\" />\n <input placeholder=\"Contact phone\" [(ngModel)]=\"draft.contactPhone\" name=\"phone\" />\n <input placeholder=\"Contact email\" [(ngModel)]=\"draft.contactEmail\" name=\"email\" />\n </div>\n <textarea placeholder=\"What did the customer contact us about?\" rows=\"2\" [(ngModel)]=\"draft.note\" name=\"note\"></textarea>\n <button type=\"submit\" class=\"x-ib-new-btn\" [disabled]=\"!draft.note.trim()\">Log ticket</button>\n </form>\n}\n\n<nav class=\"x-ib-filters\">\n @for (f of filters; track f) {\n <button type=\"button\" class=\"x-ib-filter\" [class.is-active]=\"filter === f\" (click)=\"filter = f\">\n {{ f }}\n </button>\n }\n</nav>\n\n@if (loading) {\n <x-element-loader></x-element-loader>\n} @else {\n <div class=\"x-ib-layout\">\n <div class=\"x-ib-queue\">\n @for (t of queue; track t.id) {\n <button\n type=\"button\"\n class=\"x-ib-ticket\"\n [class.is-active]=\"selected?.id === t.id\"\n [class.is-breaching]=\"isBreaching(t)\"\n (click)=\"select(t)\"\n >\n <div class=\"x-ib-ticket-top\">\n <span class=\"x-ib-chan\">{{ channelLabel(t) }}</span>\n @if (t.priority) { <span class=\"x-ib-prio x-ib-prio-{{ t.priority }}\">{{ t.priority }}</span> }\n <span class=\"x-ib-sla\" [class.is-bad]=\"isBreaching(t)\">{{ slaLabel(t) }}</span>\n </div>\n <div class=\"x-ib-ticket-subject\">{{ t.subject || t.type }}</div>\n <div class=\"x-ib-ticket-note\">{{ t.note }}</div>\n <div class=\"x-ib-ticket-meta\">\n <span>{{ t.status.replace('_', ' ') }}</span>\n @if (t.assignedTo) { <span>\u00B7 {{ t.assignedTo }}</span> }\n </div>\n </button>\n } @empty {\n <div class=\"x-ib-empty\">Nothing in this view.</div>\n }\n </div>\n\n <div class=\"x-ib-detail\">\n @if (!selected) {\n <div class=\"x-ib-empty\">Select a ticket.</div>\n } @else {\n <div class=\"x-ib-d-head\">\n <div class=\"x-ib-d-title\">{{ selected.subject || selected.type }}</div>\n <div class=\"x-ib-d-sub\">\n {{ channelLabel(selected) }} \u00B7 opened {{ selected.createdAt | date: 'short' }}\n </div>\n </div>\n\n <!-- context -->\n <div class=\"x-ib-context\">\n @if (contextLoading) {\n <span class=\"x-ib-muted\">Loading context\u2026</span>\n } @else {\n <div class=\"x-ib-ctx-block\">\n <div class=\"x-ib-ctx-label\">Customer</div>\n @if (context.customer) {\n <div>{{ context.customer.name || '\u2014' }}</div>\n <div class=\"x-ib-muted\">{{ context.customer.email }} {{ context.customer.phone }}</div>\n } @else {\n <div class=\"x-ib-muted\">{{ selected.contactEmail || selected.contactPhone || 'Not linked' }}</div>\n }\n </div>\n @if (context.order) {\n <div class=\"x-ib-ctx-block\">\n <div class=\"x-ib-ctx-label\">Linked order</div>\n <div><strong>{{ context.order.orderNumber }}</strong> \u00B7 {{ context.order.status.replace('_', ' ') }}</div>\n <div class=\"x-ib-muted\">\n \u20A6{{ context.order.grandTotal | number: '1.0-0' }} \u00B7\n {{ context.order.lines.length }} line(s)\n </div>\n </div>\n }\n }\n </div>\n\n <!-- controls -->\n <div class=\"x-ib-controls\">\n <label>Priority\n <select [ngModel]=\"selected.priority || 'normal'\" (ngModelChange)=\"patch({ priority: $event })\">\n @for (p of priorities; track p) { <option [value]=\"p\">{{ p }}</option> }\n </select>\n </label>\n <label>Category\n <select [ngModel]=\"selected.category || ''\" (ngModelChange)=\"patch({ category: $event })\">\n <option value=\"\">\u2014</option>\n @for (c of categories; track c) { <option [value]=\"c\">{{ c }}</option> }\n </select>\n </label>\n <label>Status\n <select [ngModel]=\"selected.status\" (ngModelChange)=\"patch({ status: $event })\">\n @for (s of statuses; track s) { <option [value]=\"s\">{{ s.replace('_', ' ') }}</option> }\n </select>\n </label>\n @if (selected.assignedTo !== agent) {\n <button type=\"button\" class=\"x-ib-btn\" (click)=\"assignToMe()\">Assign to me</button>\n } @else {\n <span class=\"x-ib-muted\">Assigned to you</span>\n }\n </div>\n\n <!-- whatsapp thread -->\n @if (waThread.length) {\n <div class=\"x-ib-ctx-label\">WhatsApp thread</div>\n <div class=\"x-ib-wa\">\n @for (m of waThread; track m.id) {\n <div class=\"x-ib-wa-row\" [class.is-out]=\"m.direction === 'outbound'\">\n <div class=\"x-ib-wa-bubble\" [class.is-out]=\"m.direction === 'outbound'\">{{ m.text }}</div>\n </div>\n }\n </div>\n }\n\n <!-- reply + macros -->\n <div class=\"x-ib-ctx-label\">Reply</div>\n @if (macroList.length) {\n <div class=\"x-ib-macros\">\n @for (m of macroList; track m.id) {\n <button type=\"button\" class=\"x-ib-macro\" (click)=\"applyMacro(m)\">{{ m.title }}</button>\n }\n </div>\n }\n <textarea class=\"x-ib-reply\" rows=\"4\" [(ngModel)]=\"reply\" placeholder=\"Draft a reply (copy into WhatsApp / email), then mark it sent.\"></textarea>\n <div class=\"x-ib-reply-actions\">\n <button type=\"button\" class=\"x-ib-btn\" (click)=\"markReplied()\">Mark replied (stops SLA)</button>\n @if (selected.firstResponseAt) {\n <span class=\"x-ib-muted\">First response {{ selected.firstResponseAt | date: 'short' }}</span>\n }\n </div>\n\n <!-- internal notes -->\n <div class=\"x-ib-ctx-label\">Internal notes</div>\n <div class=\"x-ib-notes\">\n @for (n of selected.internalNotes || []; track n.at) {\n <div class=\"x-ib-note\">\n <div class=\"x-ib-muted\">{{ n.by || 'agent' }} \u00B7 {{ n.at | date: 'short' }}</div>\n <div>{{ n.text }}</div>\n </div>\n } @empty {\n <div class=\"x-ib-muted\">No notes yet.</div>\n }\n </div>\n <div class=\"x-ib-note-add\">\n <input [(ngModel)]=\"newNote\" placeholder=\"Add an internal note\u2026\" (keyup.enter)=\"addNote()\" />\n <button type=\"button\" class=\"x-ib-btn\" (click)=\"addNote()\">Add</button>\n </div>\n\n <!-- resolve -->\n <div class=\"x-ib-resolve\">\n <div class=\"x-ib-ctx-label\">Resolve</div>\n <div class=\"x-ib-resolve-codes\">\n @for (code of resolutionCodes; track code) {\n <button type=\"button\" class=\"x-ib-macro\" (click)=\"resolve(code)\">{{ code }}</button>\n }\n </div>\n @if (selected.resolutionCode) {\n <span class=\"x-ib-muted\">Resolved: {{ selected.resolutionCode }}</span>\n }\n </div>\n }\n </div>\n </div>\n}\n\n<style>\n .x-page-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; }\n .x-page-title { font-size: 24px; font-weight: 800; color: var(--color-text); }\n .x-page-subtitle { font-size: 13.5px; color: var(--color-text-muted); margin-top: 2px; }\n\n .x-ib-new-btn, .x-ib-btn { appearance: none; border: 1px solid var(--color-border); background: var(--color-surface, #fff); color: var(--color-text); border-radius: 8px; padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }\n .x-ib-new-btn:disabled { opacity: 0.5; }\n\n .x-ib-new { border: 1px solid var(--color-border); border-radius: 10px; padding: 14px; margin-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }\n .x-ib-new-row { display: flex; flex-wrap: wrap; gap: 8px; }\n .x-ib-new input, .x-ib-new select, .x-ib-new textarea { font: inherit; padding: 7px 10px; border: 1px solid var(--color-border); border-radius: 6px; background: var(--color-surface, #fff); color: var(--color-text); }\n .x-ib-new input { flex: 1; min-width: 130px; }\n\n .x-ib-filters { display: flex; gap: 4px; margin-bottom: 14px; border-bottom: 1px solid var(--color-border); }\n .x-ib-filter { appearance: none; background: transparent; border: 0; border-bottom: 2px solid transparent; padding: 7px 12px; font-size: 12.5px; font-weight: 600; text-transform: capitalize; color: var(--color-text-muted); cursor: pointer; }\n .x-ib-filter.is-active { color: var(--color-text); border-bottom-color: var(--color-brand); }\n\n .x-ib-layout { display: grid; grid-template-columns: 320px 1fr; gap: 16px; align-items: start; }\n @media (max-width: 820px) { .x-ib-layout { grid-template-columns: 1fr; } }\n\n .x-ib-queue { display: flex; flex-direction: column; gap: 6px; max-height: 70vh; overflow-y: auto; }\n .x-ib-ticket { text-align: left; appearance: none; border: 1px solid var(--color-border); border-radius: 10px; background: var(--color-surface, #fff); padding: 10px 12px; cursor: pointer; }\n .x-ib-ticket.is-active { border-color: var(--color-brand); }\n .x-ib-ticket.is-breaching { border-left: 3px solid var(--color-danger, #c0392b); }\n .x-ib-ticket-top { display: flex; gap: 6px; align-items: center; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-text-muted); margin-bottom: 4px; }\n .x-ib-prio { font-weight: 700; }\n .x-ib-prio-urgent, .x-ib-prio-high { color: var(--color-danger, #c0392b); }\n .x-ib-sla { margin-left: auto; }\n .x-ib-sla.is-bad { color: var(--color-danger, #c0392b); font-weight: 700; }\n .x-ib-ticket-subject { font-size: 13.5px; font-weight: 700; color: var(--color-text); }\n .x-ib-ticket-note { font-size: 12px; color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .x-ib-ticket-meta { font-size: 11px; color: var(--color-text-muted); margin-top: 3px; text-transform: capitalize; }\n\n .x-ib-detail { border: 1px solid var(--color-border); border-radius: 12px; padding: 16px; }\n .x-ib-d-title { font-size: 16px; font-weight: 800; color: var(--color-text); }\n .x-ib-d-sub { font-size: 12px; color: var(--color-text-muted); text-transform: capitalize; margin-bottom: 12px; }\n .x-ib-context { display: flex; flex-wrap: wrap; gap: 16px; padding: 10px; background: color-mix(in srgb, var(--color-border) 20%, transparent); border-radius: 8px; margin-bottom: 12px; font-size: 13px; }\n .x-ib-ctx-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; color: var(--color-text-muted); margin: 14px 0 6px; }\n .x-ib-muted { color: var(--color-text-muted); font-size: 12px; }\n\n .x-ib-controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; }\n .x-ib-controls label { display: flex; flex-direction: column; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-text-muted); gap: 3px; }\n .x-ib-controls select { font: inherit; padding: 5px 8px; border: 1px solid var(--color-border); border-radius: 6px; background: var(--color-surface, #fff); color: var(--color-text); text-transform: capitalize; }\n\n .x-ib-wa { display: flex; flex-direction: column; gap: 5px; max-height: 240px; overflow-y: auto; padding: 8px; border: 1px solid var(--color-border); border-radius: 8px; }\n .x-ib-wa-row { display: flex; }\n .x-ib-wa-row.is-out { justify-content: flex-end; }\n .x-ib-wa-bubble { max-width: 75%; font-size: 12.5px; padding: 6px 10px; border-radius: 10px; background: color-mix(in srgb, var(--color-border) 30%, transparent); }\n .x-ib-wa-bubble.is-out { background: var(--color-brand); color: #fff; }\n\n .x-ib-macros, .x-ib-resolve-codes { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }\n .x-ib-macro { appearance: none; border: 1px solid var(--color-border); background: transparent; color: var(--color-text-muted); border-radius: 999px; padding: 3px 10px; font-size: 11.5px; cursor: pointer; }\n .x-ib-reply, .x-ib-note-add input, .x-ib-new textarea { width: 100%; font: inherit; padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 6px; background: var(--color-surface, #fff); color: var(--color-text); box-sizing: border-box; }\n .x-ib-reply-actions { display: flex; gap: 10px; align-items: center; margin-top: 6px; }\n\n .x-ib-notes { display: flex; flex-direction: column; gap: 6px; }\n .x-ib-note { font-size: 13px; border-left: 2px solid var(--color-border); padding-left: 8px; }\n .x-ib-note-add { display: flex; gap: 8px; margin-top: 8px; }\n .x-ib-note-add input { flex: 1; }\n\n .x-ib-resolve { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--color-border); }\n .x-ib-empty { padding: 24px; text-align: center; font-size: 13px; color: var(--color-text-muted); }\n</style>\n", styles: [".x-page-head{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px}.x-page-title{font-size:24px;font-weight:800;color:var(--color-text)}.x-page-subtitle{font-size:13.5px;color:var(--color-text-muted);margin-top:2px}.x-ib-new-btn,.x-ib-btn{appearance:none;border:1px solid var(--color-border);background:var(--color-surface, #fff);color:var(--color-text);border-radius:8px;padding:6px 12px;font-size:12.5px;font-weight:600;cursor:pointer}.x-ib-new-btn:disabled{opacity:.5}.x-ib-new{border:1px solid var(--color-border);border-radius:10px;padding:14px;margin-bottom:16px;display:flex;flex-direction:column;gap:8px}.x-ib-new-row{display:flex;flex-wrap:wrap;gap:8px}.x-ib-new input,.x-ib-new select,.x-ib-new textarea{font:inherit;padding:7px 10px;border:1px solid var(--color-border);border-radius:6px;background:var(--color-surface, #fff);color:var(--color-text)}.x-ib-new input{flex:1;min-width:130px}.x-ib-filters{display:flex;gap:4px;margin-bottom:14px;border-bottom:1px solid var(--color-border)}.x-ib-filter{appearance:none;background:transparent;border:0;border-bottom:2px solid transparent;padding:7px 12px;font-size:12.5px;font-weight:600;text-transform:capitalize;color:var(--color-text-muted);cursor:pointer}.x-ib-filter.is-active{color:var(--color-text);border-bottom-color:var(--color-brand)}.x-ib-layout{display:grid;grid-template-columns:320px 1fr;gap:16px;align-items:start}@media(max-width:820px){.x-ib-layout{grid-template-columns:1fr}}.x-ib-queue{display:flex;flex-direction:column;gap:6px;max-height:70vh;overflow-y:auto}.x-ib-ticket{text-align:left;appearance:none;border:1px solid var(--color-border);border-radius:10px;background:var(--color-surface, #fff);padding:10px 12px;cursor:pointer}.x-ib-ticket.is-active{border-color:var(--color-brand)}.x-ib-ticket.is-breaching{border-left:3px solid var(--color-danger, #c0392b)}.x-ib-ticket-top{display:flex;gap:6px;align-items:center;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--color-text-muted);margin-bottom:4px}.x-ib-prio{font-weight:700}.x-ib-prio-urgent,.x-ib-prio-high{color:var(--color-danger, #c0392b)}.x-ib-sla{margin-left:auto}.x-ib-sla.is-bad{color:var(--color-danger, #c0392b);font-weight:700}.x-ib-ticket-subject{font-size:13.5px;font-weight:700;color:var(--color-text)}.x-ib-ticket-note{font-size:12px;color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.x-ib-ticket-meta{font-size:11px;color:var(--color-text-muted);margin-top:3px;text-transform:capitalize}.x-ib-detail{border:1px solid var(--color-border);border-radius:12px;padding:16px}.x-ib-d-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-ib-d-sub{font-size:12px;color:var(--color-text-muted);text-transform:capitalize;margin-bottom:12px}.x-ib-context{display:flex;flex-wrap:wrap;gap:16px;padding:10px;background:color-mix(in srgb,var(--color-border) 20%,transparent);border-radius:8px;margin-bottom:12px;font-size:13px}.x-ib-ctx-label{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;font-weight:700;color:var(--color-text-muted);margin:14px 0 6px}.x-ib-muted{color:var(--color-text-muted);font-size:12px}.x-ib-controls{display:flex;flex-wrap:wrap;gap:10px;align-items:end}.x-ib-controls label{display:flex;flex-direction:column;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--color-text-muted);gap:3px}.x-ib-controls select{font:inherit;padding:5px 8px;border:1px solid var(--color-border);border-radius:6px;background:var(--color-surface, #fff);color:var(--color-text);text-transform:capitalize}.x-ib-wa{display:flex;flex-direction:column;gap:5px;max-height:240px;overflow-y:auto;padding:8px;border:1px solid var(--color-border);border-radius:8px}.x-ib-wa-row{display:flex}.x-ib-wa-row.is-out{justify-content:flex-end}.x-ib-wa-bubble{max-width:75%;font-size:12.5px;padding:6px 10px;border-radius:10px;background:color-mix(in srgb,var(--color-border) 30%,transparent)}.x-ib-wa-bubble.is-out{background:var(--color-brand);color:#fff}.x-ib-macros,.x-ib-resolve-codes{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:8px}.x-ib-macro{appearance:none;border:1px solid var(--color-border);background:transparent;color:var(--color-text-muted);border-radius:999px;padding:3px 10px;font-size:11.5px;cursor:pointer}.x-ib-reply,.x-ib-note-add input,.x-ib-new textarea{width:100%;font:inherit;padding:8px 10px;border:1px solid var(--color-border);border-radius:6px;background:var(--color-surface, #fff);color:var(--color-text);box-sizing:border-box}.x-ib-reply-actions{display:flex;gap:10px;align-items:center;margin-top:6px}.x-ib-notes{display:flex;flex-direction:column;gap:6px}.x-ib-note{font-size:13px;border-left:2px solid var(--color-border);padding-left:8px}.x-ib-note-add{display:flex;gap:8px;margin-top:8px}.x-ib-note-add input{flex:1}.x-ib-resolve{margin-top:16px;padding-top:12px;border-top:1px solid var(--color-border)}.x-ib-empty{padding:24px;text-align:center;font-size:13px;color:var(--color-text-muted)}\n"], dependencies: [{ kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i1$2.LoaderComponent, selector: "x-element-loader", inputs: ["data"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
259
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: InboxComponent, isStandalone: false, selector: "x-inbox", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div>\n <div class=\"x-page-title\">Support inbox</div>\n <div class=\"x-page-subtitle\">\n Every contact channel in one queue \u2014 WhatsApp, phone, email, web form.\n </div>\n </div>\n <button type=\"button\" class=\"x-ib-new-btn\" (click)=\"newOpen = !newOpen\">\n {{ newOpen ? 'Cancel' : 'Log a ticket' }}\n </button>\n</div>\n\n@if (newOpen) {\n <form class=\"x-ib-new\" (ngSubmit)=\"createTicket()\">\n <div class=\"x-ib-new-row\">\n <select [(ngModel)]=\"draft.channel\" name=\"channel\">\n <option value=\"phone\">Phone</option>\n <option value=\"email\">Email</option>\n <option value=\"web\">Web form</option>\n <option value=\"walk_in\">Walk-in</option>\n </select>\n <input placeholder=\"Subject\" [(ngModel)]=\"draft.subject\" name=\"subject\" />\n <input placeholder=\"Contact phone\" [(ngModel)]=\"draft.contactPhone\" name=\"phone\" />\n <input placeholder=\"Contact email\" [(ngModel)]=\"draft.contactEmail\" name=\"email\" />\n </div>\n <textarea placeholder=\"What did the customer contact us about?\" rows=\"2\" [(ngModel)]=\"draft.note\" name=\"note\"></textarea>\n <button type=\"submit\" class=\"x-ib-new-btn\" [disabled]=\"!draft.note.trim()\">Log ticket</button>\n </form>\n}\n\n<nav class=\"x-ib-filters\">\n @for (f of filters; track f) {\n <button type=\"button\" class=\"x-ib-filter\" [class.is-active]=\"filter === f\" (click)=\"filter = f\">\n {{ f }}\n </button>\n }\n</nav>\n\n@if (loading) {\n <x-element-loader></x-element-loader>\n} @else {\n <div class=\"x-ib-layout\">\n <div class=\"x-ib-queue\">\n @for (t of queue; track t.id) {\n <button\n type=\"button\"\n class=\"x-ib-ticket\"\n [class.is-active]=\"selected?.id === t.id\"\n [class.is-breaching]=\"isBreaching(t)\"\n (click)=\"select(t)\"\n >\n <div class=\"x-ib-ticket-top\">\n <span class=\"x-ib-chan\">{{ channelLabel(t) }}</span>\n @if (t.priority) { <span class=\"x-ib-prio x-ib-prio-{{ t.priority }}\">{{ t.priority }}</span> }\n <span class=\"x-ib-sla\" [class.is-bad]=\"isBreaching(t)\">{{ slaLabel(t) }}</span>\n </div>\n <div class=\"x-ib-ticket-subject\">{{ t.subject || t.type }}</div>\n <div class=\"x-ib-ticket-note\">{{ t.note }}</div>\n <div class=\"x-ib-ticket-meta\">\n <span>{{ t.status.replace('_', ' ') }}</span>\n @if (t.assignedTo) { <span>\u00B7 {{ t.assignedTo }}</span> }\n </div>\n </button>\n } @empty {\n <div class=\"x-ib-empty\">Nothing in this view.</div>\n }\n </div>\n\n <div class=\"x-ib-detail\">\n @if (!selected) {\n <div class=\"x-ib-empty\">Select a ticket.</div>\n } @else {\n <div class=\"x-ib-d-head\">\n <div class=\"x-ib-d-title\">{{ selected.subject || selected.type }}</div>\n <div class=\"x-ib-d-sub\">\n {{ channelLabel(selected) }} \u00B7 opened {{ selected.createdAt | date: 'short' }}\n </div>\n </div>\n\n <!-- context -->\n <div class=\"x-ib-context\">\n @if (contextLoading) {\n <span class=\"x-ib-muted\">Loading context\u2026</span>\n } @else {\n <div class=\"x-ib-ctx-block\">\n <div class=\"x-ib-ctx-label\">Customer</div>\n @if (context.customer) {\n <div>{{ context.customer.name || '\u2014' }}</div>\n <div class=\"x-ib-muted\">{{ context.customer.email }} {{ context.customer.phone }}</div>\n } @else {\n <div class=\"x-ib-muted\">{{ selected.contactEmail || selected.contactPhone || 'Not linked' }}</div>\n }\n </div>\n @if (context.order) {\n <div class=\"x-ib-ctx-block\">\n <div class=\"x-ib-ctx-label\">Linked order</div>\n <div><strong>{{ context.order.orderNumber }}</strong> \u00B7 {{ context.order.status.replace('_', ' ') }}</div>\n <div class=\"x-ib-muted\">\n \u20A6{{ context.order.grandTotal | number: '1.0-0' }} \u00B7\n {{ context.order.lines.length }} line(s)\n </div>\n </div>\n }\n }\n </div>\n\n <!-- controls -->\n <div class=\"x-ib-controls\">\n <label>Priority\n <select [ngModel]=\"selected.priority || 'normal'\" (ngModelChange)=\"patch({ priority: $event })\">\n @for (p of priorities; track p) { <option [value]=\"p\">{{ p }}</option> }\n </select>\n </label>\n <label>Category\n <select [ngModel]=\"selected.category || ''\" (ngModelChange)=\"patch({ category: $event })\">\n <option value=\"\">\u2014</option>\n @for (c of categories; track c) { <option [value]=\"c\">{{ c }}</option> }\n </select>\n </label>\n <label>Status\n <select [ngModel]=\"selected.status\" (ngModelChange)=\"patch({ status: $event })\">\n @for (s of statuses; track s) { <option [value]=\"s\">{{ s.replace('_', ' ') }}</option> }\n </select>\n </label>\n @if (selected.assignedTo !== agent) {\n <button type=\"button\" class=\"x-ib-btn\" (click)=\"assignToMe()\">Assign to me</button>\n } @else {\n <span class=\"x-ib-muted\">Assigned to you</span>\n }\n </div>\n\n <!-- whatsapp thread -->\n @if (waThread.length) {\n <div class=\"x-ib-ctx-label\">WhatsApp thread</div>\n <div class=\"x-ib-wa\">\n @for (m of waThread; track m.id) {\n <div class=\"x-ib-wa-row\" [class.is-out]=\"m.direction === 'outbound'\">\n <div class=\"x-ib-wa-bubble\" [class.is-out]=\"m.direction === 'outbound'\">{{ m.text }}</div>\n </div>\n }\n </div>\n }\n\n <!-- reply + macros -->\n <div class=\"x-ib-ctx-label\">Reply</div>\n @if (macroList.length) {\n <div class=\"x-ib-macros\">\n @for (m of macroList; track m.id) {\n <button type=\"button\" class=\"x-ib-macro\" (click)=\"applyMacro(m)\">{{ m.title }}</button>\n }\n </div>\n }\n <textarea class=\"x-ib-reply\" rows=\"4\" [(ngModel)]=\"reply\" placeholder=\"Draft a reply (copy into WhatsApp / email), then mark it sent.\"></textarea>\n <div class=\"x-ib-reply-actions\">\n <button type=\"button\" class=\"x-ib-btn\" (click)=\"markReplied()\">Mark replied (stops SLA)</button>\n @if (selected.firstResponseAt) {\n <span class=\"x-ib-muted\">First response {{ selected.firstResponseAt | date: 'short' }}</span>\n }\n </div>\n\n <!-- internal notes -->\n <div class=\"x-ib-ctx-label\">Internal notes</div>\n <div class=\"x-ib-notes\">\n @for (n of selected.internalNotes || []; track n.at) {\n <div class=\"x-ib-note\">\n <div class=\"x-ib-muted\">{{ n.by || 'agent' }} \u00B7 {{ n.at | date: 'short' }}</div>\n <div>{{ n.text }}</div>\n </div>\n } @empty {\n <div class=\"x-ib-muted\">No notes yet.</div>\n }\n </div>\n <div class=\"x-ib-note-add\">\n <input [(ngModel)]=\"newNote\" placeholder=\"Add an internal note\u2026\" (keyup.enter)=\"addNote()\" />\n <button type=\"button\" class=\"x-ib-btn\" (click)=\"addNote()\">Add</button>\n </div>\n\n <!-- resolve -->\n <div class=\"x-ib-resolve\">\n <div class=\"x-ib-ctx-label\">Resolve</div>\n <div class=\"x-ib-resolve-codes\">\n @for (code of resolutionCodes; track code) {\n <button type=\"button\" class=\"x-ib-macro\" (click)=\"resolve(code)\">{{ code }}</button>\n }\n </div>\n @if (selected.resolutionCode) {\n <span class=\"x-ib-muted\">Resolved: {{ selected.resolutionCode }}</span>\n }\n </div>\n }\n </div>\n </div>\n}\n\n<style>\n .x-page-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; }\n .x-page-title { font-size: 24px; font-weight: 800; color: var(--color-text); }\n .x-page-subtitle { font-size: 13.5px; color: var(--color-text-muted); margin-top: 2px; }\n\n .x-ib-new-btn, .x-ib-btn { appearance: none; border: 1px solid var(--color-border); background: var(--color-surface, #fff); color: var(--color-text); border-radius: 8px; padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }\n .x-ib-new-btn:disabled { opacity: 0.5; }\n\n .x-ib-new { border: 1px solid var(--color-border); border-radius: 10px; padding: 14px; margin-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }\n .x-ib-new-row { display: flex; flex-wrap: wrap; gap: 8px; }\n .x-ib-new input, .x-ib-new select, .x-ib-new textarea { font: inherit; padding: 7px 10px; border: 1px solid var(--color-border); border-radius: 6px; background: var(--color-surface, #fff); color: var(--color-text); }\n .x-ib-new input { flex: 1; min-width: 130px; }\n\n .x-ib-filters { display: flex; gap: 4px; margin-bottom: 14px; border-bottom: 1px solid var(--color-border); }\n .x-ib-filter { appearance: none; background: transparent; border: 0; border-bottom: 2px solid transparent; padding: 7px 12px; font-size: 12.5px; font-weight: 600; text-transform: capitalize; color: var(--color-text-muted); cursor: pointer; }\n .x-ib-filter.is-active { color: var(--color-text); border-bottom-color: var(--color-brand); }\n\n .x-ib-layout { display: grid; grid-template-columns: 320px 1fr; gap: 16px; align-items: start; }\n @media (max-width: 820px) { .x-ib-layout { grid-template-columns: 1fr; } }\n\n .x-ib-queue { display: flex; flex-direction: column; gap: 6px; max-height: 70vh; overflow-y: auto; }\n .x-ib-ticket { text-align: left; appearance: none; border: 1px solid var(--color-border); border-radius: 10px; background: var(--color-surface, #fff); padding: 10px 12px; cursor: pointer; }\n .x-ib-ticket.is-active { border-color: var(--color-brand); }\n .x-ib-ticket.is-breaching { border-left: 3px solid var(--color-danger, #c0392b); }\n .x-ib-ticket-top { display: flex; gap: 6px; align-items: center; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-text-muted); margin-bottom: 4px; }\n .x-ib-prio { font-weight: 700; }\n .x-ib-prio-urgent, .x-ib-prio-high { color: var(--color-danger, #c0392b); }\n .x-ib-sla { margin-left: auto; }\n .x-ib-sla.is-bad { color: var(--color-danger, #c0392b); font-weight: 700; }\n .x-ib-ticket-subject { font-size: 13.5px; font-weight: 700; color: var(--color-text); }\n .x-ib-ticket-note { font-size: 12px; color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .x-ib-ticket-meta { font-size: 11px; color: var(--color-text-muted); margin-top: 3px; text-transform: capitalize; }\n\n .x-ib-detail { border: 1px solid var(--color-border); border-radius: 12px; padding: 16px; }\n .x-ib-d-title { font-size: 16px; font-weight: 800; color: var(--color-text); }\n .x-ib-d-sub { font-size: 12px; color: var(--color-text-muted); text-transform: capitalize; margin-bottom: 12px; }\n .x-ib-context { display: flex; flex-wrap: wrap; gap: 16px; padding: 10px; background: color-mix(in srgb, var(--color-border) 20%, transparent); border-radius: 8px; margin-bottom: 12px; font-size: 13px; }\n .x-ib-ctx-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; color: var(--color-text-muted); margin: 14px 0 6px; }\n .x-ib-muted { color: var(--color-text-muted); font-size: 12px; }\n\n .x-ib-controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; }\n .x-ib-controls label { display: flex; flex-direction: column; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-text-muted); gap: 3px; }\n .x-ib-controls select { font: inherit; padding: 5px 8px; border: 1px solid var(--color-border); border-radius: 6px; background: var(--color-surface, #fff); color: var(--color-text); text-transform: capitalize; }\n\n .x-ib-wa { display: flex; flex-direction: column; gap: 5px; max-height: 240px; overflow-y: auto; padding: 8px; border: 1px solid var(--color-border); border-radius: 8px; }\n .x-ib-wa-row { display: flex; }\n .x-ib-wa-row.is-out { justify-content: flex-end; }\n .x-ib-wa-bubble { max-width: 75%; font-size: 12.5px; padding: 6px 10px; border-radius: 10px; background: color-mix(in srgb, var(--color-border) 30%, transparent); }\n .x-ib-wa-bubble.is-out { background: var(--color-brand); color: #fff; }\n\n .x-ib-macros, .x-ib-resolve-codes { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }\n .x-ib-macro { appearance: none; border: 1px solid var(--color-border); background: transparent; color: var(--color-text-muted); border-radius: 999px; padding: 3px 10px; font-size: 11.5px; cursor: pointer; }\n .x-ib-reply, .x-ib-note-add input, .x-ib-new textarea { width: 100%; font: inherit; padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 6px; background: var(--color-surface, #fff); color: var(--color-text); box-sizing: border-box; }\n .x-ib-reply-actions { display: flex; gap: 10px; align-items: center; margin-top: 6px; }\n\n .x-ib-notes { display: flex; flex-direction: column; gap: 6px; }\n .x-ib-note { font-size: 13px; border-left: 2px solid var(--color-border); padding-left: 8px; }\n .x-ib-note-add { display: flex; gap: 8px; margin-top: 8px; }\n .x-ib-note-add input { flex: 1; }\n\n .x-ib-resolve { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--color-border); }\n .x-ib-empty { padding: 24px; text-align: center; font-size: 13px; color: var(--color-text-muted); }\n</style>\n", styles: [".x-page-head{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px}.x-page-title{font-size:24px;font-weight:800;color:var(--color-text)}.x-page-subtitle{font-size:13.5px;color:var(--color-text-muted);margin-top:2px}.x-ib-new-btn,.x-ib-btn{appearance:none;border:1px solid var(--color-border);background:var(--color-surface, #fff);color:var(--color-text);border-radius:8px;padding:6px 12px;font-size:12.5px;font-weight:600;cursor:pointer}.x-ib-new-btn:disabled{opacity:.5}.x-ib-new{border:1px solid var(--color-border);border-radius:10px;padding:14px;margin-bottom:16px;display:flex;flex-direction:column;gap:8px}.x-ib-new-row{display:flex;flex-wrap:wrap;gap:8px}.x-ib-new input,.x-ib-new select,.x-ib-new textarea{font:inherit;padding:7px 10px;border:1px solid var(--color-border);border-radius:6px;background:var(--color-surface, #fff);color:var(--color-text)}.x-ib-new input{flex:1;min-width:130px}.x-ib-filters{display:flex;gap:4px;margin-bottom:14px;border-bottom:1px solid var(--color-border)}.x-ib-filter{appearance:none;background:transparent;border:0;border-bottom:2px solid transparent;padding:7px 12px;font-size:12.5px;font-weight:600;text-transform:capitalize;color:var(--color-text-muted);cursor:pointer}.x-ib-filter.is-active{color:var(--color-text);border-bottom-color:var(--color-brand)}.x-ib-layout{display:grid;grid-template-columns:320px 1fr;gap:16px;align-items:start}@media(max-width:820px){.x-ib-layout{grid-template-columns:1fr}}.x-ib-queue{display:flex;flex-direction:column;gap:6px;max-height:70vh;overflow-y:auto}.x-ib-ticket{text-align:left;appearance:none;border:1px solid var(--color-border);border-radius:10px;background:var(--color-surface, #fff);padding:10px 12px;cursor:pointer}.x-ib-ticket.is-active{border-color:var(--color-brand)}.x-ib-ticket.is-breaching{border-left:3px solid var(--color-danger, #c0392b)}.x-ib-ticket-top{display:flex;gap:6px;align-items:center;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--color-text-muted);margin-bottom:4px}.x-ib-prio{font-weight:700}.x-ib-prio-urgent,.x-ib-prio-high{color:var(--color-danger, #c0392b)}.x-ib-sla{margin-left:auto}.x-ib-sla.is-bad{color:var(--color-danger, #c0392b);font-weight:700}.x-ib-ticket-subject{font-size:13.5px;font-weight:700;color:var(--color-text)}.x-ib-ticket-note{font-size:12px;color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.x-ib-ticket-meta{font-size:11px;color:var(--color-text-muted);margin-top:3px;text-transform:capitalize}.x-ib-detail{border:1px solid var(--color-border);border-radius:12px;padding:16px}.x-ib-d-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-ib-d-sub{font-size:12px;color:var(--color-text-muted);text-transform:capitalize;margin-bottom:12px}.x-ib-context{display:flex;flex-wrap:wrap;gap:16px;padding:10px;background:color-mix(in srgb,var(--color-border) 20%,transparent);border-radius:8px;margin-bottom:12px;font-size:13px}.x-ib-ctx-label{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;font-weight:700;color:var(--color-text-muted);margin:14px 0 6px}.x-ib-muted{color:var(--color-text-muted);font-size:12px}.x-ib-controls{display:flex;flex-wrap:wrap;gap:10px;align-items:end}.x-ib-controls label{display:flex;flex-direction:column;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--color-text-muted);gap:3px}.x-ib-controls select{font:inherit;padding:5px 8px;border:1px solid var(--color-border);border-radius:6px;background:var(--color-surface, #fff);color:var(--color-text);text-transform:capitalize}.x-ib-wa{display:flex;flex-direction:column;gap:5px;max-height:240px;overflow-y:auto;padding:8px;border:1px solid var(--color-border);border-radius:8px}.x-ib-wa-row{display:flex}.x-ib-wa-row.is-out{justify-content:flex-end}.x-ib-wa-bubble{max-width:75%;font-size:12.5px;padding:6px 10px;border-radius:10px;background:color-mix(in srgb,var(--color-border) 30%,transparent)}.x-ib-wa-bubble.is-out{background:var(--color-brand);color:#fff}.x-ib-macros,.x-ib-resolve-codes{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:8px}.x-ib-macro{appearance:none;border:1px solid var(--color-border);background:transparent;color:var(--color-text-muted);border-radius:999px;padding:3px 10px;font-size:11.5px;cursor:pointer}.x-ib-reply,.x-ib-note-add input,.x-ib-new textarea{width:100%;font:inherit;padding:8px 10px;border:1px solid var(--color-border);border-radius:6px;background:var(--color-surface, #fff);color:var(--color-text);box-sizing:border-box}.x-ib-reply-actions{display:flex;gap:10px;align-items:center;margin-top:6px}.x-ib-notes{display:flex;flex-direction:column;gap:6px}.x-ib-note{font-size:13px;border-left:2px solid var(--color-border);padding-left:8px}.x-ib-note-add{display:flex;gap:8px;margin-top:8px}.x-ib-note-add input{flex:1}.x-ib-resolve{margin-top:16px;padding-top:12px;border-top:1px solid var(--color-border)}.x-ib-empty{padding:24px;text-align:center;font-size:13px;color:var(--color-text-muted)}\n"], dependencies: [{ kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2.LoaderComponent, selector: "x-element-loader", inputs: ["data"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
260
260
  }
261
261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: InboxComponent, decorators: [{
262
262
  type: Component,
@@ -267,7 +267,7 @@ class InboxModule {
267
267
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: InboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
268
268
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.16", ngImport: i0, type: InboxModule, declarations: [InboxComponent], imports: [SharedModule,
269
269
  ElementsModule,
270
- WebgetsModule, i1$3.RouterModule] }); }
270
+ WebgetsModule, i1$2.RouterModule] }); }
271
271
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: InboxModule, imports: [SharedModule,
272
272
  ElementsModule,
273
273
  WebgetsModule,
@@ -287,4 +287,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
287
287
  }] });
288
288
 
289
289
  export { InboxModule };
290
- //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-inbox.module-BZDTa1L-.mjs.map
290
+ //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-inbox.module-CRkfjWQT.mjs.map