@isaiahiroko/tilmart-ngx-apps-admin 0.2.5 → 0.2.8

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 (27) hide show
  1. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-banners.module-KSapnx6Y.mjs → isaiahiroko-tilmart-ngx-apps-admin-banners.module-BPMlfHaC.mjs} +3 -3
  2. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-banners.module-KSapnx6Y.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-banners.module-BPMlfHaC.mjs.map} +1 -1
  3. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-brands.module-7I0ni-tQ.mjs → isaiahiroko-tilmart-ngx-apps-admin-brands.module-CSp0tWes.mjs} +3 -3
  4. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-brands.module-7I0ni-tQ.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-brands.module-CSp0tWes.mjs.map} +1 -1
  5. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-categories.module-OTUfenf0.mjs → isaiahiroko-tilmart-ngx-apps-admin-categories.module-uKkUREjb.mjs} +3 -3
  6. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-categories.module-OTUfenf0.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-categories.module-uKkUREjb.mjs.map} +1 -1
  7. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-coupons.module-CoRh6Hxq.mjs → isaiahiroko-tilmart-ngx-apps-admin-coupons.module-Dcu1nJBW.mjs} +3 -3
  8. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-coupons.module-CoRh6Hxq.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-coupons.module-Dcu1nJBW.mjs.map} +1 -1
  9. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-flash-sales.module-BPRnC17l.mjs → isaiahiroko-tilmart-ngx-apps-admin-flash-sales.module-DF7iSJaN.mjs} +3 -3
  10. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-flash-sales.module-BPRnC17l.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-flash-sales.module-DF7iSJaN.mjs.map} +1 -1
  11. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-profile.module-D-r3HcHq.mjs +139 -0
  12. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-profile.module-D-r3HcHq.mjs.map +1 -0
  13. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-promotions.module-DG03OY1q.mjs → isaiahiroko-tilmart-ngx-apps-admin-promotions.module-BO4zRytg.mjs} +3 -3
  14. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-promotions.module-DG03OY1q.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-promotions.module-BO4zRytg.mjs.map} +1 -1
  15. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-redirects.module-oQw5Xo5T.mjs → isaiahiroko-tilmart-ngx-apps-admin-redirects.module-D8H6ujoy.mjs} +3 -3
  16. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-redirects.module-oQw5Xo5T.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-redirects.module-D8H6ujoy.mjs.map} +1 -1
  17. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-routes.module-CGBBHwId.mjs → isaiahiroko-tilmart-ngx-apps-admin-routes.module-fYKd3AOq.mjs} +3 -3
  18. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-routes.module-CGBBHwId.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-routes.module-fYKd3AOq.mjs.map} +1 -1
  19. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-staff.module-BWhhEZcd.mjs → isaiahiroko-tilmart-ngx-apps-admin-staff.module-YjJJe00X.mjs} +3 -3
  20. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-staff.module-BWhhEZcd.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-staff.module-YjJJe00X.mjs.map} +1 -1
  21. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-stock.module-Bt9W1oGR.mjs → isaiahiroko-tilmart-ngx-apps-admin-stock.module-BSAe0CfZ.mjs} +3 -3
  22. package/fesm2022/{isaiahiroko-tilmart-ngx-apps-admin-stock.module-Bt9W1oGR.mjs.map → isaiahiroko-tilmart-ngx-apps-admin-stock.module-BSAe0CfZ.mjs.map} +1 -1
  23. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-tool-sessions.module-DBBy0bzj.mjs +119 -0
  24. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin-tool-sessions.module-DBBy0bzj.mjs.map +1 -0
  25. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin.mjs +40 -20
  26. package/fesm2022/isaiahiroko-tilmart-ngx-apps-admin.mjs.map +1 -1
  27. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-redirects.module-oQw5Xo5T.mjs","sources":["../../../projects/admin/src/lib/pages/redirects/redirects.component.ts","../../../projects/admin/src/lib/pages/_shared/simple-crud.component.html","../../../projects/admin/src/lib/pages/redirects/redirects.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { CrudFieldSpec, SimpleCrudDirective } from '../_shared/simple-crud.base';\n\n// R1 production-readiness pass — CMS-06. Auto-minted on a slug change;\n// was list-only otherwise, with no way for ops to add one manually to\n// fix a stray 404.\n@Component({\n standalone: false,\n selector: 'x-redirects',\n templateUrl: '../_shared/simple-crud.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class RedirectsComponent extends SimpleCrudDirective {\n protected pageTitle = 'Redirects';\n protected pageSubtitle = 'Stored 301/302 path redirects — auto-minted on slug changes (CMS-06), or add one by hand.';\n protected singularLabel = 'redirect';\n protected pluralName = 'redirects';\n protected dataSource = this.apiService.on('apps/commerce/redirect');\n\n protected columns = [\n { key: 'fromPath', value: 'From' },\n { key: 'toPath', value: 'To' },\n { key: 'statusCode', value: 'Code' },\n { key: 'hitCount', value: 'Hits' },\n ];\n\n protected fields: CrudFieldSpec[] = [\n { key: 'fromPath', label: 'From path', type: 'text', required: true, placeholder: '/p/old-slug' },\n { key: 'toPath', label: 'To path', type: 'text', required: true, placeholder: '/p/new-slug' },\n {\n key: 'statusCode',\n label: 'Status code',\n type: 'select',\n numericSelect: true,\n options: [\n { value: '301', label: '301 — Permanent' },\n { value: '302', label: '302 — Temporary' },\n ],\n },\n { key: 'reason', label: 'Reason', type: 'text' },\n { key: 'enabled', label: 'Enabled', type: 'boolean' },\n ];\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { RedirectsComponent } from './redirects.component';\n\n@NgModule({\n declarations: [RedirectsComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: RedirectsComponent }]),\n ],\n})\nexport class RedirectsModule {}\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-redirects.module-D8H6ujoy.mjs","sources":["../../../projects/admin/src/lib/pages/redirects/redirects.component.ts","../../../projects/admin/src/lib/pages/_shared/simple-crud.component.html","../../../projects/admin/src/lib/pages/redirects/redirects.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { CrudFieldSpec, SimpleCrudDirective } from '../_shared/simple-crud.base';\n\n// R1 production-readiness pass — CMS-06. Auto-minted on a slug change;\n// was list-only otherwise, with no way for ops to add one manually to\n// fix a stray 404.\n@Component({\n standalone: false,\n selector: 'x-redirects',\n templateUrl: '../_shared/simple-crud.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class RedirectsComponent extends SimpleCrudDirective {\n protected pageTitle = 'Redirects';\n protected pageSubtitle = 'Stored 301/302 path redirects — auto-minted on slug changes (CMS-06), or add one by hand.';\n protected singularLabel = 'redirect';\n protected pluralName = 'redirects';\n protected dataSource = this.apiService.on('apps/commerce/redirect');\n\n protected columns = [\n { key: 'fromPath', value: 'From' },\n { key: 'toPath', value: 'To' },\n { key: 'statusCode', value: 'Code' },\n { key: 'hitCount', value: 'Hits' },\n ];\n\n protected fields: CrudFieldSpec[] = [\n { key: 'fromPath', label: 'From path', type: 'text', required: true, placeholder: '/p/old-slug' },\n { key: 'toPath', label: 'To path', type: 'text', required: true, placeholder: '/p/new-slug' },\n {\n key: 'statusCode',\n label: 'Status code',\n type: 'select',\n numericSelect: true,\n options: [\n { value: '301', label: '301 — Permanent' },\n { value: '302', label: '302 — Temporary' },\n ],\n },\n { key: 'reason', label: 'Reason', type: 'text' },\n { key: 'enabled', label: 'Enabled', type: 'boolean' },\n ];\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { RedirectsComponent } from './redirects.component';\n\n@NgModule({\n declarations: [RedirectsComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: RedirectsComponent }]),\n ],\n})\nexport class RedirectsModule {}\n"],"names":["i1"],"mappings":";;;;;;;;;;;AAGA;AACA;AACA;AAOM,MAAO,kBAAmB,SAAQ,mBAAmB,CAAA;AAN3D,IAAA,WAAA,GAAA;;QAOY,IAAA,CAAA,SAAS,GAAG,WAAW;QACvB,IAAA,CAAA,YAAY,GAAG,2FAA2F;QAC1G,IAAA,CAAA,aAAa,GAAG,UAAU;QAC1B,IAAA,CAAA,UAAU,GAAG,WAAW;QACxB,IAAA,CAAA,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,wBAAwB,CAAC;AAEzD,QAAA,IAAA,CAAA,OAAO,GAAG;AAClB,YAAA,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;AAClC,YAAA,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;AAC9B,YAAA,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE;AACpC,YAAA,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;SACnC;AAES,QAAA,IAAA,CAAA,MAAM,GAAoB;AAClC,YAAA,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE;AACjG,YAAA,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE;AAC7F,YAAA;AACE,gBAAA,GAAG,EAAE,YAAY;AACjB,gBAAA,KAAK,EAAE,aAAa;AACpB,gBAAA,IAAI,EAAE,QAAQ;AACd,gBAAA,aAAa,EAAE,IAAI;AACnB,gBAAA,OAAO,EAAE;AACP,oBAAA,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE;AAC1C,oBAAA,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE;AAC3C,iBAAA;AACF,aAAA;YACD,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE;YAChD,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;SACtD;AACF,IAAA;+GA9BY,kBAAkB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,+FCZ/B,q3FAsEA,EAAA,MAAA,EAAA,CAAA,49DAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,6GAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,SAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FD1Da,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAN9B,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,UAAA,EAAA,KAAK,YACP,aAAa,EAAA,QAAA,EAAA,q3FAAA,EAAA,MAAA,EAAA,CAAA,49DAAA,CAAA,EAAA;;;MEOZ,eAAe,CAAA;+GAAf,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;gHAAf,eAAe,EAAA,YAAA,EAAA,CARX,kBAAkB,CAAA,EAAA,OAAA,EAAA,CAE/B,YAAY;YACZ,cAAc;YACd,aAAa,EAAAA,IAAA,CAAA,YAAA,CAAA,EAAA,CAAA,CAAA;AAIJ,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,YANxB,YAAY;YACZ,cAAc;YACd,aAAa;AACb,YAAA,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAA,EAAA,CAAA,CAAA;;4FAG3D,eAAe,EAAA,UAAA,EAAA,CAAA;kBAT3B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,YAAY,EAAE,CAAC,kBAAkB,CAAC;AAClC,oBAAA,OAAO,EAAE;wBACP,YAAY;wBACZ,cAAc;wBACd,aAAa;AACb,wBAAA,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;AACrE,qBAAA;AACF,iBAAA;;;;;"}
