mesauth-angular 1.16.2 → 1.16.5

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.
@@ -10,7 +10,7 @@ import { DomSanitizer } from '@angular/platform-browser';
10
10
  import { DatePipe } from '@angular/common';
11
11
 
12
12
  /** Current installed package version — keep in sync with package.json. */
13
- const PACKAGE_VERSION = '1.16.2';
13
+ const PACKAGE_VERSION = '1.16.5';
14
14
  /**
15
15
  * Provides server-driven UI configuration loaded from the hosted manifest.
16
16
  * Components read `labels()` and `features()` signals instead of hardcoded strings.
@@ -1386,11 +1386,11 @@ class MaUserXComponent {
1386
1386
  this.tooltipOpen.set(false);
1387
1387
  }
1388
1388
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: MaUserXComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1389
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: MaUserXComponent, isStandalone: true, selector: "ma-ux", inputs: { userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null }, showName: { classPropertyName: "showName", publicName: "showName", isSignal: true, isRequired: false, transformFunction: null }, showTitle: { classPropertyName: "showTitle", publicName: "showTitle", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, ratio: { classPropertyName: "ratio", publicName: "ratio", isSignal: true, isRequired: false, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null }, useDefault: { classPropertyName: "useDefault", publicName: "useDefault", isSignal: true, isRequired: false, transformFunction: null }, showTooltip: { classPropertyName: "showTooltip", publicName: "showTooltip", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onHostMouseEnter()", "mouseleave": "onHostMouseLeave()", "window:scroll": "onViewportChange()", "window:resize": "onViewportChange()" }, properties: { "class": "this.themeClass" } }, ngImport: i0, template: "<ng-container>\n @if (xUser()){\n <ma-avatar\n [src]=\"getAvatarUrl(xUser())\"\n [alt]=\"xUser()?.fullName || xUser()?.userName || ''\"\n [initials]=\"getLastNameInitial(xUser())\"\n [size]=\"avatarSize()\"\n [shape]=\"avatarShape()\"\n [ratio]=\"avatarRatio()\"\n [frame]=\"avatarFrame()\"\n [scale]=\"scale()\" />\n <span class=\"user-name\">{{ name() }}</span>\n @if (showTitle() && xUser()?.givenTitle){\n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span>\n }\n @if (showTooltip() && xUser(); as u) {\n <div class=\"ma-ux-tooltip\"\n [class.open]=\"tooltipOpen()\"\n [style.top.px]=\"tooltipTop()\"\n [style.left.px]=\"tooltipLeft()\"\n role=\"tooltip\">\n <ma-avatar\n [src]=\"getAvatarUrl(u)\"\n [alt]=\"u.fullName || u.userName || ''\"\n [initials]=\"getLastNameInitial(u)\"\n [size]=\"avatarSize()\"\n [frame]=\"avatarFrame()\"\n [shape]=\"avatarShape()\"\n [scale]=\"1\" />\n <div class=\"ma-ux-tooltip-info\">\n <div class=\"ma-ux-tooltip-name\">{{ u.fullName || u.userName }}</div>\n <div class=\"ma-ux-tooltip-meta\"> \n <span>{{ u.department || '-' }}</span>\n <span class=\"sep\">\u00B7</span>\n <span>{{ u.position || '-' }}</span>\n @if (showTitle() && xUser()?.givenTitle){ \n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span> \n }\n </div>\n </div>\n </div>\n }\n }\n @else {\n <span>User | UserId is not config!</span>\n }\n \n</ng-container>\n", styles: [":host{display:flex;justify-content:flex-start;align-items:center;gap:5px;position:relative}.given-title-cell{display:inline-block;padding:1px 8px;border-radius:10px;font-size:11px;font-weight:600;height:19px}.ma-ux-tooltip{position:fixed;top:0;left:0;z-index:2147483000;display:none;align-items:center;gap:10px;padding:8px 12px;min-width:220px;max-width:320px;background:var(--ma-tooltip-bg, #ffffff);color:var(--ma-tooltip-fg, #212529);border:1px solid var(--ma-tooltip-border, rgba(0, 0, 0, .12));border-radius:8px;box-shadow:0 6px 18px #0000002e;pointer-events:none;opacity:0;transform:translateY(calc(-100% + 4px));transition:opacity .12s ease,transform .12s ease;white-space:nowrap}:host(.theme-dark) .ma-ux-tooltip,:host-context(.theme-dark) .ma-ux-tooltip{--ma-tooltip-bg: #2a2d31;--ma-tooltip-fg: #f1f3f5;--ma-tooltip-border: rgba(255, 255, 255, .12)}.ma-ux-tooltip.open{display:flex;opacity:1;transform:translateY(-100%)}.ma-ux-tooltip-info{display:flex;flex-direction:column;gap:2px;min-width:180px}.ma-ux-tooltip-name{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;margin-bottom:3px}.ma-ux-tooltip-meta{font-size:12px;opacity:.85;line-height:1.4;display:flex;align-items:center;gap:6px;text-overflow:ellipsis}.ma-ux-tooltip-meta .sep{opacity:.5}\n"], dependencies: [{ kind: "component", type: MaAvatarComponent, selector: "ma-avatar", inputs: ["src", "alt", "initials", "size", "shape", "frame", "ratio", "scale", "ring", "ringActive"] }] });
1389
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: MaUserXComponent, isStandalone: true, selector: "ma-ux", inputs: { userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null }, showName: { classPropertyName: "showName", publicName: "showName", isSignal: true, isRequired: false, transformFunction: null }, showTitle: { classPropertyName: "showTitle", publicName: "showTitle", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, ratio: { classPropertyName: "ratio", publicName: "ratio", isSignal: true, isRequired: false, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null }, useDefault: { classPropertyName: "useDefault", publicName: "useDefault", isSignal: true, isRequired: false, transformFunction: null }, showTooltip: { classPropertyName: "showTooltip", publicName: "showTooltip", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onHostMouseEnter()", "mouseleave": "onHostMouseLeave()", "window:scroll": "onViewportChange()", "window:resize": "onViewportChange()" }, properties: { "class": "this.themeClass" } }, ngImport: i0, template: "<ng-container>\n @if (xUser()){\n <ma-avatar\n [src]=\"getAvatarUrl(xUser())\"\n [alt]=\"xUser()?.fullName || xUser()?.userName || ''\"\n [initials]=\"getLastNameInitial(xUser())\"\n [size]=\"avatarSize()\"\n [shape]=\"avatarShape()\"\n [ratio]=\"avatarRatio()\"\n [frame]=\"avatarFrame()\"\n [scale]=\"scale()\" />\n <span class=\"user-name\">{{ name() }}</span>\n @if (showTitle() && xUser()?.givenTitle){\n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span>\n }\n @if (showTooltip() && xUser(); as u) {\n <div class=\"ma-ux-tooltip\"\n [class.open]=\"tooltipOpen()\"\n [style.top.px]=\"tooltipTop()\"\n [style.left.px]=\"tooltipLeft()\"\n role=\"tooltip\">\n <ma-avatar\n [src]=\"getAvatarUrl(u)\"\n [alt]=\"u.fullName || u.userName || ''\"\n [initials]=\"getLastNameInitial(u)\"\n [size]=\"avatarSize()\"\n [frame]=\"avatarFrame()\"\n [shape]=\"avatarShape()\"\n [scale]=\"1\" />\n <div class=\"ma-ux-tooltip-info\">\n <div class=\"ma-ux-tooltip-name\">{{ u.fullName || u.userName }}</div>\n <div class=\"ma-ux-tooltip-meta\"> \n <span>{{ u.department || '-' }}</span>\n <span class=\"sep\">\u00B7</span>\n <span>{{ u.position || '-' }}</span>\n @if (showTitle() && xUser()?.givenTitle){ \n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span> \n }\n </div>\n </div>\n </div>\n }\n }\n @else {\n <span>User | UserId is not config!</span>\n }\n \n</ng-container>\n", styles: [":host{display:flex;justify-content:flex-start;align-items:center;gap:8px;position:relative}.given-title-cell{display:inline-block;padding:1px 8px;border-radius:10px;font-size:11px;font-weight:600;height:19px}.ma-ux-tooltip{position:fixed;top:0;left:0;z-index:2147483000;display:none;align-items:center;gap:10px;padding:8px 12px;min-width:220px;max-width:320px;background:var(--ma-tooltip-bg, #ffffff);color:var(--ma-tooltip-fg, #212529);border:1px solid var(--ma-tooltip-border, rgba(0, 0, 0, .12));border-radius:8px;box-shadow:0 6px 18px #0000002e;pointer-events:none;opacity:0;transform:translateY(calc(-100% + 4px));transition:opacity .12s ease,transform .12s ease;white-space:nowrap}:host(.theme-dark) .ma-ux-tooltip,:host-context(.theme-dark) .ma-ux-tooltip{--ma-tooltip-bg: #2a2d31;--ma-tooltip-fg: #f1f3f5;--ma-tooltip-border: rgba(255, 255, 255, .12)}.ma-ux-tooltip.open{display:flex;opacity:1;transform:translateY(-100%)}.ma-ux-tooltip-info{display:flex;flex-direction:column;gap:2px;min-width:180px}.ma-ux-tooltip-name{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;margin-bottom:3px}.ma-ux-tooltip-meta{font-size:12px;opacity:.85;line-height:1.4;display:flex;align-items:center;gap:6px;text-overflow:ellipsis}.ma-ux-tooltip-meta .sep{opacity:.5}\n"], dependencies: [{ kind: "component", type: MaAvatarComponent, selector: "ma-avatar", inputs: ["src", "alt", "initials", "size", "shape", "frame", "ratio", "scale", "ring", "ringActive"] }] });
1390
1390
  }
1391
1391
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: MaUserXComponent, decorators: [{
1392
1392
  type: Component,
1393
- args: [{ selector: 'ma-ux', imports: [MaAvatarComponent], template: "<ng-container>\n @if (xUser()){\n <ma-avatar\n [src]=\"getAvatarUrl(xUser())\"\n [alt]=\"xUser()?.fullName || xUser()?.userName || ''\"\n [initials]=\"getLastNameInitial(xUser())\"\n [size]=\"avatarSize()\"\n [shape]=\"avatarShape()\"\n [ratio]=\"avatarRatio()\"\n [frame]=\"avatarFrame()\"\n [scale]=\"scale()\" />\n <span class=\"user-name\">{{ name() }}</span>\n @if (showTitle() && xUser()?.givenTitle){\n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span>\n }\n @if (showTooltip() && xUser(); as u) {\n <div class=\"ma-ux-tooltip\"\n [class.open]=\"tooltipOpen()\"\n [style.top.px]=\"tooltipTop()\"\n [style.left.px]=\"tooltipLeft()\"\n role=\"tooltip\">\n <ma-avatar\n [src]=\"getAvatarUrl(u)\"\n [alt]=\"u.fullName || u.userName || ''\"\n [initials]=\"getLastNameInitial(u)\"\n [size]=\"avatarSize()\"\n [frame]=\"avatarFrame()\"\n [shape]=\"avatarShape()\"\n [scale]=\"1\" />\n <div class=\"ma-ux-tooltip-info\">\n <div class=\"ma-ux-tooltip-name\">{{ u.fullName || u.userName }}</div>\n <div class=\"ma-ux-tooltip-meta\"> \n <span>{{ u.department || '-' }}</span>\n <span class=\"sep\">\u00B7</span>\n <span>{{ u.position || '-' }}</span>\n @if (showTitle() && xUser()?.givenTitle){ \n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span> \n }\n </div>\n </div>\n </div>\n }\n }\n @else {\n <span>User | UserId is not config!</span>\n }\n \n</ng-container>\n", styles: [":host{display:flex;justify-content:flex-start;align-items:center;gap:5px;position:relative}.given-title-cell{display:inline-block;padding:1px 8px;border-radius:10px;font-size:11px;font-weight:600;height:19px}.ma-ux-tooltip{position:fixed;top:0;left:0;z-index:2147483000;display:none;align-items:center;gap:10px;padding:8px 12px;min-width:220px;max-width:320px;background:var(--ma-tooltip-bg, #ffffff);color:var(--ma-tooltip-fg, #212529);border:1px solid var(--ma-tooltip-border, rgba(0, 0, 0, .12));border-radius:8px;box-shadow:0 6px 18px #0000002e;pointer-events:none;opacity:0;transform:translateY(calc(-100% + 4px));transition:opacity .12s ease,transform .12s ease;white-space:nowrap}:host(.theme-dark) .ma-ux-tooltip,:host-context(.theme-dark) .ma-ux-tooltip{--ma-tooltip-bg: #2a2d31;--ma-tooltip-fg: #f1f3f5;--ma-tooltip-border: rgba(255, 255, 255, .12)}.ma-ux-tooltip.open{display:flex;opacity:1;transform:translateY(-100%)}.ma-ux-tooltip-info{display:flex;flex-direction:column;gap:2px;min-width:180px}.ma-ux-tooltip-name{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;margin-bottom:3px}.ma-ux-tooltip-meta{font-size:12px;opacity:.85;line-height:1.4;display:flex;align-items:center;gap:6px;text-overflow:ellipsis}.ma-ux-tooltip-meta .sep{opacity:.5}\n"] }]
1393
+ args: [{ selector: 'ma-ux', imports: [MaAvatarComponent], template: "<ng-container>\n @if (xUser()){\n <ma-avatar\n [src]=\"getAvatarUrl(xUser())\"\n [alt]=\"xUser()?.fullName || xUser()?.userName || ''\"\n [initials]=\"getLastNameInitial(xUser())\"\n [size]=\"avatarSize()\"\n [shape]=\"avatarShape()\"\n [ratio]=\"avatarRatio()\"\n [frame]=\"avatarFrame()\"\n [scale]=\"scale()\" />\n <span class=\"user-name\">{{ name() }}</span>\n @if (showTitle() && xUser()?.givenTitle){\n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span>\n }\n @if (showTooltip() && xUser(); as u) {\n <div class=\"ma-ux-tooltip\"\n [class.open]=\"tooltipOpen()\"\n [style.top.px]=\"tooltipTop()\"\n [style.left.px]=\"tooltipLeft()\"\n role=\"tooltip\">\n <ma-avatar\n [src]=\"getAvatarUrl(u)\"\n [alt]=\"u.fullName || u.userName || ''\"\n [initials]=\"getLastNameInitial(u)\"\n [size]=\"avatarSize()\"\n [frame]=\"avatarFrame()\"\n [shape]=\"avatarShape()\"\n [scale]=\"1\" />\n <div class=\"ma-ux-tooltip-info\">\n <div class=\"ma-ux-tooltip-name\">{{ u.fullName || u.userName }}</div>\n <div class=\"ma-ux-tooltip-meta\"> \n <span>{{ u.department || '-' }}</span>\n <span class=\"sep\">\u00B7</span>\n <span>{{ u.position || '-' }}</span>\n @if (showTitle() && xUser()?.givenTitle){ \n <span class=\"given-title-cell given-title-badge\" [class]=\"'given-color-' + xUser()?.givenColor\">{{xUser()?.givenTitle }}</span> \n }\n </div>\n </div>\n </div>\n }\n }\n @else {\n <span>User | UserId is not config!</span>\n }\n \n</ng-container>\n", styles: [":host{display:flex;justify-content:flex-start;align-items:center;gap:8px;position:relative}.given-title-cell{display:inline-block;padding:1px 8px;border-radius:10px;font-size:11px;font-weight:600;height:19px}.ma-ux-tooltip{position:fixed;top:0;left:0;z-index:2147483000;display:none;align-items:center;gap:10px;padding:8px 12px;min-width:220px;max-width:320px;background:var(--ma-tooltip-bg, #ffffff);color:var(--ma-tooltip-fg, #212529);border:1px solid var(--ma-tooltip-border, rgba(0, 0, 0, .12));border-radius:8px;box-shadow:0 6px 18px #0000002e;pointer-events:none;opacity:0;transform:translateY(calc(-100% + 4px));transition:opacity .12s ease,transform .12s ease;white-space:nowrap}:host(.theme-dark) .ma-ux-tooltip,:host-context(.theme-dark) .ma-ux-tooltip{--ma-tooltip-bg: #2a2d31;--ma-tooltip-fg: #f1f3f5;--ma-tooltip-border: rgba(255, 255, 255, .12)}.ma-ux-tooltip.open{display:flex;opacity:1;transform:translateY(-100%)}.ma-ux-tooltip-info{display:flex;flex-direction:column;gap:2px;min-width:180px}.ma-ux-tooltip-name{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;margin-bottom:3px}.ma-ux-tooltip-meta{font-size:12px;opacity:.85;line-height:1.4;display:flex;align-items:center;gap:6px;text-overflow:ellipsis}.ma-ux-tooltip-meta .sep{opacity:.5}\n"] }]
1394
1394
  }], ctorParameters: () => [], propDecorators: { userId: [{ type: i0.Input, args: [{ isSignal: true, alias: "userId", required: false }] }], showName: [{ type: i0.Input, args: [{ isSignal: true, alias: "showName", required: false }] }], showTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTitle", required: false }] }], scale: [{ type: i0.Input, args: [{ isSignal: true, alias: "scale", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: false }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: false }] }], useDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "useDefault", required: false }] }], showTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTooltip", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], themeClass: [{
1395
1395
  type: HostBinding,
1396
1396
  args: ['class']
@@ -1535,7 +1535,6 @@ class MaArvContainerComponent {
1535
1535
  return stepsError;
1536
1536
  }, ...(ngDevMode ? [{ debugName: "isStepsError" }] : /* istanbul ignore next */ []));
