mesauth-angular 1.16.1 → 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.
|
|
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.
|
|
@@ -1358,7 +1358,7 @@ class MaUserXComponent {
|
|
|
1358
1358
|
// }
|
|
1359
1359
|
const userId = user?.userId ?? user?.id;
|
|
1360
1360
|
if (userId && baseUrl) {
|
|
1361
|
-
return this.useDefault() ? `${baseUrl.replace(/\/$/, '')}/auth/${userId}/
|
|
1361
|
+
return this.useDefault() ? `${baseUrl.replace(/\/$/, '')}/auth/${userId}/avatars/__default__` //?t=${refresh}
|
|
1362
1362
|
: `${baseUrl.replace(/\/$/, '')}/auth/${userId}/avatar`; //?t=${refresh}
|
|
1363
1363
|
}
|
|
1364
1364
|
const displayName = user?.userName || user?.userId || 'User';
|
|
@@ -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:
|
|
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:
|
|
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 <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 <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 }]
|