@@ -47,11 +47,11 @@ class RoutesComponent extends SimpleCrudDirective {
47
47
  ];
48
48
  }
49
49
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: RoutesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
50
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: RoutesComponent, isStandalone: false, selector: "x-routes", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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"] }, { kind: "component", type: i2.CollectionComponent, selector: "x-webget-collection", inputs: ["data"], outputs: ["search", "filter", "refresh", "select", "page", "show"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
50
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: RoutesComponent, isStandalone: false, selector: "x-routes", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-pwd{position:relative;display:flex}.x-scrud-pwd input{flex:1;padding-right:34px!important}.x-scrud-pwd-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:none;background:transparent;color:var(--color-text-muted);padding:4px 6px;cursor:pointer}.x-scrud-pwd-toggle:hover{color:var(--color-text)}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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"] }, { kind: "component", type: i2.CollectionComponent, selector: "x-webget-collection", inputs: ["data"], outputs: ["search", "filter", "refresh", "select", "page", "show"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
51
51
  }
52
52
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: RoutesComponent, decorators: [{
53
53
  type: Component,
54
- args: [{ standalone: false, selector: 'x-routes', template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"] }]
54
+ args: [{ standalone: false, selector: 'x-routes', template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-pwd{position:relative;display:flex}.x-scrud-pwd input{flex:1;padding-right:34px!important}.x-scrud-pwd-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:none;background:transparent;color:var(--color-text-muted);padding:4px 6px;cursor:pointer}.x-scrud-pwd-toggle:hover{color:var(--color-text)}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"] }]
55
55
  }] });
56
56
 
57
57
  class RoutesModule {
@@ -78,4 +78,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
78
78
  }] });
79
79
 
80
80
  export { RoutesModule };