1537
1537
  submitResultError = signal(null, ...(ngDevMode ? [{ debugName: "submitResultError" }] : /* istanbul ignore next */ []));
1538
- userLabelMap = signal({}, ...(ngDevMode ? [{ debugName: "userLabelMap" }] : /* istanbul ignore next */ []));
1539
1538
  mesAuth = inject(MesAuthService);
1540
1539
  themeService = inject(ThemeService);
1541
1540
  approvalSvc = null;
@@ -1699,7 +1698,6 @@ class MaArvContainerComponent {
1699
1698
  next[stepIndex] = userId;
1700
1699
  return next;
1701
1700
  });
1702
- this.storeLabelFromCandidates(userId, this.stepCandidates()[stepIndex]);
1703
1701
  this.candidateSearchQuery.update(q => { const copy = [...q]; copy[stepIndex] = ''; return copy; });
1704
1702
  this.candidateSearchResults.update(r => { const copy = [...r]; copy[stepIndex] = []; return copy; });
1705
1703
  }
@@ -1773,7 +1771,6 @@ class MaArvContainerComponent {
1773
1771
  }
1774
1772
  return copy;
1775
1773
  });
1776
- this.storeLabelFromResults(userId, this.userSearchResults()[stepIndex]);
1777
1774
  this.userSearchQuery.update(q => { const copy = [...q]; copy[stepIndex] = ''; return copy; });
1778
1775
  this.userSearchResults.update(r => { const copy = [...r]; copy[stepIndex] = []; return copy; });
1779
1776
  }
@@ -1791,26 +1788,9 @@ class MaArvContainerComponent {
1791
1788
  if (!this.referenceUserIds().includes(userId)) {
1792
1789
  this.referenceUserIds.update(ids => [...ids, userId]);
1793
1790
  }
1794
- this.storeLabelFromResults(userId, this.refSearchResults());
1795
1791
  this.refSearchQuery.set('');
1796
1792
  this.refSearchResults.set([]);
1797
1793
  }