81
- //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-routes.module-CGBBHwId.mjs.map
81
+ //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-routes.module-fYKd3AOq.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-routes.module-CGBBHwId.mjs","sources":["../../../projects/admin/src/lib/pages/routes/routes.component.ts","../../../projects/admin/src/lib/pages/_shared/simple-crud.component.html","../../../projects/admin/src/lib/pages/routes/routes.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { CrudFieldSpec, SimpleCrudDirective } from '../_shared/simple-crud.base';\n\n// R1 production-readiness pass. Route/cluster/day board (docs/TRD.md\n// §7): a simple list, not a routing-optimization engine — matches the\n// PRD's density model (which street/day, not turn-by-turn routing). Was\n// list-only; ops had no way to define a new route.\n@Component({\n standalone: false,\n selector: 'x-routes',\n templateUrl: '../_shared/simple-crud.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class RoutesComponent extends SimpleCrudDirective {\n protected pageTitle = 'Routes';\n protected pageSubtitle = 'Street/estate clusters, by delivery day.';\n protected singularLabel = 'route';\n protected pluralName = 'routes';\n protected dataSource = this.apiService.on('apps/commerce/route');\n\n protected columns = [\n { key: 'name', value: 'Name' },\n { key: 'dayOfWeek', value: 'Day', type: 'class', class: 'badge text-bg-light border' },\n { key: 'vanCapacityKg', value: 'Van capacity (kg)' },\n ];\n\n protected fields: CrudFieldSpec[] = [\n { key: 'name', label: 'Name', type: 'text', required: true },\n {\n key: 'dayOfWeek',\n label: 'Day of week',\n type: 'select',\n required: true,\n options: [\n { value: 'monday', label: 'Monday' },\n { value: 'tuesday', label: 'Tuesday' },\n { value: 'wednesday', label: 'Wednesday' },\n { value: 'thursday', label: 'Thursday' },\n { value: 'friday', label: 'Friday' },\n { value: 'saturday', label: 'Saturday' },\n { value: 'sunday', label: 'Sunday' },\n ],\n },\n { key: 'vanCapacityKg', label: 'Van capacity (kg)', type: 'number' },\n ];\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { RoutesComponent } from './routes.component';\n\n@NgModule({\n declarations: [RoutesComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: RoutesComponent }]),\n ],\n})\nexport class RoutesModule {}\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-routes.module-fYKd3AOq.mjs","sources":["../../../projects/admin/src/lib/pages/routes/routes.component.ts","../../../projects/admin/src/lib/pages/_shared/simple-crud.component.html","../../../projects/admin/src/lib/pages/routes/routes.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { CrudFieldSpec, SimpleCrudDirective } from '../_shared/simple-crud.base';\n\n// R1 production-readiness pass. Route/cluster/day board (docs/TRD.md\n// §7): a simple list, not a routing-optimization engine — matches the\n// PRD's density model (which street/day, not turn-by-turn routing). Was\n// list-only; ops had no way to define a new route.\n@Component({\n standalone: false,\n selector: 'x-routes',\n templateUrl: '../_shared/simple-crud.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class RoutesComponent extends SimpleCrudDirective {\n protected pageTitle = 'Routes';\n protected pageSubtitle = 'Street/estate clusters, by delivery day.';\n protected singularLabel = 'route';\n protected pluralName = 'routes';\n protected dataSource = this.apiService.on('apps/commerce/route');\n\n protected columns = [\n { key: 'name', value: 'Name' },\n { key: 'dayOfWeek', value: 'Day', type: 'class', class: 'badge text-bg-light border' },\n { key: 'vanCapacityKg', value: 'Van capacity (kg)' },\n ];\n\n protected fields: CrudFieldSpec[] = [\n { key: 'name', label: 'Name', type: 'text', required: true },\n {\n key: 'dayOfWeek',\n label: 'Day of week',\n type: 'select',\n required: true,\n options: [\n { value: 'monday', label: 'Monday' },\n { value: 'tuesday', label: 'Tuesday' },\n { value: 'wednesday', label: 'Wednesday' },\n { value: 'thursday', label: 'Thursday' },\n { value: 'friday', label: 'Friday' },\n { value: 'saturday', label: 'Saturday' },\n { value: 'sunday', label: 'Sunday' },\n ],\n },\n { key: 'vanCapacityKg', label: 'Van capacity (kg)', type: 'number' },\n ];\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { RoutesComponent } from './routes.component';\n\n@NgModule({\n declarations: [RoutesComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: RoutesComponent }]),\n ],\n})\nexport class RoutesModule {}\n"],"names":["i1"],"mappings":"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"}
@@ -151,11 +151,11 @@ class StaffComponent extends ListPageDirective {
151
151
  });
152
152
  }
153
153
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StaffComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
154
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StaffComponent, isStandalone: false, selector: "x-staff", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">Staff</div>\n <div class=\"x-page-subtitle\">\n Back-office accounts and the roles that decide what each can do in the admin console. Super administrators only.\n </div>\n</div>\n\n@if (created) {\n <div class=\"x-scrud-editor\" style=\"margin-bottom: 14px\">\n <div class=\"x-scrud-editor-title\">Account created for {{ created.ref }}</div>\n <div class=\"x-page-subtitle\">\n Temporary password (shown once \u2014 copy it now and share it securely):\n <code>{{ created.password }}</code>\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"created = null\">Dismiss</button>\n </div>\n </div>\n}\n\n@if (!mode) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New staff member</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">\n {{ mode === 'create' ? 'New staff member' : 'Roles for ' + draft.ref }}\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancel()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n @if (mode === 'create') {\n <div class=\"x-scrud-grid\">\n <label class=\"x-scrud-f\">\n First name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.firstName\" />\n </label>\n <label class=\"x-scrud-f\">\n Last name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.lastName\" />\n </label>\n <label class=\"x-scrud-f\">\n Email <span class=\"x-scrud-required\">*</span>\n <input type=\"email\" [(ngModel)]=\"draft.email\" autocomplete=\"off\" />\n </label>\n <label class=\"x-scrud-f\">\n Initial password\n <input type=\"text\" [(ngModel)]=\"draft.password\" placeholder=\"Leave blank to generate one\" autocomplete=\"off\" />\n </label>\n </div>\n }\n\n <div class=\"x-scrud-f\">\n Roles <span class=\"x-scrud-required\">*</span>\n @for (role of roles; track role.id) {\n <label style=\"display: flex; gap: 8px; align-items: flex-start; font-weight: 400; margin-top: 6px\">\n <input type=\"checkbox\" [checked]=\"hasRole(role.id)\" (change)=\"toggleRole(role.id)\" style=\"margin-top: 3px\" />\n <span>\n <strong>{{ roleTitle(role) }}</strong>\n @if (role.superAdmin) {\n <span class=\"badge text-bg-light border\" style=\"margin-left: 6px\">can manage staff</span>\n }\n <span style=\"display: block; font-size: 11.5px; color: var(--color-text-muted)\">\n {{ role.permissions.length }} permission{{ role.permissions.length === 1 ? '' : 's' }}\n </span>\n </span>\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"], dependencies: [{ 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.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"] }, { kind: "component", type: i2.CollectionComponent, selector: "x-webget-collection", inputs: ["data"], outputs: ["search", "filter", "refresh", "select", "page", "show"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
154
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StaffComponent, isStandalone: false, selector: "x-staff", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">Staff</div>\n <div class=\"x-page-subtitle\">\n Back-office accounts and the roles that decide what each can do in the admin console. Super administrators only.\n </div>\n</div>\n\n@if (created) {\n <div class=\"x-scrud-editor\" style=\"margin-bottom: 14px\">\n <div class=\"x-scrud-editor-title\">Account created for {{ created.ref }}</div>\n <div class=\"x-page-subtitle\">\n Temporary password (shown once \u2014 copy it now and share it securely):\n <code>{{ created.password }}</code>\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"created = null\">Dismiss</button>\n </div>\n </div>\n}\n\n@if (!mode) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New staff member</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">\n {{ mode === 'create' ? 'New staff member' : 'Roles for ' + draft.ref }}\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancel()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n @if (mode === 'create') {\n <div class=\"x-scrud-grid\">\n <label class=\"x-scrud-f\">\n First name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.firstName\" />\n </label>\n <label class=\"x-scrud-f\">\n Last name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.lastName\" />\n </label>\n <label class=\"x-scrud-f\">\n Email <span class=\"x-scrud-required\">*</span>\n <input type=\"email\" [(ngModel)]=\"draft.email\" autocomplete=\"off\" />\n </label>\n <label class=\"x-scrud-f\">\n Initial password\n <input type=\"text\" [(ngModel)]=\"draft.password\" placeholder=\"Leave blank to generate one\" autocomplete=\"off\" />\n </label>\n </div>\n }\n\n <div class=\"x-scrud-f\">\n Roles <span class=\"x-scrud-required\">*</span>\n @for (role of roles; track role.id) {\n <label style=\"display: flex; gap: 8px; align-items: flex-start; font-weight: 400; margin-top: 6px\">\n <input type=\"checkbox\" [checked]=\"hasRole(role.id)\" (change)=\"toggleRole(role.id)\" style=\"margin-top: 3px\" />\n <span>\n <strong>{{ roleTitle(role) }}</strong>\n @if (role.superAdmin) {\n <span class=\"badge text-bg-light border\" style=\"margin-left: 6px\">can manage staff</span>\n }\n <span style=\"display: block; font-size: 11.5px; color: var(--color-text-muted)\">\n {{ role.permissions.length }} permission{{ role.permissions.length === 1 ? '' : 's' }}\n </span>\n </span>\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-pwd{position:relative;display:flex}.x-scrud-pwd input{flex:1;padding-right:34px!important}.x-scrud-pwd-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:none;background:transparent;color:var(--color-text-muted);padding:4px 6px;cursor:pointer}.x-scrud-pwd-toggle:hover{color:var(--color-text)}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"], dependencies: [{ 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.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"] }, { kind: "component", type: i2.CollectionComponent, selector: "x-webget-collection", inputs: ["data"], outputs: ["search", "filter", "refresh", "select", "page", "show"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
155
155
  }
156
156
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StaffComponent, decorators: [{
157
157
  type: Component,
158
- args: [{ standalone: false, selector: 'x-staff', template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">Staff</div>\n <div class=\"x-page-subtitle\">\n Back-office accounts and the roles that decide what each can do in the admin console. Super administrators only.\n </div>\n</div>\n\n@if (created) {\n <div class=\"x-scrud-editor\" style=\"margin-bottom: 14px\">\n <div class=\"x-scrud-editor-title\">Account created for {{ created.ref }}</div>\n <div class=\"x-page-subtitle\">\n Temporary password (shown once \u2014 copy it now and share it securely):\n <code>{{ created.password }}</code>\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"created = null\">Dismiss</button>\n </div>\n </div>\n}\n\n@if (!mode) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New staff member</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">\n {{ mode === 'create' ? 'New staff member' : 'Roles for ' + draft.ref }}\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancel()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n @if (mode === 'create') {\n <div class=\"x-scrud-grid\">\n <label class=\"x-scrud-f\">\n First name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.firstName\" />\n </label>\n <label class=\"x-scrud-f\">\n Last name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.lastName\" />\n </label>\n <label class=\"x-scrud-f\">\n Email <span class=\"x-scrud-required\">*</span>\n <input type=\"email\" [(ngModel)]=\"draft.email\" autocomplete=\"off\" />\n </label>\n <label class=\"x-scrud-f\">\n Initial password\n <input type=\"text\" [(ngModel)]=\"draft.password\" placeholder=\"Leave blank to generate one\" autocomplete=\"off\" />\n </label>\n </div>\n }\n\n <div class=\"x-scrud-f\">\n Roles <span class=\"x-scrud-required\">*</span>\n @for (role of roles; track role.id) {\n <label style=\"display: flex; gap: 8px; align-items: flex-start; font-weight: 400; margin-top: 6px\">\n <input type=\"checkbox\" [checked]=\"hasRole(role.id)\" (change)=\"toggleRole(role.id)\" style=\"margin-top: 3px\" />\n <span>\n <strong>{{ roleTitle(role) }}</strong>\n @if (role.superAdmin) {\n <span class=\"badge text-bg-light border\" style=\"margin-left: 6px\">can manage staff</span>\n }\n <span style=\"display: block; font-size: 11.5px; color: var(--color-text-muted)\">\n {{ role.permissions.length }} permission{{ role.permissions.length === 1 ? '' : 's' }}\n </span>\n </span>\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"] }]
158
+ args: [{ standalone: false, selector: 'x-staff', template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">Staff</div>\n <div class=\"x-page-subtitle\">\n Back-office accounts and the roles that decide what each can do in the admin console. Super administrators only.\n </div>\n</div>\n\n@if (created) {\n <div class=\"x-scrud-editor\" style=\"margin-bottom: 14px\">\n <div class=\"x-scrud-editor-title\">Account created for {{ created.ref }}</div>\n <div class=\"x-page-subtitle\">\n Temporary password (shown once \u2014 copy it now and share it securely):\n <code>{{ created.password }}</code>\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"created = null\">Dismiss</button>\n </div>\n </div>\n}\n\n@if (!mode) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New staff member</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">\n {{ mode === 'create' ? 'New staff member' : 'Roles for ' + draft.ref }}\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancel()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n @if (mode === 'create') {\n <div class=\"x-scrud-grid\">\n <label class=\"x-scrud-f\">\n First name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.firstName\" />\n </label>\n <label class=\"x-scrud-f\">\n Last name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.lastName\" />\n </label>\n <label class=\"x-scrud-f\">\n Email <span class=\"x-scrud-required\">*</span>\n <input type=\"email\" [(ngModel)]=\"draft.email\" autocomplete=\"off\" />\n </label>\n <label class=\"x-scrud-f\">\n Initial password\n <input type=\"text\" [(ngModel)]=\"draft.password\" placeholder=\"Leave blank to generate one\" autocomplete=\"off\" />\n </label>\n </div>\n }\n\n <div class=\"x-scrud-f\">\n Roles <span class=\"x-scrud-required\">*</span>\n @for (role of roles; track role.id) {\n <label style=\"display: flex; gap: 8px; align-items: flex-start; font-weight: 400; margin-top: 6px\">\n <input type=\"checkbox\" [checked]=\"hasRole(role.id)\" (change)=\"toggleRole(role.id)\" style=\"margin-top: 3px\" />\n <span>\n <strong>{{ roleTitle(role) }}</strong>\n @if (role.superAdmin) {\n <span class=\"badge text-bg-light border\" style=\"margin-left: 6px\">can manage staff</span>\n }\n <span style=\"display: block; font-size: 11.5px; color: var(--color-text-muted)\">\n {{ role.permissions.length }} permission{{ role.permissions.length === 1 ? '' : 's' }}\n </span>\n </span>\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-pwd{position:relative;display:flex}.x-scrud-pwd input{flex:1;padding-right:34px!important}.x-scrud-pwd-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:none;background:transparent;color:var(--color-text-muted);padding:4px 6px;cursor:pointer}.x-scrud-pwd-toggle:hover{color:var(--color-text)}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"] }]
159
159
  }] });
160
160
 
161
161
  class StaffModule {
@@ -182,4 +182,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
182
182
  }] });
183
183
 
184
184
  export { StaffModule };