1798
- storeLabelFromResults(userId, results) {
1799
- const user = results.find((u) => u.id === userId);
1800
- if (user) {
1801
- const parts = [user.department, user.position, user.fullName, user.employeeCode].filter(Boolean);
1802
- const label = parts.length > 0 ? parts.join(' - ') : (user.userName || userId);
1803
- this.userLabelMap.update(m => ({ ...m, [userId]: label }));
1804
- }
1805
- }
1806
- storeLabelFromCandidates(userId, candidates) {
1807
- const user = candidates.find((u) => u.userId === userId);
1808
- if (user) {
1809
- const parts = [user.department, user.position, user.fullName, user.employeeCode].filter(Boolean);
1810
- const label = parts.length > 0 ? parts.join(' - ') : (user.employeeCode || userId);
1811
- this.userLabelMap.update(m => ({ ...m, [userId]: label }));
1812
- }
1813
- }
1814
1794
  removeReference(j) {
1815
1795
  this.referenceUserIds.update(ids => ids.filter((_, idx) => idx !== j));
1816
1796
  }
@@ -1855,25 +1835,6 @@ class MaArvContainerComponent {
1855
1835
  return;
1856
1836
  if (this.errorMessage())
1857
1837
  return;
1858
- // if (!this.approvalSvc) { this.errorMessage.set('Approval service not initialized. Ensure provideMesAuth() is configured.'); return; }
1859
- // if (!this.referenceId()) { this.errorMessage.set('ReferenceId is required.'); return; }
1860
- // if (!this.title()) { this.errorMessage.set('Title is required.'); return; }
1861
- // if (this.routingMode === 'template' && !this.selectedTemplateId()) {
1862
- // this.errorMessage.set('Please select a template or switch to Custom Steps.'); return;
1863
- // }
1864
- // if (this.routingMode === 'adhoc' && this.adHocSteps.length === 0) {
1865
- // this.errorMessage.set('Please add at least one approval step.'); return;
1866
- // }
1867
- // // Validate selectable steps (role-based or multi-assignee) have a selected approver
1868
- // if (this.routingMode === 'template' && this.selectedTemplate()) {
1869
- // for (let i = 0; i < this.selectedTemplate().steps.length; i++) {
1870
- // const step = this.selectedTemplate().steps[i];
1871
- // const isSelectable = (this.stepCandidates()[i]?.length ?? 0) > 1;
1872
- // if (isSelectable && !this.stepSelectedUsers()[i]) {
1873
- // this.errorMessage.set(`Please select an approver for step "${step.stepName}".`); return;
1874
- // }
1875
- // }
1876
- // }
1877
1838
  // Emit before capture so parent can hide edit controls (inputs, buttons)
1878
1839
  // then wait one tick for Angular CD to update the DOM before snapshotting
1879
1840
  this.approvalSubmitting.emit();
@@ -2076,11 +2037,11 @@ ${clone.outerHTML}
2076
2037
  ];
2077
2038
  }
2078
2039
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: MaArvContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2079
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: MaArvContainerComponent, isStandalone: true, selector: "ma-arv-container", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, referenceId: { classPropertyName: "referenceId", publicName: "referenceId", isSignal: true, isRequired: false, transformFunction: null }, templateIds: { classPropertyName: "templateIds", publicName: "templateIds", isSignal: true, isRequired: false, transformFunction: null }, callbackUrl: { classPropertyName: "callbackUrl", publicName: "callbackUrl", isSignal: true, isRequired: false, transformFunction: null }, deadlineHours: { classPropertyName: "deadlineHours", publicName: "deadlineHours", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { approvalSubmitted: "approvalSubmitted", approvalSubmitting: "approvalSubmitting", cancelled: "cancelled" }, host: { properties: { "class": "this.themeClass" } }, viewQueries: [{ propertyName: "contentBody", first: true, predicate: ["contentBody"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"arv-container\">\n <!-- Content Area -->\n <div class=\"arv-content-body\" #contentBody>\n <ng-content></ng-content>\n </div>\n\n <!-- Approval Footer -->\n <div class=\"arv-footer\">\n @if (!isSubmitted()) {\n <div class=\"arv-footer-inner\">\n\n <!-- Routing mode -->\n <div class=\"arv-routing\">\n <div class=\"arv-routing-header\">\n <h4 class=\"arv-section-title\">Approval Routing</h4>\n <!-- Show routing toggle only when templateId is NOT locked to a single template -->\n @if (!templateIds() || templateIds()!.length <= 0) {\n <div class=\"arv-routing-mode\">\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"template\" [checked]=\"routingMode() === 'template'\" (change)=\"routingMode.set('template')\"> Use Template\n </label>\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"adhoc\" [checked]=\"routingMode() === 'adhoc'\" (change)=\"routingMode.set('adhoc')\"> Custom Steps\n </label>\n </div>\n }\n </div>\n\n <!-- Locked template: only when templateId set and no multi-choice -->\n @if (templateIds() && templateIds()!.length === 1 && routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (loadingTemplate()) {\n <div class=\"arv-template-loading\">Loading template...</div>\n }\n @if (selectedTemplate() && !loadingTemplate()) {\n <div class=\"arv-locked-template\">\n <span class=\"arv-locked-label\">Template</span>\n <span class=\"arv-locked-name\">{{ selectedTemplate()!.name }}</span>\n </div>\n }\n </div>\n }\n <!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->\n @else if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n <label class=\"arv-label\">Select Template</label>\n <select class=\"arv-select\" (change)=\"onTemplateChange($event)\">\n <option value=\"\">-- Select a template --</option>\n @for (t of templates(); track t.id) {\n <option [value]=\"t.id\" [selected]=\"t.id === selectedTemplateId()\">{{ t.name }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Step pickers (shared for both locked and free template) -->\n @if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (!loadingTemplate() && selectedTemplate()) {\n <!-- arv-template-steps -->\n <div class=\"arv-steps\">\n @for (s of selectedTemplate()!.steps; track s.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-card-header\">\n <span class=\"arv-step-preview-num\">Step {{ s.stepOrder }}</span>\n <span class=\"arv-step-preview-name\">{{ s.stepName }}</span>\n @if(isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n @if (s.roles && s.roles.length > 0) {\n <span class=\"arv-step-role-badge\">\n @for (r of s.roles; track r.id) {\n {{ r.positionLevel }}{{ r.orgName ? ' \u00B7 ' + r.orgName : '' }}{{ r !== s.roles[s.roles.length - 1] ? ', ' : '' }}\n } \n </span>\n }\n </div>\n <!-- Selectable step: show approver picker -->\n @if (stepCandidates()[i]?.length > 1 || stepLoadingCandidates()[i]) {\n @if (stepLoadingCandidates()[i]) {\n <div class=\"arv-template-loading\">Loading candidates...</div>\n }\n @if (!stepLoadingCandidates()[i]) {\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @if (stepSelectedUsers()[i]) {\n <span class=\"arv-tag\">\n <!-- {{ userLabelMap()[stepSelectedUsers()[i]] || stepSelectedUsers()[i] }} -->\n <ma-ux [userId]=\"stepSelectedUsers()[i]\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"onStepUserChangeInput(i, '')\">x</button>\n </span>\n }\n </div>\n @if (!stepSelectedUsers()[i]) {\n <div class=\"arv-user-search arv-step-picker\">\n <input class=\"arv-input arv-input-sm\" [value]=\"candidateSearchQuery()[i] || ''\"\n (input)=\"onCandidateSearchInput(i, $any($event.target).value)\"\n (focus)=\"onCandidateSearchInput(i, candidateSearchQuery()[i] || '')\"\n (blur)=\"clearCandidateResults(i)\"\n placeholder=\"Search approver...\" />\n @if (candidateSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of candidateSearchResults()[i]; track u.userId) {\n <div class=\"arv-search-item\" (mousedown)=\"onStepUserChangeInput(i, u.userId)\">\n <!-- {{ u.fullName || u.userName }} {{ u.department ? ' \u00B7 ' + u.department : '' }} {{ u.position ? ' (' + u.position + ')' : '' }} {{ u.employeeCode ? ' (' + u.employeeCode + ')' : '' }} -->\n <ma-ux [userId]=\"u.userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n }\n <!-- Single fixed-user step: show who is assigned -->\n @if (!stepLoadingCandidates()[i] && stepCandidates()[i]?.length === 1) {\n <div class=\"arv-step-fixed\">\n <!-- {{ stepCandidates()[i][0].fullName || stepCandidates()[i][0].userId }}{{ stepCandidates()[i][0].department ? ' \u00B7 ' + stepCandidates()[i][0].department : '' }}{{ stepCandidates()[i][0].position ? ' (' + stepCandidates()[i][0].position + ')' : '' }}{{ stepCandidates()[i][0].employeeCode ? ' (' + stepCandidates()[i][0].employeeCode + ')' : '' }} -->\n <ma-ux [userId]=\"stepCandidates()[i][0].userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n @if (selectedTemplate() && selectedTemplate()!.referenceUserIds.length > 0) {\n <div class=\"arv-step-preview arv-step-preview-cc\">\n <span class=\"arv-step-preview-num\">CC</span>\n <span class=\"arv-step-preview-name\">{{ selectedTemplate()!.referenceUserIds.length }} reference user(s) from template</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Ad-hoc steps -->\n @if (routingMode() === 'adhoc') {\n <div class=\"arv-steps\">\n @for (step of adHocSteps(); track step.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-header\">\n <span class=\"arv-step-num\">Step {{ i + 1 }}</span>\n @if (isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n <input class=\"arv-input\" [value]=\"step.stepName\" (input)=\"updateStepName(i, $any($event.target).value)\" placeholder=\"Step name\" />\n <button class=\"arv-btn-icon arv-btn-danger\" (click)=\"removeStep(i)\" title=\"Remove step\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n </div>\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @for (uid of step.approverUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap()[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeApprover(i, j)\">x</button>\n </span>\n }\n </div>\n @if (step.approverUserIds.length === 0) {\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"userSearchQuery()[i] || ''\"\n (input)=\"onUserSearchInput(i, $any($event.target).value)\"\n placeholder=\"Search approver...\" />\n @if (userSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of userSearchResults()[i]; track u.id) {\n <div class=\"arv-search-item\" (click)=\"addApprover(i, u.id)\">\n {{ u.fullName || u.userName }} {{ u.department ? ' \u00B7 ' + u.department : '' }} {{ u.position ? ' (' + u.position + ')' : '' }} {{ u.employeeCode ? ' (' + u.employeeCode + ')' : '' }}\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <button class=\"arv-btn arv-btn-outline\" (click)=\"addStep()\">+ Add Step</button>\n </div>\n }\n </div>\n\n <!-- Reference / CC users -->\n <div class=\"arv-references\">\n <h4 class=\"arv-section-title\">CC / Reference</h4>\n <p class=\"arv-hint\">These users will be notified when the approval completes, but won't be asked to approve.</p>\n <div class=\"arv-approver-tags\">\n @for (uid of referenceUserIds(); track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap()[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeReference(j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"refSearchQuery()\"\n (input)=\"onRefSearchInput($any($event.target).value)\"\n placeholder=\"Search CC user...\" />\n @if (refSearchResults().length) {\n <div class=\"arv-search-results\">\n @for (u of refSearchResults(); track u.id) {\n <div class=\"arv-search-item\" (click)=\"addReference(u.id)\">\n {{ u.fullName || u.userName }} {{ u.department ? ' \u00B7 ' + u.department : '' }} {{ u.position ? ' (' + u.position + ')' : '' }} {{ u.employeeCode ? ' (' + u.employeeCode + ')' : '' }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"arv-actions\">\n <button class=\"arv-btn arv-btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"arv-btn arv-btn-primary\" [disabled]=\"submitting() || isError()\" (click)=\"submit()\">\n @if (submitting()) {\n <span class=\"arv-spinner\"></span>\n }\n {{isError() ? 'Complete Form to Submit' : submitting() ? 'Submitting...' : 'Submit for Approval' }}\n </button>\n </div>\n\n @if (errorMessage() || submitResultError()) {\n <div class=\"arv-error\">{{ errorMessage() || submitResultError() }}</div>\n }\n </div>\n }\n </div>\n\n <!-- Success state -->\n @if (isSubmitted()) {\n <div class=\"arv-success\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#66bb6a\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <p>Submitted for approval successfully.</p>\n </div>\n }\n</div>\n", styles: [".arv-container{display:flex;flex-direction:column;height:100%}.arv-content-body{flex:1;overflow:auto}.arv-footer{border-top:1px solid var(--arv-border);background:var(--arv-bg2)}.arv-footer-inner{padding:16px;display:flex;flex-direction:column;gap:14px}.arv-section-title{margin:0 0 8px;font-size:13px;font-weight:700;color:var(--arv-primary);text-transform:uppercase;letter-spacing:.5px}.arv-routing-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.arv-routing-mode{display:flex;gap:12px}.arv-radio{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--arv-text);cursor:pointer}.arv-label{font-size:12px;color:var(--arv-text-muted);display:block;margin-bottom:4px}.arv-template-select{margin-bottom:10px}.arv-select{width:100%;padding:8px 32px 8px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\") no-repeat right 10px center;color:var(--arv-text);font-size:13px;appearance:none;-webkit-appearance:none;cursor:pointer}.arv-input{padding:7px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg);color:var(--arv-text);font-size:13px}.arv-input-sm{width:100%;margin-top:0;padding:3px 10px}.arv-steps{display:flex;flex-direction:column;gap:10px}.arv-step{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);padding:10px}.arv-step-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.arv-step-num{font-size:12px;font-weight:700;color:var(--arv-primary);min-width:44px}.arv-approver-tags{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}.arv-template-select .arv-approver-tags{margin-top:6px}.arv-tag{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;background:#90caf91f;border:1px solid rgba(144,202,249,.3);border-radius:12px;font-size:12px;color:var(--arv-primary)}.arv-tag-remove{background:none;border:none;cursor:pointer;color:var(--arv-text-muted);font-size:11px;padding:0 2px;line-height:1}.arv-tag-remove:hover{color:var(--arv-danger)}.arv-user-search{position:relative}.arv-search-results{position:absolute;left:0;right:0;z-index:100;background:var(--arv-bg2);border:1px solid var(--arv-border);border-radius:var(--arv-radius);max-height:150px;overflow-y:auto}.arv-search-item{padding:8px 12px;cursor:pointer;font-size:13px;color:var(--arv-text)}.arv-search-item:hover{background:var(--arv-bg)}.arv-hint{font-size:12px;color:var(--arv-text-muted);margin:0 0 8px}.arv-btn-icon{background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.arv-btn-danger{color:var(--arv-danger)}.arv-btn-danger:hover{background:#ef53501a}.arv-actions{display:flex;justify-content:flex-end;gap:10px}.arv-btn{padding:9px 18px;border-radius:var(--arv-radius);font-size:13px;font-weight:600;cursor:pointer;border:none;transition:background .15s}.arv-btn-primary{background:var(--arv-primary);color:#fff}.arv-btn-primary:hover:not(:disabled){background:var(--arv-primary-hover)}.arv-btn-primary:disabled{opacity:.6;cursor:not-allowed}.arv-btn-secondary{background:transparent;border:1px solid var(--arv-border);color:var(--arv-text-muted)}.arv-btn-secondary:hover{color:var(--arv-text);border-color:var(--arv-text-muted)}.arv-btn-outline{background:transparent;border:1px dashed var(--arv-border);color:var(--arv-text-muted);font-size:12px;padding:6px 12px}.arv-btn-outline:hover{border-color:var(--arv-primary);color:var(--arv-primary)}.arv-spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:arv-spin .6s linear infinite;margin-right:6px}@keyframes arv-spin{to{transform:rotate(360deg)}}.arv-error{padding:8px 12px;background:#ef53501a;border:1px solid rgba(239,83,80,.3);border-radius:var(--arv-radius);font-size:13px;color:var(--arv-danger)}.arv-success{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px;gap:12px;text-align:center}.arv-success p{color:var(--arv-success);font-size:15px;font-weight:600;margin:0}.arv-references{border-top:1px solid var(--arv-border);padding-top:12px}.arv-template-loading{font-size:12px;color:var(--arv-text-muted);margin-top:8px;padding:4px 0}.arv-template-steps{margin-top:8px;display:flex;flex-direction:column;gap:6px}.arv-step-card{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);overflow:hidden}.arv-step-card-header{display:flex;align-items:center;gap:8px;padding:7px 10px;background:#00000008;border-bottom:1px solid var(--arv-border);flex-wrap:wrap}.arv-step-preview{display:flex;align-items:center;gap:8px;padding:5px 8px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:4px;font-size:12px}.arv-step-preview-num{font-weight:700;color:var(--arv-primary);min-width:44px;flex-shrink:0;font-size:12px}.arv-step-preview-name{flex:1;color:var(--arv-text);font-size:12px;font-weight:600}.arv-step-error{font-size:11px;color:var(--arv-danger);font-weight:600}.arv-step-role-badge{font-size:11px;color:var(--arv-text-muted);background:#90caf91a;border:1px solid rgba(144,202,249,.25);border-radius:10px;padding:1px 7px}.arv-step-preview-cc .arv-step-preview-num{color:var(--arv-text-muted)}.arv-locked-template{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);margin-top:6px}.arv-locked-label{font-size:11px;color:var(--arv-text-muted);text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.arv-locked-name{font-size:13px;font-weight:600;color:var(--arv-text)}.arv-step-picker{padding:0}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"], dependencies: [{ kind: "component", type: MaUserXComponent, selector: "ma-ux", inputs: ["userId", "showName", "showTitle", "scale", "shape", "ratio", "user", "useDefault", "showTooltip", "theme"] }] });
2040
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: MaArvContainerComponent, isStandalone: true, selector: "ma-arv-container", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, referenceId: { classPropertyName: "referenceId", publicName: "referenceId", isSignal: true, isRequired: false, transformFunction: null }, templateIds: { classPropertyName: "templateIds", publicName: "templateIds", isSignal: true, isRequired: false, transformFunction: null }, callbackUrl: { classPropertyName: "callbackUrl", publicName: "callbackUrl", isSignal: true, isRequired: false, transformFunction: null }, deadlineHours: { classPropertyName: "deadlineHours", publicName: "deadlineHours", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { approvalSubmitted: "approvalSubmitted", approvalSubmitting: "approvalSubmitting", cancelled: "cancelled" }, host: { properties: { "class": "this.themeClass" } }, viewQueries: [{ propertyName: "contentBody", first: true, predicate: ["contentBody"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"arv-container\">\n <!-- Content Area -->\n <div class=\"arv-content-body\" #contentBody>\n <ng-content></ng-content>\n </div>\n\n <!-- Approval Footer -->\n <div class=\"arv-footer\">\n @if (!isSubmitted()) {\n <div class=\"arv-footer-inner\">\n\n <!-- Routing mode -->\n <div class=\"arv-routing\">\n <div class=\"arv-routing-header\">\n <h4 class=\"arv-section-title\">Approval Routing</h4>\n <!-- Show routing toggle only when templateId is NOT locked to a single template -->\n @if (!templateIds() || templateIds()!.length <= 0) {\n <div class=\"arv-routing-mode\">\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"template\" [checked]=\"routingMode() === 'template'\" (change)=\"routingMode.set('template')\"> Use Template\n </label>\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"adhoc\" [checked]=\"routingMode() === 'adhoc'\" (change)=\"routingMode.set('adhoc')\"> Custom Steps\n </label>\n </div>\n }\n </div>\n\n <!-- Locked template: only when templateId set and no multi-choice -->\n @if (templateIds() && templateIds()!.length === 1 && routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (loadingTemplate()) {\n <div class=\"arv-template-loading\">Loading template...</div>\n }\n @if (selectedTemplate() && !loadingTemplate()) {\n <div class=\"arv-locked-template\">\n <span class=\"arv-locked-label\">Template</span>\n <span class=\"arv-locked-name\">{{ selectedTemplate()!.name }}</span>\n </div>\n }\n </div>\n }\n <!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->\n @else if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n <label class=\"arv-label\">Select Template</label>\n <select class=\"arv-select\" (change)=\"onTemplateChange($event)\">\n <option value=\"\">-- Select a template --</option>\n @for (t of templates(); track t.id) {\n <option [value]=\"t.id\" [selected]=\"t.id === selectedTemplateId()\">{{ t.name }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Step pickers (shared for both locked and free template) -->\n @if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (!loadingTemplate() && selectedTemplate()) {\n <!-- arv-template-steps -->\n <div class=\"arv-steps\">\n @for (s of selectedTemplate()!.steps; track s.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-card-header\">\n <span class=\"arv-step-preview-num\">Step {{ s.stepOrder }}</span>\n <span class=\"arv-step-preview-name\">{{ s.stepName }}</span>\n @if(isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n @if (s.roles && s.roles.length > 0) {\n <span class=\"arv-step-role-badge\">\n @for (r of s.roles; track r.id) {\n {{ r.positionLevel }}{{ r.orgName ? ' \u00B7 ' + r.orgName : '' }}{{ r !== s.roles[s.roles.length - 1] ? ', ' : '' }}\n } \n </span>\n }\n </div>\n <!-- Selectable step: show approver picker -->\n @if (stepCandidates()[i]?.length > 1 || stepLoadingCandidates()[i]) {\n @if (stepLoadingCandidates()[i]) {\n <div class=\"arv-template-loading\">Loading candidates...</div>\n }\n @if (!stepLoadingCandidates()[i]) {\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @if (stepSelectedUsers()[i]) {\n <span class=\"arv-tag\">\n <ma-ux [userId]=\"stepSelectedUsers()[i]\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"onStepUserChangeInput(i, '')\">x</button>\n </span>\n }\n </div>\n @if (!stepSelectedUsers()[i]) {\n <div class=\"arv-user-search arv-step-picker\">\n <input class=\"arv-input arv-input-sm\" [value]=\"candidateSearchQuery()[i] || ''\"\n (input)=\"onCandidateSearchInput(i, $any($event.target).value)\"\n (focus)=\"onCandidateSearchInput(i, candidateSearchQuery()[i] || '')\"\n (blur)=\"clearCandidateResults(i)\"\n placeholder=\"Search approver...\" />\n @if (candidateSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of candidateSearchResults()[i]; track u.userId) {\n <div class=\"arv-search-item\" (mousedown)=\"onStepUserChangeInput(i, u.userId)\">\n <ma-ux [userId]=\"u.userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n }\n <!-- Single fixed-user step: show who is assigned -->\n @if (!stepLoadingCandidates()[i] && stepCandidates()[i]?.length === 1) {\n <div class=\"arv-step-fixed\">\n <ma-ux [userId]=\"stepCandidates()[i][0].userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n @if (selectedTemplate() && selectedTemplate()!.referenceUserIds.length > 0) {\n <div class=\"arv-step-preview arv-step-preview-cc\">\n <span class=\"arv-step-preview-num\">CC</span>\n <span class=\"arv-step-preview-name\">{{ selectedTemplate()!.referenceUserIds.length }} reference user(s) from template</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Ad-hoc steps -->\n @if (routingMode() === 'adhoc') {\n <div class=\"arv-steps\">\n @for (step of adHocSteps(); track step.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-header\">\n <span class=\"arv-step-num\">Step {{ i + 1 }}</span>\n @if (isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n <input class=\"arv-input\" [value]=\"step.stepName\" (input)=\"updateStepName(i, $any($event.target).value)\" placeholder=\"Step name\" />\n <button class=\"arv-btn-icon arv-btn-danger\" (click)=\"removeStep(i)\" title=\"Remove step\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n </div>\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @for (uid of step.approverUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n <ma-ux [userId]=\"uid\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"removeApprover(i, j)\">x</button>\n </span>\n }\n </div>\n @if (step.approverUserIds.length === 0) {\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"userSearchQuery()[i] || ''\"\n (input)=\"onUserSearchInput(i, $any($event.target).value)\"\n placeholder=\"Search approver...\" />\n @if (userSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of userSearchResults()[i]; track u.id) {\n <div class=\"arv-search-item\" (mousedown)=\"addApprover(i, u.id)\">\n <ma-ux [userId]=\"u.id\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <button class=\"arv-btn arv-btn-outline\" (click)=\"addStep()\">+ Add Step</button>\n </div>\n }\n </div>\n\n <!-- Reference / CC users -->\n <div class=\"arv-references\">\n <h4 class=\"arv-section-title\">CC / Reference</h4>\n <p class=\"arv-hint\">These users will be notified when the approval completes, but won't be asked to approve.</p>\n <div class=\"arv-approver-tags\">\n @for (uid of referenceUserIds(); track uid; let j = $index) {\n <span class=\"arv-tag\">\n <ma-ux [userId]=\"uid\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"removeReference(j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"refSearchQuery()\"\n (input)=\"onRefSearchInput($any($event.target).value)\"\n placeholder=\"Search CC user...\" />\n @if (refSearchResults().length) {\n <div class=\"arv-search-results\">\n @for (u of refSearchResults(); track u.id) {\n <div class=\"arv-search-item\" (mousedown)=\"addReference(u.id)\">\n <ma-ux [userId]=\"u.id\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"arv-actions\">\n <button class=\"arv-btn arv-btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"arv-btn arv-btn-primary\" [disabled]=\"submitting() || isError()\" (click)=\"submit()\">\n @if (submitting()) {\n <span class=\"arv-spinner\"></span>\n }\n {{isError() ? 'Complete Form to Submit' : submitting() ? 'Submitting...' : 'Submit for Approval' }}\n </button>\n </div>\n\n @if (errorMessage() || submitResultError()) {\n <div class=\"arv-error\">{{ errorMessage() || submitResultError() }}</div>\n }\n </div>\n }\n </div>\n\n <!-- Success state -->\n @if (isSubmitted()) {\n <div class=\"arv-success\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#66bb6a\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <p>Submitted for approval successfully.</p>\n </div>\n }\n</div>\n", styles: [".arv-container{display:flex;flex-direction:column;height:100%}.arv-content-body{flex:1;overflow:auto}.arv-footer{border-top:1px solid var(--arv-border);background:var(--arv-bg2)}.arv-footer-inner{padding:16px;display:flex;flex-direction:column;gap:14px}.arv-section-title{margin:0 0 8px;font-size:13px;font-weight:700;color:var(--arv-primary);text-transform:uppercase;letter-spacing:.5px}.arv-routing-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.arv-routing-mode{display:flex;gap:12px}.arv-radio{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--arv-text);cursor:pointer}.arv-label{font-size:12px;color:var(--arv-text-muted);display:block;margin-bottom:4px}.arv-template-select{margin-bottom:10px}.arv-select{width:100%;padding:8px 32px 8px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\") no-repeat right 10px center;color:var(--arv-text);font-size:13px;appearance:none;-webkit-appearance:none;cursor:pointer}.arv-input{padding:7px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg);color:var(--arv-text);font-size:13px}.arv-input-sm{width:100%;margin-top:0;padding:3px 10px}.arv-steps{display:flex;flex-direction:column;gap:10px}.arv-step{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);padding:10px}.arv-step-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.arv-step-num{font-size:12px;font-weight:700;color:var(--arv-primary);min-width:44px}.arv-approver-tags{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}.arv-template-select .arv-approver-tags{margin-top:6px}.arv-tag{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;background:#90caf91f;border:1px solid rgba(144,202,249,.3);border-radius:12px;font-size:12px;color:var(--arv-primary)}.arv-tag-remove{background:none;border:none;cursor:pointer;color:var(--arv-text-muted);font-size:11px;padding:0 2px;line-height:1}.arv-tag-remove:hover{color:var(--arv-danger)}.arv-user-search{position:relative}.arv-search-results{position:absolute;left:0;right:0;z-index:100;background:var(--arv-bg2);border:1px solid var(--arv-border);border-radius:var(--arv-radius);max-height:150px;overflow-y:auto}.arv-search-item{padding:8px 12px;cursor:pointer;font-size:13px;color:var(--arv-text)}.arv-search-item:hover{background:var(--arv-bg)}.arv-hint{font-size:12px;color:var(--arv-text-muted);margin:0 0 8px}.arv-btn-icon{background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.arv-btn-danger{color:var(--arv-danger)}.arv-btn-danger:hover{background:#ef53501a}.arv-actions{display:flex;justify-content:flex-end;gap:10px}.arv-btn{padding:9px 18px;border-radius:var(--arv-radius);font-size:13px;font-weight:600;cursor:pointer;border:none;transition:background .15s}.arv-btn-primary{background:var(--arv-primary);color:#fff}.arv-btn-primary:hover:not(:disabled){background:var(--arv-primary-hover)}.arv-btn-primary:disabled{opacity:.6;cursor:not-allowed}.arv-btn-secondary{background:transparent;border:1px solid var(--arv-border);color:var(--arv-text-muted)}.arv-btn-secondary:hover{color:var(--arv-text);border-color:var(--arv-text-muted)}.arv-btn-outline{background:transparent;border:1px dashed var(--arv-border);color:var(--arv-text-muted);font-size:12px;padding:6px 12px}.arv-btn-outline:hover{border-color:var(--arv-primary);color:var(--arv-primary)}.arv-spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:arv-spin .6s linear infinite;margin-right:6px}@keyframes arv-spin{to{transform:rotate(360deg)}}.arv-error{padding:8px 12px;background:#ef53501a;border:1px solid rgba(239,83,80,.3);border-radius:var(--arv-radius);font-size:13px;color:var(--arv-danger)}.arv-success{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px;gap:12px;text-align:center}.arv-success p{color:var(--arv-success);font-size:15px;font-weight:600;margin:0}.arv-references{border-top:1px solid var(--arv-border);padding-top:12px}.arv-template-loading{font-size:12px;color:var(--arv-text-muted);margin-top:8px;padding:4px 0}.arv-template-steps{margin-top:8px;display:flex;flex-direction:column;gap:6px}.arv-step-card{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);overflow:hidden}.arv-step-card-header{display:flex;align-items:center;gap:8px;padding:7px 10px;background:#00000008;border-bottom:1px solid var(--arv-border);flex-wrap:wrap}.arv-step-preview{display:flex;align-items:center;gap:8px;padding:5px 8px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:4px;font-size:12px}.arv-step-preview-num{font-weight:700;color:var(--arv-primary);min-width:44px;flex-shrink:0;font-size:12px}.arv-step-preview-name{flex:1;color:var(--arv-text);font-size:12px;font-weight:600}.arv-step-error{font-size:11px;color:var(--arv-danger);font-weight:600}.arv-step-role-badge{font-size:11px;color:var(--arv-text-muted);background:#90caf91a;border:1px solid rgba(144,202,249,.25);border-radius:10px;padding:1px 7px}.arv-step-preview-cc .arv-step-preview-num{color:var(--arv-text-muted)}.arv-locked-template{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);margin-top:6px}.arv-locked-label{font-size:11px;color:var(--arv-text-muted);text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.arv-locked-name{font-size:13px;font-weight:600;color:var(--arv-text)}.arv-step-picker{padding:0}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"], dependencies: [{ kind: "component", type: MaUserXComponent, selector: "ma-ux", inputs: ["userId", "showName", "showTitle", "scale", "shape", "ratio", "user", "useDefault", "showTooltip", "theme"] }] });
2080
2041
  }
2081
2042
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: MaArvContainerComponent, decorators: [{
2082
2043
  type: Component,
2083
- args: [{ selector: 'ma-arv-container', imports: [MaUserXComponent], template: "<div class=\"arv-container\">\n <!-- Content Area -->\n <div class=\"arv-content-body\" #contentBody>\n <ng-content></ng-content>\n </div>\n\n <!-- Approval Footer -->\n <div class=\"arv-footer\">\n @if (!isSubmitted()) {\n <div class=\"arv-footer-inner\">\n\n <!-- Routing mode -->\n <div class=\"arv-routing\">\n <div class=\"arv-routing-header\">\n <h4 class=\"arv-section-title\">Approval Routing</h4>\n <!-- Show routing toggle only when templateId is NOT locked to a single template -->\n @if (!templateIds() || templateIds()!.length <= 0) {\n <div class=\"arv-routing-mode\">\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"template\" [checked]=\"routingMode() === 'template'\" (change)=\"routingMode.set('template')\"> Use Template\n </label>\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"adhoc\" [checked]=\"routingMode() === 'adhoc'\" (change)=\"routingMode.set('adhoc')\"> Custom Steps\n </label>\n </div>\n }\n </div>\n\n <!-- Locked template: only when templateId set and no multi-choice -->\n @if (templateIds() && templateIds()!.length === 1 && routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (loadingTemplate()) {\n <div class=\"arv-template-loading\">Loading template...</div>\n }\n @if (selectedTemplate() && !loadingTemplate()) {\n <div class=\"arv-locked-template\">\n <span class=\"arv-locked-label\">Template</span>\n <span class=\"arv-locked-name\">{{ selectedTemplate()!.name }}</span>\n </div>\n }\n </div>\n }\n <!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->\n @else if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n <label class=\"arv-label\">Select Template</label>\n <select class=\"arv-select\" (change)=\"onTemplateChange($event)\">\n <option value=\"\">-- Select a template --</option>\n @for (t of templates(); track t.id) {\n <option [value]=\"t.id\" [selected]=\"t.id === selectedTemplateId()\">{{ t.name }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Step pickers (shared for both locked and free template) -->\n @if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (!loadingTemplate() && selectedTemplate()) {\n <!-- arv-template-steps -->\n <div class=\"arv-steps\">\n @for (s of selectedTemplate()!.steps; track s.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-card-header\">\n <span class=\"arv-step-preview-num\">Step {{ s.stepOrder }}</span>\n <span class=\"arv-step-preview-name\">{{ s.stepName }}</span>\n @if(isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n @if (s.roles && s.roles.length > 0) {\n <span class=\"arv-step-role-badge\">\n @for (r of s.roles; track r.id) {\n {{ r.positionLevel }}{{ r.orgName ? ' \u00B7 ' + r.orgName : '' }}{{ r !== s.roles[s.roles.length - 1] ? ', ' : '' }}\n } \n </span>\n }\n </div>\n <!-- Selectable step: show approver picker -->\n @if (stepCandidates()[i]?.length > 1 || stepLoadingCandidates()[i]) {\n @if (stepLoadingCandidates()[i]) {\n <div class=\"arv-template-loading\">Loading candidates...</div>\n }\n @if (!stepLoadingCandidates()[i]) {\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @if (stepSelectedUsers()[i]) {\n <span class=\"arv-tag\">\n <!-- {{ userLabelMap()[stepSelectedUsers()[i]] || stepSelectedUsers()[i] }} -->\n <ma-ux [userId]=\"stepSelectedUsers()[i]\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"onStepUserChangeInput(i, '')\">x</button>\n </span>\n }\n </div>\n @if (!stepSelectedUsers()[i]) {\n <div class=\"arv-user-search arv-step-picker\">\n <input class=\"arv-input arv-input-sm\" [value]=\"candidateSearchQuery()[i] || ''\"\n (input)=\"onCandidateSearchInput(i, $any($event.target).value)\"\n (focus)=\"onCandidateSearchInput(i, candidateSearchQuery()[i] || '')\"\n (blur)=\"clearCandidateResults(i)\"\n placeholder=\"Search approver...\" />\n @if (candidateSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of candidateSearchResults()[i]; track u.userId) {\n <div class=\"arv-search-item\" (mousedown)=\"onStepUserChangeInput(i, u.userId)\">\n <!-- {{ u.fullName || u.userName }} {{ u.department ? ' \u00B7 ' + u.department : '' }} {{ u.position ? ' (' + u.position + ')' : '' }} {{ u.employeeCode ? ' (' + u.employeeCode + ')' : '' }} -->\n <ma-ux [userId]=\"u.userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n }\n <!-- Single fixed-user step: show who is assigned -->\n @if (!stepLoadingCandidates()[i] && stepCandidates()[i]?.length === 1) {\n <div class=\"arv-step-fixed\">\n <!-- {{ stepCandidates()[i][0].fullName || stepCandidates()[i][0].userId }}{{ stepCandidates()[i][0].department ? ' \u00B7 ' + stepCandidates()[i][0].department : '' }}{{ stepCandidates()[i][0].position ? ' (' + stepCandidates()[i][0].position + ')' : '' }}{{ stepCandidates()[i][0].employeeCode ? ' (' + stepCandidates()[i][0].employeeCode + ')' : '' }} -->\n <ma-ux [userId]=\"stepCandidates()[i][0].userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n @if (selectedTemplate() && selectedTemplate()!.referenceUserIds.length > 0) {\n <div class=\"arv-step-preview arv-step-preview-cc\">\n <span class=\"arv-step-preview-num\">CC</span>\n <span class=\"arv-step-preview-name\">{{ selectedTemplate()!.referenceUserIds.length }} reference user(s) from template</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Ad-hoc steps -->\n @if (routingMode() === 'adhoc') {\n <div class=\"arv-steps\">\n @for (step of adHocSteps(); track step.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-header\">\n <span class=\"arv-step-num\">Step {{ i + 1 }}</span>\n @if (isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n <input class=\"arv-input\" [value]=\"step.stepName\" (input)=\"updateStepName(i, $any($event.target).value)\" placeholder=\"Step name\" />\n <button class=\"arv-btn-icon arv-btn-danger\" (click)=\"removeStep(i)\" title=\"Remove step\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n </div>\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @for (uid of step.approverUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap()[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeApprover(i, j)\">x</button>\n </span>\n }\n </div>\n @if (step.approverUserIds.length === 0) {\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"userSearchQuery()[i] || ''\"\n (input)=\"onUserSearchInput(i, $any($event.target).value)\"\n placeholder=\"Search approver...\" />\n @if (userSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of userSearchResults()[i]; track u.id) {\n <div class=\"arv-search-item\" (click)=\"addApprover(i, u.id)\">\n {{ u.fullName || u.userName }} {{ u.department ? ' \u00B7 ' + u.department : '' }} {{ u.position ? ' (' + u.position + ')' : '' }} {{ u.employeeCode ? ' (' + u.employeeCode + ')' : '' }}\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <button class=\"arv-btn arv-btn-outline\" (click)=\"addStep()\">+ Add Step</button>\n </div>\n }\n </div>\n\n <!-- Reference / CC users -->\n <div class=\"arv-references\">\n <h4 class=\"arv-section-title\">CC / Reference</h4>\n <p class=\"arv-hint\">These users will be notified when the approval completes, but won't be asked to approve.</p>\n <div class=\"arv-approver-tags\">\n @for (uid of referenceUserIds(); track uid; let j = $index) {\n <span class=\"arv-tag\">\n {{ userLabelMap()[uid] || uid }}\n <button class=\"arv-tag-remove\" (click)=\"removeReference(j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"refSearchQuery()\"\n (input)=\"onRefSearchInput($any($event.target).value)\"\n placeholder=\"Search CC user...\" />\n @if (refSearchResults().length) {\n <div class=\"arv-search-results\">\n @for (u of refSearchResults(); track u.id) {\n <div class=\"arv-search-item\" (click)=\"addReference(u.id)\">\n {{ u.fullName || u.userName }} {{ u.department ? ' \u00B7 ' + u.department : '' }} {{ u.position ? ' (' + u.position + ')' : '' }} {{ u.employeeCode ? ' (' + u.employeeCode + ')' : '' }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"arv-actions\">\n <button class=\"arv-btn arv-btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"arv-btn arv-btn-primary\" [disabled]=\"submitting() || isError()\" (click)=\"submit()\">\n @if (submitting()) {\n <span class=\"arv-spinner\"></span>\n }\n {{isError() ? 'Complete Form to Submit' : submitting() ? 'Submitting...' : 'Submit for Approval' }}\n </button>\n </div>\n\n @if (errorMessage() || submitResultError()) {\n <div class=\"arv-error\">{{ errorMessage() || submitResultError() }}</div>\n }\n </div>\n }\n </div>\n\n <!-- Success state -->\n @if (isSubmitted()) {\n <div class=\"arv-success\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#66bb6a\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <p>Submitted for approval successfully.</p>\n </div>\n }\n</div>\n", styles: [".arv-container{display:flex;flex-direction:column;height:100%}.arv-content-body{flex:1;overflow:auto}.arv-footer{border-top:1px solid var(--arv-border);background:var(--arv-bg2)}.arv-footer-inner{padding:16px;display:flex;flex-direction:column;gap:14px}.arv-section-title{margin:0 0 8px;font-size:13px;font-weight:700;color:var(--arv-primary);text-transform:uppercase;letter-spacing:.5px}.arv-routing-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.arv-routing-mode{display:flex;gap:12px}.arv-radio{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--arv-text);cursor:pointer}.arv-label{font-size:12px;color:var(--arv-text-muted);display:block;margin-bottom:4px}.arv-template-select{margin-bottom:10px}.arv-select{width:100%;padding:8px 32px 8px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\") no-repeat right 10px center;color:var(--arv-text);font-size:13px;appearance:none;-webkit-appearance:none;cursor:pointer}.arv-input{padding:7px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg);color:var(--arv-text);font-size:13px}.arv-input-sm{width:100%;margin-top:0;padding:3px 10px}.arv-steps{display:flex;flex-direction:column;gap:10px}.arv-step{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);padding:10px}.arv-step-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.arv-step-num{font-size:12px;font-weight:700;color:var(--arv-primary);min-width:44px}.arv-approver-tags{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}.arv-template-select .arv-approver-tags{margin-top:6px}.arv-tag{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;background:#90caf91f;border:1px solid rgba(144,202,249,.3);border-radius:12px;font-size:12px;color:var(--arv-primary)}.arv-tag-remove{background:none;border:none;cursor:pointer;color:var(--arv-text-muted);font-size:11px;padding:0 2px;line-height:1}.arv-tag-remove:hover{color:var(--arv-danger)}.arv-user-search{position:relative}.arv-search-results{position:absolute;left:0;right:0;z-index:100;background:var(--arv-bg2);border:1px solid var(--arv-border);border-radius:var(--arv-radius);max-height:150px;overflow-y:auto}.arv-search-item{padding:8px 12px;cursor:pointer;font-size:13px;color:var(--arv-text)}.arv-search-item:hover{background:var(--arv-bg)}.arv-hint{font-size:12px;color:var(--arv-text-muted);margin:0 0 8px}.arv-btn-icon{background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.arv-btn-danger{color:var(--arv-danger)}.arv-btn-danger:hover{background:#ef53501a}.arv-actions{display:flex;justify-content:flex-end;gap:10px}.arv-btn{padding:9px 18px;border-radius:var(--arv-radius);font-size:13px;font-weight:600;cursor:pointer;border:none;transition:background .15s}.arv-btn-primary{background:var(--arv-primary);color:#fff}.arv-btn-primary:hover:not(:disabled){background:var(--arv-primary-hover)}.arv-btn-primary:disabled{opacity:.6;cursor:not-allowed}.arv-btn-secondary{background:transparent;border:1px solid var(--arv-border);color:var(--arv-text-muted)}.arv-btn-secondary:hover{color:var(--arv-text);border-color:var(--arv-text-muted)}.arv-btn-outline{background:transparent;border:1px dashed var(--arv-border);color:var(--arv-text-muted);font-size:12px;padding:6px 12px}.arv-btn-outline:hover{border-color:var(--arv-primary);color:var(--arv-primary)}.arv-spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:arv-spin .6s linear infinite;margin-right:6px}@keyframes arv-spin{to{transform:rotate(360deg)}}.arv-error{padding:8px 12px;background:#ef53501a;border:1px solid rgba(239,83,80,.3);border-radius:var(--arv-radius);font-size:13px;color:var(--arv-danger)}.arv-success{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px;gap:12px;text-align:center}.arv-success p{color:var(--arv-success);font-size:15px;font-weight:600;margin:0}.arv-references{border-top:1px solid var(--arv-border);padding-top:12px}.arv-template-loading{font-size:12px;color:var(--arv-text-muted);margin-top:8px;padding:4px 0}.arv-template-steps{margin-top:8px;display:flex;flex-direction:column;gap:6px}.arv-step-card{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);overflow:hidden}.arv-step-card-header{display:flex;align-items:center;gap:8px;padding:7px 10px;background:#00000008;border-bottom:1px solid var(--arv-border);flex-wrap:wrap}.arv-step-preview{display:flex;align-items:center;gap:8px;padding:5px 8px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:4px;font-size:12px}.arv-step-preview-num{font-weight:700;color:var(--arv-primary);min-width:44px;flex-shrink:0;font-size:12px}.arv-step-preview-name{flex:1;color:var(--arv-text);font-size:12px;font-weight:600}.arv-step-error{font-size:11px;color:var(--arv-danger);font-weight:600}.arv-step-role-badge{font-size:11px;color:var(--arv-text-muted);background:#90caf91a;border:1px solid rgba(144,202,249,.25);border-radius:10px;padding:1px 7px}.arv-step-preview-cc .arv-step-preview-num{color:var(--arv-text-muted)}.arv-locked-template{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);margin-top:6px}.arv-locked-label{font-size:11px;color:var(--arv-text-muted);text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.arv-locked-name{font-size:13px;font-weight:600;color:var(--arv-text)}.arv-step-picker{padding:0}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"] }]
2044
+ args: [{ selector: 'ma-arv-container', imports: [MaUserXComponent], template: "<div class=\"arv-container\">\n <!-- Content Area -->\n <div class=\"arv-content-body\" #contentBody>\n <ng-content></ng-content>\n </div>\n\n <!-- Approval Footer -->\n <div class=\"arv-footer\">\n @if (!isSubmitted()) {\n <div class=\"arv-footer-inner\">\n\n <!-- Routing mode -->\n <div class=\"arv-routing\">\n <div class=\"arv-routing-header\">\n <h4 class=\"arv-section-title\">Approval Routing</h4>\n <!-- Show routing toggle only when templateId is NOT locked to a single template -->\n @if (!templateIds() || templateIds()!.length <= 0) {\n <div class=\"arv-routing-mode\">\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"template\" [checked]=\"routingMode() === 'template'\" (change)=\"routingMode.set('template')\"> Use Template\n </label>\n <label class=\"arv-radio\">\n <input type=\"radio\" name=\"routingMode\" value=\"adhoc\" [checked]=\"routingMode() === 'adhoc'\" (change)=\"routingMode.set('adhoc')\"> Custom Steps\n </label>\n </div>\n }\n </div>\n\n <!-- Locked template: only when templateId set and no multi-choice -->\n @if (templateIds() && templateIds()!.length === 1 && routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (loadingTemplate()) {\n <div class=\"arv-template-loading\">Loading template...</div>\n }\n @if (selectedTemplate() && !loadingTemplate()) {\n <div class=\"arv-locked-template\">\n <span class=\"arv-locked-label\">Template</span>\n <span class=\"arv-locked-name\">{{ selectedTemplate()!.name }}</span>\n </div>\n }\n </div>\n }\n <!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->\n @else if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n <label class=\"arv-label\">Select Template</label>\n <select class=\"arv-select\" (change)=\"onTemplateChange($event)\">\n <option value=\"\">-- Select a template --</option>\n @for (t of templates(); track t.id) {\n <option [value]=\"t.id\" [selected]=\"t.id === selectedTemplateId()\">{{ t.name }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Step pickers (shared for both locked and free template) -->\n @if (routingMode() === 'template') {\n <div class=\"arv-template-select\">\n @if (!loadingTemplate() && selectedTemplate()) {\n <!-- arv-template-steps -->\n <div class=\"arv-steps\">\n @for (s of selectedTemplate()!.steps; track s.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-card-header\">\n <span class=\"arv-step-preview-num\">Step {{ s.stepOrder }}</span>\n <span class=\"arv-step-preview-name\">{{ s.stepName }}</span>\n @if(isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n @if (s.roles && s.roles.length > 0) {\n <span class=\"arv-step-role-badge\">\n @for (r of s.roles; track r.id) {\n {{ r.positionLevel }}{{ r.orgName ? ' \u00B7 ' + r.orgName : '' }}{{ r !== s.roles[s.roles.length - 1] ? ', ' : '' }}\n } \n </span>\n }\n </div>\n <!-- Selectable step: show approver picker -->\n @if (stepCandidates()[i]?.length > 1 || stepLoadingCandidates()[i]) {\n @if (stepLoadingCandidates()[i]) {\n <div class=\"arv-template-loading\">Loading candidates...</div>\n }\n @if (!stepLoadingCandidates()[i]) {\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @if (stepSelectedUsers()[i]) {\n <span class=\"arv-tag\">\n <ma-ux [userId]=\"stepSelectedUsers()[i]\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"onStepUserChangeInput(i, '')\">x</button>\n </span>\n }\n </div>\n @if (!stepSelectedUsers()[i]) {\n <div class=\"arv-user-search arv-step-picker\">\n <input class=\"arv-input arv-input-sm\" [value]=\"candidateSearchQuery()[i] || ''\"\n (input)=\"onCandidateSearchInput(i, $any($event.target).value)\"\n (focus)=\"onCandidateSearchInput(i, candidateSearchQuery()[i] || '')\"\n (blur)=\"clearCandidateResults(i)\"\n placeholder=\"Search approver...\" />\n @if (candidateSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of candidateSearchResults()[i]; track u.userId) {\n <div class=\"arv-search-item\" (mousedown)=\"onStepUserChangeInput(i, u.userId)\">\n <ma-ux [userId]=\"u.userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n }\n <!-- Single fixed-user step: show who is assigned -->\n @if (!stepLoadingCandidates()[i] && stepCandidates()[i]?.length === 1) {\n <div class=\"arv-step-fixed\">\n <ma-ux [userId]=\"stepCandidates()[i][0].userId\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n @if (selectedTemplate() && selectedTemplate()!.referenceUserIds.length > 0) {\n <div class=\"arv-step-preview arv-step-preview-cc\">\n <span class=\"arv-step-preview-num\">CC</span>\n <span class=\"arv-step-preview-name\">{{ selectedTemplate()!.referenceUserIds.length }} reference user(s) from template</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Ad-hoc steps -->\n @if (routingMode() === 'adhoc') {\n <div class=\"arv-steps\">\n @for (step of adHocSteps(); track step.stepOrder; let i = $index) {\n <div class=\"arv-step\">\n <div class=\"arv-step-header\">\n <span class=\"arv-step-num\">Step {{ i + 1 }}</span>\n @if (isStepsError()[i]) {\n <span class=\"arv-step-error\">Required (*)</span>\n }\n <input class=\"arv-input\" [value]=\"step.stepName\" (input)=\"updateStepName(i, $any($event.target).value)\" placeholder=\"Step name\" />\n <button class=\"arv-btn-icon arv-btn-danger\" (click)=\"removeStep(i)\" title=\"Remove step\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n </div>\n <div class=\"arv-approvers\">\n <div class=\"arv-approver-tags\">\n @for (uid of step.approverUserIds; track uid; let j = $index) {\n <span class=\"arv-tag\">\n <ma-ux [userId]=\"uid\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"removeApprover(i, j)\">x</button>\n </span>\n }\n </div>\n @if (step.approverUserIds.length === 0) {\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"userSearchQuery()[i] || ''\"\n (input)=\"onUserSearchInput(i, $any($event.target).value)\"\n placeholder=\"Search approver...\" />\n @if (userSearchResults()[i]?.length) {\n <div class=\"arv-search-results\">\n @for (u of userSearchResults()[i]; track u.id) {\n <div class=\"arv-search-item\" (mousedown)=\"addApprover(i, u.id)\">\n <ma-ux [userId]=\"u.id\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n <button class=\"arv-btn arv-btn-outline\" (click)=\"addStep()\">+ Add Step</button>\n </div>\n }\n </div>\n\n <!-- Reference / CC users -->\n <div class=\"arv-references\">\n <h4 class=\"arv-section-title\">CC / Reference</h4>\n <p class=\"arv-hint\">These users will be notified when the approval completes, but won't be asked to approve.</p>\n <div class=\"arv-approver-tags\">\n @for (uid of referenceUserIds(); track uid; let j = $index) {\n <span class=\"arv-tag\">\n <ma-ux [userId]=\"uid\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n <button class=\"arv-tag-remove\" (click)=\"removeReference(j)\">x</button>\n </span>\n }\n </div>\n <div class=\"arv-user-search\">\n <input class=\"arv-input arv-input-sm\" [value]=\"refSearchQuery()\"\n (input)=\"onRefSearchInput($any($event.target).value)\"\n placeholder=\"Search CC user...\" />\n @if (refSearchResults().length) {\n <div class=\"arv-search-results\">\n @for (u of refSearchResults(); track u.id) {\n <div class=\"arv-search-item\" (mousedown)=\"addReference(u.id)\">\n <ma-ux [userId]=\"u.id\" [useDefault]=\"true\" [showTitle]=\"false\"/>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"arv-actions\">\n <button class=\"arv-btn arv-btn-secondary\" (click)=\"onCancel()\">Cancel</button>\n <button class=\"arv-btn arv-btn-primary\" [disabled]=\"submitting() || isError()\" (click)=\"submit()\">\n @if (submitting()) {\n <span class=\"arv-spinner\"></span>\n }\n {{isError() ? 'Complete Form to Submit' : submitting() ? 'Submitting...' : 'Submit for Approval' }}\n </button>\n </div>\n\n @if (errorMessage() || submitResultError()) {\n <div class=\"arv-error\">{{ errorMessage() || submitResultError() }}</div>\n }\n </div>\n }\n </div>\n\n <!-- Success state -->\n @if (isSubmitted()) {\n <div class=\"arv-success\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#66bb6a\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n <p>Submitted for approval successfully.</p>\n </div>\n }\n</div>\n", styles: [".arv-container{display:flex;flex-direction:column;height:100%}.arv-content-body{flex:1;overflow:auto}.arv-footer{border-top:1px solid var(--arv-border);background:var(--arv-bg2)}.arv-footer-inner{padding:16px;display:flex;flex-direction:column;gap:14px}.arv-section-title{margin:0 0 8px;font-size:13px;font-weight:700;color:var(--arv-primary);text-transform:uppercase;letter-spacing:.5px}.arv-routing-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}.arv-routing-mode{display:flex;gap:12px}.arv-radio{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--arv-text);cursor:pointer}.arv-label{font-size:12px;color:var(--arv-text-muted);display:block;margin-bottom:4px}.arv-template-select{margin-bottom:10px}.arv-select{width:100%;padding:8px 32px 8px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\") no-repeat right 10px center;color:var(--arv-text);font-size:13px;appearance:none;-webkit-appearance:none;cursor:pointer}.arv-input{padding:7px 10px;border:1px solid var(--arv-border);border-radius:var(--arv-radius);background:var(--arv-bg);color:var(--arv-text);font-size:13px}.arv-input-sm{width:100%;margin-top:0;padding:3px 10px}.arv-steps{display:flex;flex-direction:column;gap:10px}.arv-step{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);padding:10px}.arv-step-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.arv-step-num{font-size:12px;font-weight:700;color:var(--arv-primary);min-width:44px}.arv-approver-tags{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}.arv-template-select .arv-approver-tags{margin-top:6px}.arv-tag{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;background:#90caf91f;border:1px solid rgba(144,202,249,.3);border-radius:12px;font-size:12px;color:var(--arv-primary)}.arv-tag-remove{background:none;border:none;cursor:pointer;color:var(--arv-text-muted);font-size:11px;padding:0 2px;line-height:1}.arv-tag-remove:hover{color:var(--arv-danger)}.arv-user-search{position:relative}.arv-search-results{position:absolute;left:0;right:0;z-index:100;background:var(--arv-bg2);border:1px solid var(--arv-border);border-radius:var(--arv-radius);max-height:150px;overflow-y:auto}.arv-search-item{padding:8px 12px;cursor:pointer;font-size:13px;color:var(--arv-text)}.arv-search-item:hover{background:var(--arv-bg)}.arv-hint{font-size:12px;color:var(--arv-text-muted);margin:0 0 8px}.arv-btn-icon{background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.arv-btn-danger{color:var(--arv-danger)}.arv-btn-danger:hover{background:#ef53501a}.arv-actions{display:flex;justify-content:flex-end;gap:10px}.arv-btn{padding:9px 18px;border-radius:var(--arv-radius);font-size:13px;font-weight:600;cursor:pointer;border:none;transition:background .15s}.arv-btn-primary{background:var(--arv-primary);color:#fff}.arv-btn-primary:hover:not(:disabled){background:var(--arv-primary-hover)}.arv-btn-primary:disabled{opacity:.6;cursor:not-allowed}.arv-btn-secondary{background:transparent;border:1px solid var(--arv-border);color:var(--arv-text-muted)}.arv-btn-secondary:hover{color:var(--arv-text);border-color:var(--arv-text-muted)}.arv-btn-outline{background:transparent;border:1px dashed var(--arv-border);color:var(--arv-text-muted);font-size:12px;padding:6px 12px}.arv-btn-outline:hover{border-color:var(--arv-primary);color:var(--arv-primary)}.arv-spinner{display:inline-block;width:14px;height:14px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:arv-spin .6s linear infinite;margin-right:6px}@keyframes arv-spin{to{transform:rotate(360deg)}}.arv-error{padding:8px 12px;background:#ef53501a;border:1px solid rgba(239,83,80,.3);border-radius:var(--arv-radius);font-size:13px;color:var(--arv-danger)}.arv-success{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px;gap:12px;text-align:center}.arv-success p{color:var(--arv-success);font-size:15px;font-weight:600;margin:0}.arv-references{border-top:1px solid var(--arv-border);padding-top:12px}.arv-template-loading{font-size:12px;color:var(--arv-text-muted);margin-top:8px;padding:4px 0}.arv-template-steps{margin-top:8px;display:flex;flex-direction:column;gap:6px}.arv-step-card{background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);overflow:hidden}.arv-step-card-header{display:flex;align-items:center;gap:8px;padding:7px 10px;background:#00000008;border-bottom:1px solid var(--arv-border);flex-wrap:wrap}.arv-step-preview{display:flex;align-items:center;gap:8px;padding:5px 8px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:4px;font-size:12px}.arv-step-preview-num{font-weight:700;color:var(--arv-primary);min-width:44px;flex-shrink:0;font-size:12px}.arv-step-preview-name{flex:1;color:var(--arv-text);font-size:12px;font-weight:600}.arv-step-error{font-size:11px;color:var(--arv-danger);font-weight:600}.arv-step-role-badge{font-size:11px;color:var(--arv-text-muted);background:#90caf91a;border:1px solid rgba(144,202,249,.25);border-radius:10px;padding:1px 7px}.arv-step-preview-cc .arv-step-preview-num{color:var(--arv-text-muted)}.arv-locked-template{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--arv-bg);border:1px solid var(--arv-border);border-radius:var(--arv-radius);margin-top:6px}.arv-locked-label{font-size:11px;color:var(--arv-text-muted);text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.arv-locked-name{font-size:13px;font-weight:600;color:var(--arv-text)}.arv-step-picker{padding:0}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"] }]
2084
2045
  }], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], referenceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "referenceId", required: false }] }], templateIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateIds", required: false }] }], callbackUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "callbackUrl", required: false }] }], deadlineHours: [{ type: i0.Input, args: [{ isSignal: true, alias: "deadlineHours", required: false }] }], approvalSubmitted: [{ type: i0.Output, args: ["approvalSubmitted"] }], approvalSubmitting: [{ type: i0.Output, args: ["approvalSubmitting"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }], contentBody: [{
2085
2046
  type: ViewChild,
2086
2047
  args: ['contentBody', { static: true }]