185
- //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-staff.module-BWhhEZcd.mjs.map
185
+ //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-staff.module-YjJJe00X.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-staff.module-BWhhEZcd.mjs","sources":["../../../projects/admin/src/lib/pages/staff/staff.component.ts","../../../projects/admin/src/lib/pages/staff/staff.component.html","../../../projects/admin/src/lib/pages/staff/staff.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { notify, using } from '@thescaffold/ngx-core';\nimport { takeUntil } from 'rxjs';\nimport { ListPageDirective } from '../_shared/list-page.base';\n\ninterface StaffRole {\n id: string;\n name: string;\n title: string;\n permissions: string[];\n superAdmin: boolean;\n}\n\n// Staff (admin dashboard accounts) — super admin only. Backed by\n// `apps/admin/staff` (libs/admin), which enforces the super-admin check\n// server-side; the nav entry and route are only a courtesy. Roles offered\n// here are the existing platform RoleTypes (support agent, catalogue\n// manager, order manager, finance manager, super administrator) — the\n// permission strings shown under each are the ones that role already\n// carries, not something this page defines.\n@Component({\n standalone: false,\n selector: 'x-staff',\n templateUrl: './staff.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class StaffComponent extends ListPageDirective {\n protected pluralName = 'staff';\n protected dataSource = this.apiService.on('apps/admin/staff');\n\n protected columns = [\n { key: 'name', value: 'Name' },\n { key: 'ref', value: 'Email' },\n { key: 'roleLabel', value: 'Roles' },\n { key: 'statusLabel', value: 'Status', type: 'class', class: 'badge text-bg-light border' },\n { key: 'createdAt', value: 'Added', type: 'date' },\n ];\n\n roles: StaffRole[] = [];\n mode: 'create' | 'roles' | null = null;\n saving = false;\n draft: { id?: string; ref?: string; email: string; firstName: string; lastName: string; password: string; roleTypeIds: string[] } | null = null;\n // Shown once after a create that generated the password server-side.\n created: { ref: string; password: string } | null = null;\n\n override init = () => {\n this.apiService\n .get('apps/admin/staff/roles')\n .pipe(takeUntil(this.$))\n .subscribe(using((res: any) => (this.roles = res?.data ?? [])));\n this.list();\n };\n\n protected override mapRow(row: any) {\n return {\n ...row,\n name: [row.firstName, row.lastName].filter(Boolean).join(' ') || '—',\n roleLabel: (row.roles ?? []).map((r: any) => this.roleTitle(r)).join(', '),\n statusLabel: row.suspended ? 'Suspended' : 'Active',\n };\n }\n\n protected override extraCollectionFields() {\n return {\n links: {\n secondary: [\n { title: 'Edit roles', fn: (_link: any, item: any) => this.editRoles(item) },\n {\n title: 'Suspend / reactivate',\n fn: (_link: any, item: any) => this.toggleSuspended(item),\n },\n ],\n },\n };\n }\n\n roleTitle(role: { name: string; title?: string }): string {\n if (role.name === 'global_admin') return 'Super administrator';\n if (role.title) return role.title;\n const words = role.name.replace(/_/g, ' ');\n return words.charAt(0).toUpperCase() + words.slice(1);\n }\n\n startCreate(): void {\n this.created = null;\n this.mode = 'create';\n this.draft = { email: '', firstName: '', lastName: '', password: '', roleTypeIds: [] };\n }\n\n editRoles(item: any): void {\n this.created = null;\n this.mode = 'roles';\n this.draft = {\n id: item.id,\n ref: item.ref,\n email: item.ref,\n firstName: item.firstName ?? '',\n lastName: item.lastName ?? '',\n password: '',\n roleTypeIds: (item.roles ?? []).map((r: any) => r.id),\n };\n }\n\n cancel(): void {\n this.mode = null;\n this.draft = null;\n }\n\n hasRole(id: string): boolean {\n return !!this.draft?.roleTypeIds.includes(id);\n }\n\n toggleRole(id: string): void {\n if (!this.draft) return;\n const ids = this.draft.roleTypeIds;\n this.draft.roleTypeIds = ids.includes(id) ? ids.filter((r) => r !== id) : [...ids, id];\n }\n\n save(): void {\n if (!this.draft || this.saving) return;\n const d = this.draft;\n if (!d.roleTypeIds.length) {\n notify('Assign at least one role.', undefined, 'error');\n return;\n }\n const request$ =\n this.mode === 'create'\n ? this.apiService.post('apps/admin/staff', {\n email: d.email,\n firstName: d.firstName,\n lastName: d.lastName,\n ...(d.password ? { password: d.password } : {}),\n roleTypeIds: d.roleTypeIds,\n })\n : this.apiService.patch(`apps/admin/staff/${d.id}/roles`, { roleTypeIds: d.roleTypeIds });\n\n this.saving = true;\n request$.pipe(takeUntil(this.$)).subscribe({\n next: (res: any) => {\n this.saving = false;\n if (this.mode === 'create' && res?.data?.temporaryPassword) {\n this.created = { ref: res.data.ref, password: res.data.temporaryPassword };\n }\n notify(this.mode === 'create' ? 'Staff account created.' : 'Roles updated.', undefined, 'success');\n this.cancel();\n this.list(this.page, this.perPage, this.query);\n },\n error: (err: any) => {\n this.saving = false;\n notify(err?.error?.message || 'Could not save.', undefined, 'error');\n },\n });\n }\n\n toggleSuspended(item: any): void {\n const action = item.suspended ? 'unsuspend' : 'suspend';\n this.apiService\n .patch(`apps/admin/staff/${item.id}/${action}`, {})\n .pipe(takeUntil(this.$))\n .subscribe({\n next: () => {\n notify(item.suspended ? 'Account reactivated.' : 'Account suspended.', undefined, 'success');\n this.list(this.page, this.perPage, this.query);\n },\n error: (err: any) => notify(err?.error?.message || 'Could not update the account.', undefined, 'error'),\n });\n }\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">Staff</div>\n <div class=\"x-page-subtitle\">\n Back-office accounts and the roles that decide what each can do in the admin console. Super administrators only.\n </div>\n</div>\n\n@if (created) {\n <div class=\"x-scrud-editor\" style=\"margin-bottom: 14px\">\n <div class=\"x-scrud-editor-title\">Account created for {{ created.ref }}</div>\n <div class=\"x-page-subtitle\">\n Temporary password (shown once — copy it now and share it securely):\n <code>{{ created.password }}</code>\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"created = null\">Dismiss</button>\n </div>\n </div>\n}\n\n@if (!mode) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New staff member</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">\n {{ mode === 'create' ? 'New staff member' : 'Roles for ' + draft.ref }}\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancel()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n @if (mode === 'create') {\n <div class=\"x-scrud-grid\">\n <label class=\"x-scrud-f\">\n First name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.firstName\" />\n </label>\n <label class=\"x-scrud-f\">\n Last name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.lastName\" />\n </label>\n <label class=\"x-scrud-f\">\n Email <span class=\"x-scrud-required\">*</span>\n <input type=\"email\" [(ngModel)]=\"draft.email\" autocomplete=\"off\" />\n </label>\n <label class=\"x-scrud-f\">\n Initial password\n <input type=\"text\" [(ngModel)]=\"draft.password\" placeholder=\"Leave blank to generate one\" autocomplete=\"off\" />\n </label>\n </div>\n }\n\n <div class=\"x-scrud-f\">\n Roles <span class=\"x-scrud-required\">*</span>\n @for (role of roles; track role.id) {\n <label style=\"display: flex; gap: 8px; align-items: flex-start; font-weight: 400; margin-top: 6px\">\n <input type=\"checkbox\" [checked]=\"hasRole(role.id)\" (change)=\"toggleRole(role.id)\" style=\"margin-top: 3px\" />\n <span>\n <strong>{{ roleTitle(role) }}</strong>\n @if (role.superAdmin) {\n <span class=\"badge text-bg-light border\" style=\"margin-left: 6px\">can manage staff</span>\n }\n <span style=\"display: block; font-size: 11.5px; color: var(--color-text-muted)\">\n {{ role.permissions.length }} permission{{ role.permissions.length === 1 ? '' : 's' }}\n </span>\n </span>\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { StaffComponent } from './staff.component';\n\n@NgModule({\n declarations: [StaffComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: StaffComponent }]),\n ],\n})\nexport class StaffModule {}\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-staff.module-YjJJe00X.mjs","sources":["../../../projects/admin/src/lib/pages/staff/staff.component.ts","../../../projects/admin/src/lib/pages/staff/staff.component.html","../../../projects/admin/src/lib/pages/staff/staff.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { notify, using } from '@thescaffold/ngx-core';\nimport { takeUntil } from 'rxjs';\nimport { ListPageDirective } from '../_shared/list-page.base';\n\ninterface StaffRole {\n id: string;\n name: string;\n title: string;\n permissions: string[];\n superAdmin: boolean;\n}\n\n// Staff (admin dashboard accounts) — super admin only. Backed by\n// `apps/admin/staff` (libs/admin), which enforces the super-admin check\n// server-side; the nav entry and route are only a courtesy. Roles offered\n// here are the existing platform RoleTypes (support agent, catalogue\n// manager, order manager, finance manager, super administrator) — the\n// permission strings shown under each are the ones that role already\n// carries, not something this page defines.\n@Component({\n standalone: false,\n selector: 'x-staff',\n templateUrl: './staff.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class StaffComponent extends ListPageDirective {\n protected pluralName = 'staff';\n protected dataSource = this.apiService.on('apps/admin/staff');\n\n protected columns = [\n { key: 'name', value: 'Name' },\n { key: 'ref', value: 'Email' },\n { key: 'roleLabel', value: 'Roles' },\n { key: 'statusLabel', value: 'Status', type: 'class', class: 'badge text-bg-light border' },\n { key: 'createdAt', value: 'Added', type: 'date' },\n ];\n\n roles: StaffRole[] = [];\n mode: 'create' | 'roles' | null = null;\n saving = false;\n draft: { id?: string; ref?: string; email: string; firstName: string; lastName: string; password: string; roleTypeIds: string[] } | null = null;\n // Shown once after a create that generated the password server-side.\n created: { ref: string; password: string } | null = null;\n\n override init = () => {\n this.apiService\n .get('apps/admin/staff/roles')\n .pipe(takeUntil(this.$))\n .subscribe(using((res: any) => (this.roles = res?.data ?? [])));\n this.list();\n };\n\n protected override mapRow(row: any) {\n return {\n ...row,\n name: [row.firstName, row.lastName].filter(Boolean).join(' ') || '—',\n roleLabel: (row.roles ?? []).map((r: any) => this.roleTitle(r)).join(', '),\n statusLabel: row.suspended ? 'Suspended' : 'Active',\n };\n }\n\n protected override extraCollectionFields() {\n return {\n links: {\n secondary: [\n { title: 'Edit roles', fn: (_link: any, item: any) => this.editRoles(item) },\n {\n title: 'Suspend / reactivate',\n fn: (_link: any, item: any) => this.toggleSuspended(item),\n },\n ],\n },\n };\n }\n\n roleTitle(role: { name: string; title?: string }): string {\n if (role.name === 'global_admin') return 'Super administrator';\n if (role.title) return role.title;\n const words = role.name.replace(/_/g, ' ');\n return words.charAt(0).toUpperCase() + words.slice(1);\n }\n\n startCreate(): void {\n this.created = null;\n this.mode = 'create';\n this.draft = { email: '', firstName: '', lastName: '', password: '', roleTypeIds: [] };\n }\n\n editRoles(item: any): void {\n this.created = null;\n this.mode = 'roles';\n this.draft = {\n id: item.id,\n ref: item.ref,\n email: item.ref,\n firstName: item.firstName ?? '',\n lastName: item.lastName ?? '',\n password: '',\n roleTypeIds: (item.roles ?? []).map((r: any) => r.id),\n };\n }\n\n cancel(): void {\n this.mode = null;\n this.draft = null;\n }\n\n hasRole(id: string): boolean {\n return !!this.draft?.roleTypeIds.includes(id);\n }\n\n toggleRole(id: string): void {\n if (!this.draft) return;\n const ids = this.draft.roleTypeIds;\n this.draft.roleTypeIds = ids.includes(id) ? ids.filter((r) => r !== id) : [...ids, id];\n }\n\n save(): void {\n if (!this.draft || this.saving) return;\n const d = this.draft;\n if (!d.roleTypeIds.length) {\n notify('Assign at least one role.', undefined, 'error');\n return;\n }\n const request$ =\n this.mode === 'create'\n ? this.apiService.post('apps/admin/staff', {\n email: d.email,\n firstName: d.firstName,\n lastName: d.lastName,\n ...(d.password ? { password: d.password } : {}),\n roleTypeIds: d.roleTypeIds,\n })\n : this.apiService.patch(`apps/admin/staff/${d.id}/roles`, { roleTypeIds: d.roleTypeIds });\n\n this.saving = true;\n request$.pipe(takeUntil(this.$)).subscribe({\n next: (res: any) => {\n this.saving = false;\n if (this.mode === 'create' && res?.data?.temporaryPassword) {\n this.created = { ref: res.data.ref, password: res.data.temporaryPassword };\n }\n notify(this.mode === 'create' ? 'Staff account created.' : 'Roles updated.', undefined, 'success');\n this.cancel();\n this.list(this.page, this.perPage, this.query);\n },\n error: (err: any) => {\n this.saving = false;\n notify(err?.error?.message || 'Could not save.', undefined, 'error');\n },\n });\n }\n\n toggleSuspended(item: any): void {\n const action = item.suspended ? 'unsuspend' : 'suspend';\n this.apiService\n .patch(`apps/admin/staff/${item.id}/${action}`, {})\n .pipe(takeUntil(this.$))\n .subscribe({\n next: () => {\n notify(item.suspended ? 'Account reactivated.' : 'Account suspended.', undefined, 'success');\n this.list(this.page, this.perPage, this.query);\n },\n error: (err: any) => notify(err?.error?.message || 'Could not update the account.', undefined, 'error'),\n });\n }\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">Staff</div>\n <div class=\"x-page-subtitle\">\n Back-office accounts and the roles that decide what each can do in the admin console. Super administrators only.\n </div>\n</div>\n\n@if (created) {\n <div class=\"x-scrud-editor\" style=\"margin-bottom: 14px\">\n <div class=\"x-scrud-editor-title\">Account created for {{ created.ref }}</div>\n <div class=\"x-page-subtitle\">\n Temporary password (shown once — copy it now and share it securely):\n <code>{{ created.password }}</code>\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"created = null\">Dismiss</button>\n </div>\n </div>\n}\n\n@if (!mode) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New staff member</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">\n {{ mode === 'create' ? 'New staff member' : 'Roles for ' + draft.ref }}\n </div>\n <div class=\"x-scrud-editor-actions\">\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancel()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n @if (mode === 'create') {\n <div class=\"x-scrud-grid\">\n <label class=\"x-scrud-f\">\n First name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.firstName\" />\n </label>\n <label class=\"x-scrud-f\">\n Last name <span class=\"x-scrud-required\">*</span>\n <input type=\"text\" [(ngModel)]=\"draft.lastName\" />\n </label>\n <label class=\"x-scrud-f\">\n Email <span class=\"x-scrud-required\">*</span>\n <input type=\"email\" [(ngModel)]=\"draft.email\" autocomplete=\"off\" />\n </label>\n <label class=\"x-scrud-f\">\n Initial password\n <input type=\"text\" [(ngModel)]=\"draft.password\" placeholder=\"Leave blank to generate one\" autocomplete=\"off\" />\n </label>\n </div>\n }\n\n <div class=\"x-scrud-f\">\n Roles <span class=\"x-scrud-required\">*</span>\n @for (role of roles; track role.id) {\n <label style=\"display: flex; gap: 8px; align-items: flex-start; font-weight: 400; margin-top: 6px\">\n <input type=\"checkbox\" [checked]=\"hasRole(role.id)\" (change)=\"toggleRole(role.id)\" style=\"margin-top: 3px\" />\n <span>\n <strong>{{ roleTitle(role) }}</strong>\n @if (role.superAdmin) {\n <span class=\"badge text-bg-light border\" style=\"margin-left: 6px\">can manage staff</span>\n }\n <span style=\"display: block; font-size: 11.5px; color: var(--color-text-muted)\">\n {{ role.permissions.length }} permission{{ role.permissions.length === 1 ? '' : 's' }}\n </span>\n </span>\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { StaffComponent } from './staff.component';\n\n@NgModule({\n declarations: [StaffComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: StaffComponent }]),\n ],\n})\nexport class StaffModule {}\n"],"names":["i1"],"mappings":"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"}
@@ -68,11 +68,11 @@ class StockComponent extends SimpleCrudDirective {
68
68
  };
69
69
  }
70
70
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StockComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
71
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StockComponent, isStandalone: false, selector: "x-stock", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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"] }, { kind: "component", type: i2.CollectionComponent, selector: "x-webget-collection", inputs: ["data"], outputs: ["search", "filter", "refresh", "select", "page", "show"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
71
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StockComponent, isStandalone: false, selector: "x-stock", usesInheritance: true, ngImport: i0, template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-pwd{position:relative;display:flex}.x-scrud-pwd input{flex:1;padding-right:34px!important}.x-scrud-pwd-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:none;background:transparent;color:var(--color-text-muted);padding:4px 6px;cursor:pointer}.x-scrud-pwd-toggle:hover{color:var(--color-text)}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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"] }, { kind: "component", type: i2.CollectionComponent, selector: "x-webget-collection", inputs: ["data"], outputs: ["search", "filter", "refresh", "select", "page", "show"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
72
72
  }
73
73
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StockComponent, decorators: [{
74
74
  type: Component,
75
- args: [{ standalone: false, selector: 'x-stock', template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"] }]
75
+ args: [{ standalone: false, selector: 'x-stock', template: "<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving\u2026' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">\u2014 choose \u2014</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n", styles: [".x-page-head{margin-bottom:20px}.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-scrud-toolbar{display:flex;justify-content:flex-end;margin-bottom:14px}.x-scrud-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-scrud-btn:disabled{opacity:.5;cursor:default}.x-scrud-btn-primary{border-color:var(--color-accent);color:var(--color-accent-hover)}.x-scrud-danger{color:var(--color-danger, #c0362c)}.x-scrud-editor{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px;display:flex;flex-direction:column;gap:14px}.x-scrud-editor-head{display:flex;align-items:center;justify-content:space-between}.x-scrud-editor-title{font-size:16px;font-weight:800;color:var(--color-text)}.x-scrud-editor-actions{display:flex;gap:8px}.x-scrud-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.x-scrud-f{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--color-text-muted);font-weight:700}.x-scrud-f-wide{grid-column:1/-1}.x-scrud-f input,.x-scrud-f select,.x-scrud-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);font-weight:400}.x-scrud-f input[type=checkbox]{width:18px;height:18px}.x-scrud-pwd{position:relative;display:flex}.x-scrud-pwd input{flex:1;padding-right:34px!important}.x-scrud-pwd-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);border:none;background:transparent;color:var(--color-text-muted);padding:4px 6px;cursor:pointer}.x-scrud-pwd-toggle:hover{color:var(--color-text)}.x-scrud-json{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.x-scrud-required{color:var(--color-danger, #c0362c)}\n"] }]
76
76
  }] });
77
77
 
78
78
  class StockModule {
@@ -99,4 +99,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
99
99
  }] });
100
100
 
101
101
  export { StockModule };
102
- //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-stock.module-Bt9W1oGR.mjs.map
102
+ //# sourceMappingURL=isaiahiroko-tilmart-ngx-apps-admin-stock.module-BSAe0CfZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-stock.module-Bt9W1oGR.mjs","sources":["../../../projects/admin/src/lib/pages/stock/stock.component.ts","../../../projects/admin/src/lib/pages/_shared/simple-crud.component.html","../../../projects/admin/src/lib/pages/stock/stock.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { using } from '@thescaffold/ngx-core';\nimport { takeUntil } from 'rxjs';\nimport { CrudFieldSpec, SimpleCrudDirective } from '../_shared/simple-crud.base';\n\n// R1 production-readiness pass — CAT-08 (partial). Was a flat read-only\n// table; this makes available/reserved/incoming/threshold/policy\n// editable directly. Reason-coded adjustment history, transfers between\n// locations and serial-number registers are real, separate scope (no\n// `StockAdjustment`-style entity exists yet — that's a new audit-trail\n// feature, not a form to add) — most new variant/location stock rows\n// still get created from the Catalogue product editor, which has proper\n// variant/location pickers; this page is for adjusting an existing row.\n@Component({\n standalone: false,\n selector: 'x-stock',\n templateUrl: '../_shared/simple-crud.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class StockComponent extends SimpleCrudDirective {\n private readonly locationSource = this.apiService.on('apps/commerce/stock-location');\n\n protected pageTitle = 'Stock';\n protected pageSubtitle = 'Per-variant, per-location levels — available, reserved and incoming.';\n protected singularLabel = 'stock level';\n protected pluralName = 'stock';\n protected dataSource = this.apiService.on('apps/commerce/stock-level');\n\n protected columns = [\n { key: 'variantId', value: 'Variant' },\n { key: 'locationId', value: 'Location' },\n { key: 'available', value: 'Available' },\n { key: 'reserved', value: 'Reserved' },\n { key: 'incoming', value: 'Incoming' },\n ];\n\n protected fields: CrudFieldSpec[] = [\n { key: 'variantId', label: 'Variant id', type: 'text', required: true, placeholder: 'paste from the Catalogue editor' },\n { key: 'locationId', label: 'Location', type: 'select', optionsKey: 'locations', required: true },\n { key: 'available', label: 'Available', type: 'number' },\n { key: 'reserved', label: 'Reserved', type: 'number' },\n { key: 'incoming', label: 'Incoming', type: 'number' },\n { key: 'lowStockThreshold', label: 'Low-stock threshold', type: 'number' },\n { key: 'leadTimeDays', label: 'Lead time (days)', type: 'number' },\n {\n key: 'outOfStockPolicy',\n label: 'Out-of-stock policy',\n type: 'select',\n options: [\n { value: 'hide', label: 'Hide' },\n { value: 'show', label: 'Show (sold out)' },\n { value: 'backorder', label: 'Backorder' },\n { value: 'preorder', label: 'Preorder' },\n ],\n },\n ];\n\n override init = () => {\n this.list();\n this.locationSource\n .getMany({ page: 1, perPage: 100 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((response: any) => {\n this.dynamicOptions['locations'] = (response?.data ?? []).map((l: any) => ({\n value: l.id,\n label: l.name,\n }));\n }),\n );\n };\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { StockComponent } from './stock.component';\n\n@NgModule({\n declarations: [StockComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: StockComponent }]),\n ],\n})\nexport class StockModule {}\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"isaiahiroko-tilmart-ngx-apps-admin-stock.module-BSAe0CfZ.mjs","sources":["../../../projects/admin/src/lib/pages/stock/stock.component.ts","../../../projects/admin/src/lib/pages/_shared/simple-crud.component.html","../../../projects/admin/src/lib/pages/stock/stock.module.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { using } from '@thescaffold/ngx-core';\nimport { takeUntil } from 'rxjs';\nimport { CrudFieldSpec, SimpleCrudDirective } from '../_shared/simple-crud.base';\n\n// R1 production-readiness pass — CAT-08 (partial). Was a flat read-only\n// table; this makes available/reserved/incoming/threshold/policy\n// editable directly. Reason-coded adjustment history, transfers between\n// locations and serial-number registers are real, separate scope (no\n// `StockAdjustment`-style entity exists yet — that's a new audit-trail\n// feature, not a form to add) — most new variant/location stock rows\n// still get created from the Catalogue product editor, which has proper\n// variant/location pickers; this page is for adjusting an existing row.\n@Component({\n standalone: false,\n selector: 'x-stock',\n templateUrl: '../_shared/simple-crud.component.html',\n styleUrl: '../_shared/simple-crud.component.scss',\n})\nexport class StockComponent extends SimpleCrudDirective {\n private readonly locationSource = this.apiService.on('apps/commerce/stock-location');\n\n protected pageTitle = 'Stock';\n protected pageSubtitle = 'Per-variant, per-location levels — available, reserved and incoming.';\n protected singularLabel = 'stock level';\n protected pluralName = 'stock';\n protected dataSource = this.apiService.on('apps/commerce/stock-level');\n\n protected columns = [\n { key: 'variantId', value: 'Variant' },\n { key: 'locationId', value: 'Location' },\n { key: 'available', value: 'Available' },\n { key: 'reserved', value: 'Reserved' },\n { key: 'incoming', value: 'Incoming' },\n ];\n\n protected fields: CrudFieldSpec[] = [\n { key: 'variantId', label: 'Variant id', type: 'text', required: true, placeholder: 'paste from the Catalogue editor' },\n { key: 'locationId', label: 'Location', type: 'select', optionsKey: 'locations', required: true },\n { key: 'available', label: 'Available', type: 'number' },\n { key: 'reserved', label: 'Reserved', type: 'number' },\n { key: 'incoming', label: 'Incoming', type: 'number' },\n { key: 'lowStockThreshold', label: 'Low-stock threshold', type: 'number' },\n { key: 'leadTimeDays', label: 'Lead time (days)', type: 'number' },\n {\n key: 'outOfStockPolicy',\n label: 'Out-of-stock policy',\n type: 'select',\n options: [\n { value: 'hide', label: 'Hide' },\n { value: 'show', label: 'Show (sold out)' },\n { value: 'backorder', label: 'Backorder' },\n { value: 'preorder', label: 'Preorder' },\n ],\n },\n ];\n\n override init = () => {\n this.list();\n this.locationSource\n .getMany({ page: 1, perPage: 100 } as any)\n .pipe(takeUntil(this.$))\n .subscribe(\n using((response: any) => {\n this.dynamicOptions['locations'] = (response?.data ?? []).map((l: any) => ({\n value: l.id,\n label: l.name,\n }));\n }),\n );\n };\n}\n","<div class=\"x-page-head\">\n <div class=\"x-page-title\">{{ pageTitle }}</div>\n <div class=\"x-page-subtitle\">{{ pageSubtitle }}</div>\n</div>\n\n@if (!editing) {\n <div class=\"x-scrud-toolbar\">\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" (click)=\"startCreate()\">+ New {{ singularLabel }}</button>\n </div>\n\n @if (list$ | async; as list) {\n <x-webget-collection [data]=\"list\"></x-webget-collection>\n } @else {\n <x-element-loader></x-element-loader>\n }\n} @else if (draft) {\n <div class=\"x-scrud-editor\">\n <div class=\"x-scrud-editor-head\">\n <div class=\"x-scrud-editor-title\">{{ draft['id'] ? 'Edit' : 'New' }} {{ singularLabel }}</div>\n <div class=\"x-scrud-editor-actions\">\n @if (draft['id'] && !hideDelete) {\n <button type=\"button\" class=\"x-scrud-btn x-scrud-danger\" (click)=\"remove(draft); cancelEdit()\">Delete</button>\n }\n <button type=\"button\" class=\"x-scrud-btn\" (click)=\"cancelEdit()\">Close</button>\n <button type=\"button\" class=\"x-scrud-btn x-scrud-btn-primary\" [disabled]=\"saving\" (click)=\"save()\">\n {{ saving ? 'Saving…' : 'Save' }}\n </button>\n </div>\n </div>\n\n <div class=\"x-scrud-grid\">\n @for (f of fields; track f.key) {\n <label class=\"x-scrud-f\" [class.x-scrud-f-wide]=\"f.type === 'textarea' || f.type === 'json'\">\n {{ f.label }}\n @if (f.required) {\n <span class=\"x-scrud-required\">*</span>\n }\n @switch (f.type) {\n @case ('boolean') {\n <input type=\"checkbox\" [(ngModel)]=\"draft[f.key]\" />\n }\n @case ('select') {\n <select [(ngModel)]=\"draft[f.key]\">\n <option value=\"\">— choose —</option>\n @for (opt of (f.optionsKey ? dynamicOptions[f.optionsKey] : f.options); track opt.value) {\n <option [value]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @case ('textarea') {\n <textarea rows=\"3\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\"></textarea>\n }\n @case ('json') {\n <textarea rows=\"4\" class=\"x-scrud-json\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || '{}'\"></textarea>\n }\n @case ('number') {\n <input type=\"number\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n @case ('date') {\n <input type=\"datetime-local\" [(ngModel)]=\"draft[f.key]\" />\n }\n @default {\n <input type=\"text\" [(ngModel)]=\"draft[f.key]\" [placeholder]=\"f.placeholder || ''\" />\n }\n }\n </label>\n }\n </div>\n </div>\n}\n","import { NgModule } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { SharedModule } from '@thescaffold/ngx-core';\nimport { ElementsModule, WebgetsModule } from '@thescaffold/ngx-ui';\nimport { StockComponent } from './stock.component';\n\n@NgModule({\n declarations: [StockComponent],\n imports: [\n SharedModule,\n ElementsModule,\n WebgetsModule,\n RouterModule.forChild([{ path: '', component: StockComponent }]),\n ],\n})\nexport class StockModule {}\n"],"names":["i1"],"mappings":"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"}