mesauth-angular 1.6.9 → 1.7.1
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.
|
@@ -192,10 +192,10 @@ class MesAuthService {
|
|
|
192
192
|
refreshUser() {
|
|
193
193
|
return this.fetchCurrentUser();
|
|
194
194
|
}
|
|
195
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
196
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
195
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MesAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
196
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MesAuthService });
|
|
197
197
|
}
|
|
198
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
198
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MesAuthService, decorators: [{
|
|
199
199
|
type: Injectable
|
|
200
200
|
}], ctorParameters: () => [] });
|
|
201
201
|
|
|
@@ -267,13 +267,13 @@ function appendPermissions(body, allowedActions) {
|
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
class MesAuthModule {
|
|
270
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
271
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
272
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
270
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MesAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
271
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.7", ngImport: i0, type: MesAuthModule });
|
|
272
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MesAuthModule, providers: [
|
|
273
273
|
MesAuthService
|
|
274
274
|
] });
|
|
275
275
|
}
|
|
276
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
276
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MesAuthModule, decorators: [{
|
|
277
277
|
type: NgModule,
|
|
278
278
|
args: [{
|
|
279
279
|
providers: [
|
|
@@ -332,10 +332,10 @@ class ThemeService {
|
|
|
332
332
|
refreshTheme() {
|
|
333
333
|
this.detectTheme();
|
|
334
334
|
}
|
|
335
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
336
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
335
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
336
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, providedIn: 'root' });
|
|
337
337
|
}
|
|
338
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
338
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ThemeService, decorators: [{
|
|
339
339
|
type: Injectable,
|
|
340
340
|
args: [{
|
|
341
341
|
providedIn: 'root'
|
|
@@ -353,7 +353,7 @@ class UserProfileComponent {
|
|
|
353
353
|
get themeClass() {
|
|
354
354
|
return `theme-${this.currentTheme}`;
|
|
355
355
|
}
|
|
356
|
-
currentUser = signal(null, ...(ngDevMode ? [{ debugName: "currentUser" }] : []));
|
|
356
|
+
currentUser = signal(null, ...(ngDevMode ? [{ debugName: "currentUser" }] : /* istanbul ignore next */ []));
|
|
357
357
|
currentTheme = 'light';
|
|
358
358
|
unreadCount = 0;
|
|
359
359
|
pendingApprovalCount = 0;
|
|
@@ -361,7 +361,7 @@ class UserProfileComponent {
|
|
|
361
361
|
hasUser = false;
|
|
362
362
|
destroy$ = new Subject();
|
|
363
363
|
// Signal to force avatar refresh
|
|
364
|
-
avatarRefresh = signal(Date.now(), ...(ngDevMode ? [{ debugName: "avatarRefresh" }] : []));
|
|
364
|
+
avatarRefresh = signal(Date.now(), ...(ngDevMode ? [{ debugName: "avatarRefresh" }] : /* istanbul ignore next */ []));
|
|
365
365
|
constructor(authService, router, themeService, cdr, http) {
|
|
366
366
|
this.authService = authService;
|
|
367
367
|
this.router = router;
|
|
@@ -512,8 +512,8 @@ class UserProfileComponent {
|
|
|
512
512
|
onNotificationClick() {
|
|
513
513
|
this.notificationClick.emit();
|
|
514
514
|
}
|
|
515
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
516
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
515
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: UserProfileComponent, deps: [{ token: MesAuthService }, { token: i2.Router }, { token: ThemeService }, { token: i0.ChangeDetectorRef }, { token: i4.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
|
|
516
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: UserProfileComponent, isStandalone: true, selector: "ma-user-profile", outputs: { notificationClick: "notificationClick", approvalClick: "approvalClick" }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "this.themeClass" } }, ngImport: i0, template: `
|
|
517
517
|
<div class="user-profile-container">
|
|
518
518
|
<!-- Not logged in -->
|
|
519
519
|
<ng-container *ngIf="!currentUser()">
|
|
@@ -603,7 +603,7 @@ class UserProfileComponent {
|
|
|
603
603
|
</div>
|
|
604
604
|
`, isInline: true, styles: [":host{--primary-color: #1976d2;--primary-hover: #1565c0;--primary-light: rgba(25, 118, 210, .12);--primary-glow: rgba(25, 118, 210, .3);--error-color: #f44336;--error-light: rgba(244, 67, 54, .1);--text-primary: #212121;--text-secondary: #616161;--text-muted: #9e9e9e;--bg-primary: #ffffff;--bg-secondary: #f8f9fa;--bg-hover: #f0f4ff;--border-color: #e0e0e0;--shadow: rgba(0, 0, 0, .12);--shadow-lg: rgba(0, 0, 0, .18)}:host(.theme-dark){--primary-color: #90caf9;--primary-hover: #64b5f6;--primary-light: rgba(144, 202, 249, .12);--primary-glow: rgba(144, 202, 249, .25);--error-color: #ef5350;--error-light: rgba(239, 83, 80, .12);--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #757575;--bg-primary: #1e1e2e;--bg-secondary: #27273a;--bg-hover: #2a2d4a;--border-color: #383850;--shadow: rgba(0, 0, 0, .35);--shadow-lg: rgba(0, 0, 0, .5)}.user-profile-container{display:flex;align-items:center;gap:4px}.login-btn{padding:7px 18px;background-color:var(--primary-color);color:#fff;border:none;border-radius:8px;cursor:pointer;font-weight:500;font-size:13px;letter-spacing:.2px;transition:background-color .2s,transform .15s}.login-btn:hover{background-color:var(--primary-hover);transform:translateY(-1px)}.user-header{display:flex;align-items:center;gap:4px}.notification-btn{position:relative;background:none;border:none;cursor:pointer;padding:8px;border-radius:10px;color:var(--text-secondary);display:flex;align-items:center;justify-content:center;transition:color .2s,background-color .2s}.notification-btn:hover{background-color:var(--primary-light);color:var(--primary-color)}.notification-btn.has-unread{color:var(--primary-color)}.bell-icon{display:block;transition:transform .35s cubic-bezier(.34,1.56,.64,1)}.notification-btn:hover .bell-icon{transform:rotate(-20deg) scale(1.15)}.badge{position:absolute;top:2px;right:2px;background-color:var(--error-color);color:#fff;border-radius:10px;min-width:17px;height:17px;padding:0 4px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;line-height:1;box-shadow:0 0 0 2px var(--bg-primary);animation:badge-pop .25s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(0)}to{transform:scale(1)}}.user-menu-wrapper{position:relative}.user-menu-btn{background:none;border:none;cursor:pointer;padding:2px;border-radius:50%;display:flex;align-items:center;justify-content:center;transition:transform .2s}.user-menu-btn:hover{transform:scale(1.06)}.avatar-ring{border-radius:50%;padding:2px;border:2px solid transparent;transition:border-color .25s,box-shadow .25s}.avatar-ring.active,.user-menu-btn:hover .avatar-ring{border-color:var(--primary-color);box-shadow:0 0 0 3px var(--primary-glow)}.avatar{width:36px;height:36px;border-radius:50%;object-fit:cover;display:block}.avatar-initial{width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,var(--primary-color),var(--primary-hover));color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px}.mes-dropdown-menu{position:absolute;top:calc(100% + 10px);right:0;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:14px;box-shadow:0 8px 32px var(--shadow-lg),0 2px 8px var(--shadow);min-width:220px;z-index:1000;overflow:hidden;animation:dropdown-in .16s cubic-bezier(.16,1,.3,1)}@keyframes dropdown-in{0%{opacity:0;transform:translateY(-8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}.mes-dropdown-header{display:flex;align-items:center;gap:12px;padding:16px;background:var(--bg-secondary)}.dropdown-avatar-wrap{flex-shrink:0}.dropdown-avatar{width:46px;height:46px;border-radius:50%;object-fit:cover;border:2px solid var(--primary-color);display:block}.dropdown-avatar-initial{width:46px;height:46px;border-radius:50%;background:linear-gradient(135deg,var(--primary-color),var(--primary-hover));color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:18px;border:2px solid var(--primary-color)}.dropdown-user-info{display:flex;flex-direction:column;gap:3px;min-width:0}.dropdown-user-name{font-weight:600;font-size:14px;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dropdown-user-sub{font-size:11px;color:var(--primary-color);font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mes-dropdown-divider{height:1px;background:var(--border-color)}.mes-dropdown-item{display:flex;align-items:center;gap:10px;width:100%;padding:11px 16px;border:none;background:none;text-align:left;cursor:pointer;font-size:13.5px;font-weight:500;transition:background-color .15s}.item-icon{flex-shrink:0;opacity:.8}.profile-link{color:var(--primary-color)}.profile-link:hover{background-color:var(--primary-light)}.logout-item{color:var(--error-color)}.logout-item:hover{background-color:var(--error-light)}@media(max-width:768px){.avatar,.avatar-initial{width:32px;height:32px;font-size:13px}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
605
605
|
}
|
|
606
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
606
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: UserProfileComponent, decorators: [{
|
|
607
607
|
type: Component,
|
|
608
608
|
args: [{ selector: 'ma-user-profile', standalone: true, imports: [NgIf], template: `
|
|
609
609
|
<div class="user-profile-container">
|
|
@@ -734,10 +734,10 @@ class ToastService {
|
|
|
734
734
|
clear() {
|
|
735
735
|
this.toasts$.next([]);
|
|
736
736
|
}
|
|
737
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
738
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
737
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
738
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ToastService, providedIn: 'root' });
|
|
739
739
|
}
|
|
740
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
740
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ToastService, decorators: [{
|
|
741
741
|
type: Injectable,
|
|
742
742
|
args: [{ providedIn: 'root' }]
|
|
743
743
|
}] });
|
|
@@ -774,8 +774,8 @@ class ToastContainerComponent {
|
|
|
774
774
|
close(id) {
|
|
775
775
|
this.toastService.remove(id);
|
|
776
776
|
}
|
|
777
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
778
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
777
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ToastContainerComponent, deps: [{ token: ToastService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
778
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: ToastContainerComponent, isStandalone: true, selector: "ma-toast-container", host: { properties: { "class": "this.themeClass" } }, ngImport: i0, template: `
|
|
779
779
|
<div class="toast-container">
|
|
780
780
|
<div *ngFor="let toast of toasts" class="toast toast-{{ toast.type }}">
|
|
781
781
|
|
|
@@ -814,7 +814,7 @@ class ToastContainerComponent {
|
|
|
814
814
|
</div>
|
|
815
815
|
`, isInline: true, styles: [":host{--info-color: #2196f3;--info-bg: rgba(33, 150, 243, .1);--success-color: #43a047;--success-bg: rgba(67, 160, 71, .1);--warning-color: #f57c00;--warning-bg: rgba(245, 124, 0, .1);--error-color: #e53935;--error-bg: rgba(229, 57, 53, .1);--text-primary: #212121;--text-secondary: #757575;--bg-primary: #ffffff;--border-color: rgba(0, 0, 0, .08);--shadow: rgba(0, 0, 0, .1);--shadow-lg: rgba(0, 0, 0, .18)}:host(.theme-dark){--info-color: #64b5f6;--info-bg: rgba(100, 181, 246, .12);--success-color: #66bb6a;--success-bg: rgba(102, 187, 106, .12);--warning-color: #ffb74d;--warning-bg: rgba(255, 183, 77, .12);--error-color: #ef5350;--error-bg: rgba(239, 83, 80, .12);--text-primary: #e0e0e0;--text-secondary: #9e9e9e;--bg-primary: #1e1e2e;--border-color: rgba(255, 255, 255, .08);--shadow: rgba(0, 0, 0, .35);--shadow-lg: rgba(0, 0, 0, .5)}.toast-container{position:fixed;top:20px;right:20px;z-index:9999;pointer-events:none;display:flex;flex-direction:column;gap:10px}.toast{position:relative;display:flex;align-items:flex-start;gap:11px;padding:13px 13px 16px 16px;border-radius:12px;background:var(--bg-primary);border:1px solid var(--border-color);box-shadow:0 8px 28px var(--shadow-lg),0 2px 8px var(--shadow);pointer-events:auto;min-width:300px;max-width:420px;overflow:hidden;animation:toast-in .35s cubic-bezier(.16,1,.3,1)}@keyframes toast-in{0%{opacity:0;transform:translate(36px) scale(.96)}to{opacity:1;transform:translate(0) scale(1)}}.toast:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;border-radius:12px 0 0 12px}.toast-info:before{background:var(--info-color)}.toast-success:before{background:var(--success-color)}.toast-warning:before{background:var(--warning-color)}.toast-error:before{background:var(--error-color)}.toast-icon{flex-shrink:0;width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;margin-left:2px}.toast-info .toast-icon{color:var(--info-color);background:var(--info-bg)}.toast-success .toast-icon{color:var(--success-color);background:var(--success-bg)}.toast-warning .toast-icon{color:var(--warning-color);background:var(--warning-bg)}.toast-error .toast-icon{color:var(--error-color);background:var(--error-bg)}.toast-content{flex:1;min-width:0;padding-top:1px}.toast-title{font-weight:700;font-size:13.5px;margin-bottom:3px;line-height:1.3}.toast-info .toast-title{color:var(--info-color)}.toast-success .toast-title{color:var(--success-color)}.toast-warning .toast-title{color:var(--warning-color)}.toast-error .toast-title{color:var(--error-color)}.toast-message{font-size:12.5px;line-height:1.45;color:var(--text-secondary)}.toast-close{background:none;border:none;cursor:pointer;color:var(--text-secondary);width:26px;height:26px;border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;transition:color .15s,background-color .15s}.toast-close:hover{color:var(--text-primary);background:var(--border-color)}.toast-progress{position:absolute;bottom:0;left:4px;right:0;height:3px;border-radius:0 0 12px;animation:toast-progress linear forwards;opacity:.7}.toast-info .toast-progress{background:var(--info-color)}.toast-success .toast-progress{background:var(--success-color)}.toast-warning .toast-progress{background:var(--warning-color)}.toast-error .toast-progress{background:var(--error-color)}@keyframes toast-progress{0%{width:calc(100% - 4px)}to{width:0}}@media(max-width:600px){.toast-container{top:10px;right:10px;left:10px}.toast{min-width:auto;max-width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
816
816
|
}
|
|
817
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
817
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: ToastContainerComponent, decorators: [{
|
|
818
818
|
type: Component,
|
|
819
819
|
args: [{ selector: 'ma-toast-container', standalone: true, imports: [CommonModule], template: `
|
|
820
820
|
<div class="toast-container">
|
|
@@ -1116,8 +1116,8 @@ class NotificationPanelComponent {
|
|
|
1116
1116
|
}
|
|
1117
1117
|
return normalized;
|
|
1118
1118
|
}
|
|
1119
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1120
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1119
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: NotificationPanelComponent, deps: [{ token: MesAuthService }, { token: ToastService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1120
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: NotificationPanelComponent, isStandalone: true, selector: "ma-notification-panel", outputs: { notificationRead: "notificationRead" }, host: { properties: { "class": "this.themeClass" } }, ngImport: i0, template: `
|
|
1121
1121
|
<div class="notification-panel" [class.open]="isOpen">
|
|
1122
1122
|
<!-- Header -->
|
|
1123
1123
|
<div class="panel-header">
|
|
@@ -1275,7 +1275,7 @@ class NotificationPanelComponent {
|
|
|
1275
1275
|
</div>
|
|
1276
1276
|
`, isInline: true, styles: [".panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px 18px;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);flex-shrink:0}.panel-header-left{display:flex;align-items:center;gap:9px;color:var(--primary)}.panel-header h3{margin:0;font-size:16px;font-weight:700;color:var(--text-primary)}.close-btn{background:none;border:none;cursor:pointer;color:var(--text-muted);width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s}.close-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.tabs{display:flex;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);flex-shrink:0}.tab-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:11px 8px;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-muted);cursor:pointer;font-size:13px;font-weight:500;transition:color .15s,border-color .15s}.tab-btn.active{color:var(--primary);border-bottom-color:var(--primary)}.tab-btn:hover:not(.active){color:var(--text-secondary)}.tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;background:var(--primary);color:#fff;font-size:11px;font-weight:700;border-radius:9px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;gap:12px;color:var(--text-muted)}.empty-state p{margin:0;font-size:13px}.loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;gap:12px;color:var(--text-muted);font-size:13px}.spinner{width:24px;height:24px;border:2px solid var(--border-color);border-top-color:var(--primary);border-radius:50%;animation:spin .7s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n", ":host{display:block;position:relative;--primary: #1976d2;--primary-hover: #1565c0;--success: #43a047;--error: #f44336;--error-hover: #d32f2f;--info-color: #2196f3;--info-bg: rgba(33, 150, 243, .1);--success-bg: rgba(67, 160, 71, .1);--warning-color: #f57c00;--warning-bg: rgba(245, 124, 0, .1);--error-bg: rgba(244, 67, 54, .1);--text-primary: #212121;--text-secondary: #616161;--text-muted: #9e9e9e;--bg-primary: #ffffff;--bg-secondary: #f8f9fa;--bg-hover: #f0f4ff;--bg-unread: rgba(25, 118, 210, .06);--border-color: #e0e0e0;--border-light: #eeeeee;--shadow: rgba(0, 0, 0, .15)}:host(.theme-dark){--primary: #90caf9;--primary-hover: #64b5f6;--success: #66bb6a;--error: #ef5350;--error-hover: #c62828;--info-color: #64b5f6;--info-bg: rgba(100, 181, 246, .12);--success-bg: rgba(102, 187, 106, .12);--warning-color: #ffb74d;--warning-bg: rgba(255, 183, 77, .12);--error-bg: rgba(239, 83, 80, .12);--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #757575;--bg-primary: #1e1e2e;--bg-secondary: #27273a;--bg-hover: #2a2d4a;--bg-unread: rgba(144, 202, 249, .08);--border-color: #383850;--border-light: #2e2e42;--shadow: rgba(0, 0, 0, .4)}.tab-btn:not(.active) .tab-badge{background:var(--error)}.read-badge{background:var(--text-muted)}.notification-panel{position:fixed;top:0;right:-360px;width:360px;height:100vh;background:var(--bg-primary);box-shadow:-4px 0 24px var(--shadow);display:flex;flex-direction:column;z-index:1030;transition:right .3s cubic-bezier(.16,1,.3,1)}.notification-panel.open{right:0}.notifications-list{flex:1;overflow-y:auto}.notification-item{display:flex;align-items:flex-start;gap:0;border-bottom:1px solid var(--border-light);cursor:pointer;background:var(--bg-primary);transition:background-color .15s;position:relative}.notification-item:hover{background:var(--bg-hover)}.notification-item.unread{background:var(--bg-unread)}.notif-accent{width:3px;align-self:stretch;flex-shrink:0;background:transparent;border-radius:0 2px 2px 0;opacity:.3}.notification-item.unread .notif-accent{opacity:1}.notif-accent.type-info{background:var(--info-color)}.notif-accent.type-success{background:var(--success)}.notif-accent.type-warning{background:var(--warning-color)}.notif-accent.type-error{background:var(--error)}.notif-type-icon{flex-shrink:0;width:26px;height:26px;border-radius:7px;display:flex;align-items:center;justify-content:center;align-self:center;margin-left:10px}.notif-type-icon.type-info{color:var(--info-color);background:var(--info-bg)}.notif-type-icon.type-success{color:var(--success);background:var(--success-bg)}.notif-type-icon.type-warning{color:var(--warning-color);background:var(--warning-bg)}.notif-type-icon.type-error{color:var(--error);background:var(--error-bg)}.notification-content{flex:1;min-width:0;padding:12px 8px 12px 12px}.notification-title{font-weight:600;color:var(--text-primary);font-size:13.5px;margin-bottom:3px;line-height:1.35}.notification-message{color:var(--text-secondary);font-size:12px;line-height:1.45;margin-bottom:7px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.notification-meta{display:flex;justify-content:space-between;font-size:11px;color:var(--text-muted)}.app-name{font-weight:600;color:var(--primary)}.icon-btn{background:none;border:none;cursor:pointer;width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0;align-self:center;margin-right:8px;transition:color .15s,background-color .15s;color:var(--text-muted)}.read-btn:hover{color:var(--success);background:#43a0471a}.delete-btn:hover{color:var(--error);background:#f443361a}.panel-footer{padding:10px 14px;border-top:1px solid var(--border-color);background:var(--bg-secondary);flex-shrink:0}.footer-actions{display:flex;gap:8px}.footer-actions .action-btn{flex:1}.action-btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:8px 12px;background:var(--primary);color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:12.5px;font-weight:600;transition:background-color .18s,transform .12s}.action-btn:hover{background:var(--primary-hover);transform:translateY(-1px)}.delete-all-btn{background:var(--error)}.delete-all-btn:hover{background:var(--error-hover)}.modal-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:1060;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.modal-container{background:var(--bg-primary);border-radius:14px;width:90%;max-width:580px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 16px 48px #00000040;animation:modal-in .2s cubic-bezier(.16,1,.3,1)}@keyframes modal-in{0%{opacity:0;transform:scale(.94) translateY(8px)}to{opacity:1;transform:scale(1) translateY(0)}}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);border-radius:14px 14px 0 0;border-top:3px solid transparent}.modal-header.modal-type-info{border-top-color:var(--info-color)}.modal-header.modal-type-success{border-top-color:var(--success)}.modal-header.modal-type-warning{border-top-color:var(--warning-color)}.modal-header.modal-type-error{border-top-color:var(--error)}.modal-header-left{display:flex;align-items:center;gap:10px;min-width:0}.modal-type-icon{flex-shrink:0;width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center}.modal-type-info .modal-type-icon{color:var(--info-color);background:var(--info-bg)}.modal-type-success .modal-type-icon{color:var(--success);background:var(--success-bg)}.modal-type-warning .modal-type-icon{color:var(--warning-color);background:var(--warning-bg)}.modal-type-error .modal-type-icon{color:var(--error);background:var(--error-bg)}.modal-header h3{margin:0;font-size:15px;font-weight:700;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.modal-meta{display:flex;justify-content:space-between;padding:8px 20px;font-size:11.5px;color:var(--text-muted);border-bottom:1px solid var(--border-light)}.modal-body{padding:20px;overflow-y:auto;flex:1;color:var(--text-primary);font-size:14px;line-height:1.65}.modal-footer{padding:12px 20px;border-top:1px solid var(--border-color);background:var(--bg-secondary);border-radius:0 0 14px 14px;display:flex;justify-content:flex-end;gap:8px}.modal-footer .action-btn{width:auto;padding:8px 24px}.modal-footer .see-details-btn{background:var(--info-bg);color:var(--info-color);border:1px solid var(--info-color)}.modal-footer .see-details-btn:hover{opacity:.85}@media(max-width:600px){.notification-panel{width:100%;right:-100%}.modal-container{width:95%;max-height:90vh}}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
1277
1277
|
}
|
|
1278
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1278
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: NotificationPanelComponent, decorators: [{
|
|
1279
1279
|
type: Component,
|
|
1280
1280
|
args: [{ selector: 'ma-notification-panel', standalone: true, imports: [NgIf, NgFor], template: `
|
|
1281
1281
|
<div class="notification-panel" [class.open]="isOpen">
|
|
@@ -1526,10 +1526,10 @@ class MaApprovalService {
|
|
|
1526
1526
|
createApproval(request) {
|
|
1527
1527
|
return this.http.post(`${this.apiBase}/approval/documents`, request, this.opts);
|
|
1528
1528
|
}
|
|
1529
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1530
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1529
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaApprovalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1530
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaApprovalService });
|
|
1531
1531
|
}
|
|
1532
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1532
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaApprovalService, decorators: [{
|
|
1533
1533
|
type: Injectable
|
|
1534
1534
|
}], ctorParameters: () => [] });
|
|
1535
1535
|
|
|
@@ -1669,8 +1669,8 @@ class MaApprovalPanelComponent {
|
|
|
1669
1669
|
this.close();
|
|
1670
1670
|
this.router.navigate(['/auth/approval/my-requests'], { queryParams: { status } });
|
|
1671
1671
|
}
|
|
1672
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1673
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1672
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaApprovalPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1673
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: MaApprovalPanelComponent, isStandalone: true, selector: "ma-approval-panel", outputs: { approvalActioned: "approvalActioned" }, ngImport: i0, template: `
|
|
1674
1674
|
<div class="approval-backdrop" [class.open]="isOpen" (click)="close()"></div>
|
|
1675
1675
|
<div class="approval-panel" [class.open]="isOpen">
|
|
1676
1676
|
|
|
@@ -1776,7 +1776,7 @@ class MaApprovalPanelComponent {
|
|
|
1776
1776
|
</div>
|
|
1777
1777
|
`, isInline: true, styles: [".panel-header{display:flex;justify-content:space-between;align-items:center;padding:16px 18px;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);flex-shrink:0}.panel-header-left{display:flex;align-items:center;gap:9px;color:var(--primary)}.panel-header h3{margin:0;font-size:16px;font-weight:700;color:var(--text-primary)}.close-btn{background:none;border:none;cursor:pointer;color:var(--text-muted);width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s}.close-btn:hover{background:var(--bg-hover);color:var(--text-primary)}.tabs{display:flex;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);flex-shrink:0}.tab-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:11px 8px;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-muted);cursor:pointer;font-size:13px;font-weight:500;transition:color .15s,border-color .15s}.tab-btn.active{color:var(--primary);border-bottom-color:var(--primary)}.tab-btn:hover:not(.active){color:var(--text-secondary)}.tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;background:var(--primary);color:#fff;font-size:11px;font-weight:700;border-radius:9px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;gap:12px;color:var(--text-muted)}.empty-state p{margin:0;font-size:13px}.loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;gap:12px;color:var(--text-muted);font-size:13px}.spinner{width:24px;height:24px;border:2px solid var(--border-color);border-top-color:var(--primary);border-radius:50%;animation:spin .7s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n", ":host{--primary: #90caf9;--success: #66bb6a;--error: #ef5350;--text-primary: #e0e0e0;--text-secondary: #b0b0b0;--text-muted: #757575;--bg-primary: #1e1e2e;--bg-secondary: #27273a;--bg-hover: #2a2d4a;--border-color: #383850;--shadow: rgba(0,0,0,.4)}:host(.theme-light){--primary: #1565c0;--success: #2e7d32;--error: #c62828;--text-primary: #212121;--text-secondary: #616161;--text-muted: #9e9e9e;--bg-primary: #ffffff;--bg-secondary: #f5f5f5;--bg-hover: #e8eaf6;--border-color: #e0e0e0;--shadow: rgba(0,0,0,.15)}.approval-backdrop{display:none;position:fixed;inset:0;background:#0006;z-index:1029}.approval-backdrop.open{display:block}.approval-panel{position:fixed;top:0;right:-380px;width:380px;height:100vh;background:var(--bg-primary);box-shadow:-4px 0 24px var(--shadow);display:flex;flex-direction:column;z-index:1030;transition:right .3s cubic-bezier(.16,1,.3,1)}.approval-panel.open{right:0}.panel-content{flex:1;overflow-y:auto;padding:8px 0}.approval-item{padding:14px 18px;border-bottom:1px solid var(--border-color);cursor:pointer;transition:background .15s}.approval-item:hover{background:var(--bg-hover)}.approval-item:last-child{border-bottom:none}.item-title{font-size:14px;font-weight:600;color:var(--text-primary);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.item-meta{font-size:12px;color:var(--text-muted);margin-bottom:8px;display:flex;gap:4px;flex-wrap:wrap}.item-footer{display:flex;align-items:center;gap:8px}.item-time{font-size:11px;color:var(--text-muted);margin-right:auto}.item-link{font-size:12px;color:var(--primary);font-weight:500}.status-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:600;letter-spacing:.3px}.approved-badge{background:#66bb6a26;color:var(--success)}.rejected-badge{background:#ef53501f;color:var(--error)}.show-more{text-align:center;padding:14px;font-size:13px;color:var(--primary);cursor:pointer;font-weight:500}.show-more:hover{text-decoration:underline}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
|
|
1778
1778
|
}
|
|
1779
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1779
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaApprovalPanelComponent, decorators: [{
|
|
1780
1780
|
type: Component,
|
|
1781
1781
|
args: [{ selector: 'ma-approval-panel', standalone: true, imports: [NgIf, NgFor, DatePipe], template: `
|
|
1782
1782
|
<div class="approval-backdrop" [class.open]="isOpen" (click)="close()"></div>
|
|
@@ -1906,8 +1906,8 @@ class MaUserComponent {
|
|
|
1906
1906
|
this.userProfile.loadPendingApprovalCount();
|
|
1907
1907
|
}
|
|
1908
1908
|
}
|
|
1909
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1910
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1909
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaUserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1910
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: MaUserComponent, isStandalone: true, selector: "ma-user", viewQueries: [{ propertyName: "userProfile", first: true, predicate: UserProfileComponent, descendants: true }, { propertyName: "approvalPanel", first: true, predicate: MaApprovalPanelComponent, descendants: true }], ngImport: i0, template: `
|
|
1911
1911
|
<ma-toast-container></ma-toast-container>
|
|
1912
1912
|
<div class="user-header">
|
|
1913
1913
|
<ma-user-profile
|
|
@@ -1919,7 +1919,7 @@ class MaUserComponent {
|
|
|
1919
1919
|
<ma-approval-panel #approvalPanel (approvalActioned)="onApprovalActioned()"></ma-approval-panel>
|
|
1920
1920
|
`, isInline: true, styles: [".user-header{display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "component", type: ToastContainerComponent, selector: "ma-toast-container" }, { kind: "component", type: UserProfileComponent, selector: "ma-user-profile", outputs: ["notificationClick", "approvalClick"] }, { kind: "component", type: NotificationPanelComponent, selector: "ma-notification-panel", outputs: ["notificationRead"] }, { kind: "component", type: MaApprovalPanelComponent, selector: "ma-approval-panel", outputs: ["approvalActioned"] }] });
|
|
1921
1921
|
}
|
|
1922
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1922
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaUserComponent, decorators: [{
|
|
1923
1923
|
type: Component,
|
|
1924
1924
|
args: [{ selector: 'ma-user', standalone: true, imports: [ToastContainerComponent, UserProfileComponent, NotificationPanelComponent, MaApprovalPanelComponent], template: `
|
|
1925
1925
|
<ma-toast-container></ma-toast-container>
|
|
@@ -1999,15 +1999,15 @@ class NotificationBadgeComponent {
|
|
|
1999
1999
|
onNotificationClick() {
|
|
2000
2000
|
this.notificationClick.emit();
|
|
2001
2001
|
}
|
|
2002
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2003
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
2002
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: NotificationBadgeComponent, deps: [{ token: MesAuthService }, { token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2003
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.7", type: NotificationBadgeComponent, isStandalone: true, selector: "ma-notification-badge", outputs: { notificationClick: "notificationClick" }, host: { properties: { "class": "this.themeClass" } }, ngImport: i0, template: `
|
|
2004
2004
|
<button class="notification-btn" (click)="onNotificationClick()" title="Notifications">
|
|
2005
2005
|
<span class="icon">🔔</span>
|
|
2006
2006
|
<span class="badge" *ngIf="unreadCount > 0">{{ unreadCount }}</span>
|
|
2007
2007
|
</button>
|
|
2008
2008
|
`, isInline: true, styles: [":host{--error-color: #f44336}:host(.theme-dark){--error-color: #ef5350}.notification-btn{position:relative;background:none;border:none;font-size:24px;cursor:pointer;padding:8px;transition:opacity .2s}.notification-btn:hover{opacity:.7}.icon{display:inline-block}.badge{position:absolute;top:0;right:0;background-color:var(--error-color);color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
2009
2009
|
}
|
|
2010
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2010
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: NotificationBadgeComponent, decorators: [{
|
|
2011
2011
|
type: Component,
|
|
2012
2012
|
args: [{ selector: 'ma-notification-badge', standalone: true, imports: [NgIf], template: `
|
|
2013
2013
|
<button class="notification-btn" (click)="onNotificationClick()" title="Notifications">
|
|
@@ -2027,6 +2027,7 @@ class MaArvContainerComponent {
|
|
|
2027
2027
|
description;
|
|
2028
2028
|
referenceId = '';
|
|
2029
2029
|
templateId;
|
|
2030
|
+
templateIds;
|
|
2030
2031
|
callbackUrl;
|
|
2031
2032
|
deadlineHours;
|
|
2032
2033
|
approvalSubmitted = new EventEmitter();
|
|
@@ -2078,6 +2079,8 @@ class MaArvContainerComponent {
|
|
|
2078
2079
|
loadTemplates() {
|
|
2079
2080
|
this.approvalSvc.getTemplates().pipe(takeUntil(this.destroy$)).subscribe({
|
|
2080
2081
|
next: (t) => {
|
|
2082
|
+
if (this.templateIds && this.templateIds.length > 0)
|
|
2083
|
+
t = t.filter(temp => this.templateIds.includes(temp.id));
|
|
2081
2084
|
this.templates = t;
|
|
2082
2085
|
if (this.templateId != null && this.selectedTemplateId == null) {
|
|
2083
2086
|
this.selectedTemplateId = this.templateId;
|
|
@@ -2484,330 +2487,430 @@ ${clone.outerHTML}
|
|
|
2484
2487
|
'text-transform', 'letter-spacing', 'white-space', 'word-break'
|
|
2485
2488
|
];
|
|
2486
2489
|
}
|
|
2487
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2488
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2489
|
-
|
|
2490
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaArvContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2491
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: MaArvContainerComponent, isStandalone: true, selector: "ma-arv-container", inputs: { title: "title", description: "description", referenceId: "referenceId", templateId: "templateId", templateIds: "templateIds", callbackUrl: "callbackUrl", deadlineHours: "deadlineHours" }, 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: `
|
|
2492
|
+
<div class="arv-container">
|
|
2490
2493
|
<!-- Content Area -->
|
|
2491
2494
|
<div class="arv-content-body" #contentBody>
|
|
2492
2495
|
<ng-content></ng-content>
|
|
2493
2496
|
</div>
|
|
2494
2497
|
|
|
2495
2498
|
<!-- Approval Footer -->
|
|
2496
|
-
<div class="arv-footer"
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
<div class="arv-routing
|
|
2502
|
-
<
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
<
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
<div *ngIf="templateId && routingMode === 'template'" class="arv-template-select">
|
|
2516
|
-
<div *ngIf="loadingTemplate" class="arv-template-loading">Loading template...</div>
|
|
2517
|
-
<div *ngIf="selectedTemplate && !loadingTemplate" class="arv-locked-template">
|
|
2518
|
-
<span class="arv-locked-label">Template</span>
|
|
2519
|
-
<span class="arv-locked-name">{{ selectedTemplate.name }}</span>
|
|
2499
|
+
<div class="arv-footer">
|
|
2500
|
+
@if (!isSubmitted) {
|
|
2501
|
+
<div class="arv-footer-inner">
|
|
2502
|
+
|
|
2503
|
+
<!-- Routing mode -->
|
|
2504
|
+
<div class="arv-routing">
|
|
2505
|
+
<div class="arv-routing-header">
|
|
2506
|
+
<h4 class="arv-section-title">Approval Routing</h4>
|
|
2507
|
+
<!-- Show routing toggle only when templateId is NOT locked to a single template -->
|
|
2508
|
+
@if (!templateId || (templateIds && templateIds.length > 0)) {
|
|
2509
|
+
<div class="arv-routing-mode">
|
|
2510
|
+
<label class="arv-radio">
|
|
2511
|
+
<input type="radio" name="routingMode" value="template" [checked]="routingMode === 'template'" (change)="routingMode = 'template'"> Use Template
|
|
2512
|
+
</label>
|
|
2513
|
+
<label class="arv-radio">
|
|
2514
|
+
<input type="radio" name="routingMode" value="adhoc" [checked]="routingMode === 'adhoc'" (change)="routingMode = 'adhoc'"> Custom Steps
|
|
2515
|
+
</label>
|
|
2516
|
+
</div>
|
|
2517
|
+
}
|
|
2520
2518
|
</div>
|
|
2521
|
-
</div>
|
|
2522
2519
|
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
<div class="arv-step-card" *ngFor="let s of selectedTemplate.steps; let i = index">
|
|
2536
|
-
<div class="arv-step-card-header">
|
|
2537
|
-
<span class="arv-step-preview-num">Step {{ s.stepOrder }}</span>
|
|
2538
|
-
<span class="arv-step-preview-name">{{ s.stepName }}</span>
|
|
2539
|
-
<span *ngIf="s.roles && s.roles.length > 0" class="arv-step-role-badge">
|
|
2540
|
-
{{ s.roles[0].positionLevel }}{{ s.roles[0].orgName ? ' · ' + s.roles[0].orgName : '' }}
|
|
2541
|
-
</span>
|
|
2542
|
-
</div>
|
|
2543
|
-
<!-- Selectable step (role-based or multi-assignee): show approver picker -->
|
|
2544
|
-
<div *ngIf="stepCandidates[i]?.length > 1 || stepLoadingCandidates[i]" class="arv-step-picker">
|
|
2545
|
-
<div *ngIf="stepLoadingCandidates[i]" class="arv-template-loading">Loading candidates...</div>
|
|
2546
|
-
<select *ngIf="!stepLoadingCandidates[i]" class="arv-select arv-select-sm"
|
|
2547
|
-
(change)="onStepUserChange(i, $event)">
|
|
2548
|
-
<option value="">-- Select approver --</option>
|
|
2549
|
-
<option *ngFor="let u of stepCandidates[i]" [value]="u.userId"
|
|
2550
|
-
[selected]="u.userId === stepSelectedUsers[i]">
|
|
2551
|
-
{{ u.fullName || u.userId }}{{ u.department ? ' · ' + u.department : '' }}{{ u.position ? ' (' + u.position + ')' : '' }}
|
|
2552
|
-
</option>
|
|
2553
|
-
</select>
|
|
2554
|
-
</div>
|
|
2555
|
-
<!-- Single fixed-user step: show who is assigned -->
|
|
2556
|
-
<div *ngIf="!stepLoadingCandidates[i] && stepCandidates[i]?.length === 1" class="arv-step-fixed">
|
|
2557
|
-
{{ stepCandidates[i][0].fullName || stepCandidates[i][0].userId }}{{ stepCandidates[i][0].department ? ' · ' + stepCandidates[i][0].department : '' }}{{ stepCandidates[i][0].position ? ' (' + stepCandidates[i][0].position + ')' : '' }}
|
|
2558
|
-
</div>
|
|
2520
|
+
<!-- Locked template: only when templateId set and no multi-choice -->
|
|
2521
|
+
@if (templateId && (!templateIds || templateIds.length <= 1) && routingMode === 'template') {
|
|
2522
|
+
<div class="arv-template-select">
|
|
2523
|
+
@if (loadingTemplate) {
|
|
2524
|
+
<div class="arv-template-loading">Loading template...</div>
|
|
2525
|
+
}
|
|
2526
|
+
@if (selectedTemplate && !loadingTemplate) {
|
|
2527
|
+
<div class="arv-locked-template">
|
|
2528
|
+
<span class="arv-locked-label">Template</span>
|
|
2529
|
+
<span class="arv-locked-name">{{ selectedTemplate.name }}</span>
|
|
2530
|
+
</div>
|
|
2531
|
+
}
|
|
2559
2532
|
</div>
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
<!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->
|
|
2536
|
+
@if ((!templateId || (templateIds && templateIds.length > 1)) && routingMode === 'template') {
|
|
2537
|
+
<div class="arv-template-select">
|
|
2538
|
+
<label class="arv-label">Select Template</label>
|
|
2539
|
+
<select class="arv-select" (change)="onTemplateChange($event)">
|
|
2540
|
+
<option value="">-- Select a template --</option>
|
|
2541
|
+
@for (t of templates; track t.id) {
|
|
2542
|
+
<option [value]="t.id" [selected]="t.id === selectedTemplateId">{{ t.name }}</option>
|
|
2543
|
+
}
|
|
2544
|
+
</select>
|
|
2563
2545
|
</div>
|
|
2564
|
-
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
<!-- Step pickers (shared for both locked and free template) -->
|
|
2549
|
+
@if (routingMode === 'template') {
|
|
2550
|
+
<div class="arv-template-select">
|
|
2551
|
+
@if (!loadingTemplate && selectedTemplate) {
|
|
2552
|
+
<div class="arv-template-steps">
|
|
2553
|
+
@for (s of selectedTemplate.steps; track s.stepOrder; let i = $index) {
|
|
2554
|
+
<div class="arv-step-card">
|
|
2555
|
+
<div class="arv-step-card-header">
|
|
2556
|
+
<span class="arv-step-preview-num">Step {{ s.stepOrder }}</span>
|
|
2557
|
+
<span class="arv-step-preview-name">{{ s.stepName }}</span>
|
|
2558
|
+
@if (s.roles && s.roles.length > 0) {
|
|
2559
|
+
<span class="arv-step-role-badge">
|
|
2560
|
+
{{ s.roles[0].positionLevel }}{{ s.roles[0].orgName ? ' · ' + s.roles[0].orgName : '' }}
|
|
2561
|
+
</span>
|
|
2562
|
+
}
|
|
2563
|
+
</div>
|
|
2564
|
+
<!-- Selectable step: show approver picker -->
|
|
2565
|
+
@if (stepCandidates[i]?.length > 1 || stepLoadingCandidates[i]) {
|
|
2566
|
+
<div class="arv-step-picker">
|
|
2567
|
+
@if (stepLoadingCandidates[i]) {
|
|
2568
|
+
<div class="arv-template-loading">Loading candidates...</div>
|
|
2569
|
+
}
|
|
2570
|
+
@if (!stepLoadingCandidates[i]) {
|
|
2571
|
+
<select class="arv-select arv-select-sm" (change)="onStepUserChange(i, $event)">
|
|
2572
|
+
<option value="">-- Select approver --</option>
|
|
2573
|
+
@for (u of stepCandidates[i]; track u.userId) {
|
|
2574
|
+
<option [value]="u.userId" [selected]="u.userId === stepSelectedUsers[i]">
|
|
2575
|
+
{{ u.fullName || u.userId }}{{ u.department ? ' · ' + u.department : '' }}{{ u.position ? ' (' + u.position + ')' : '' }}
|
|
2576
|
+
</option>
|
|
2577
|
+
}
|
|
2578
|
+
</select>
|
|
2579
|
+
}
|
|
2580
|
+
</div>
|
|
2581
|
+
}
|
|
2582
|
+
<!-- Single fixed-user step: show who is assigned -->
|
|
2583
|
+
@if (!stepLoadingCandidates[i] && stepCandidates[i]?.length === 1) {
|
|
2584
|
+
<div class="arv-step-fixed">
|
|
2585
|
+
{{ stepCandidates[i][0].fullName || stepCandidates[i][0].userId }}{{ stepCandidates[i][0].department ? ' · ' + stepCandidates[i][0].department : '' }}{{ stepCandidates[i][0].position ? ' (' + stepCandidates[i][0].position + ')' : '' }}
|
|
2586
|
+
</div>
|
|
2587
|
+
}
|
|
2588
|
+
</div>
|
|
2589
|
+
}
|
|
2590
|
+
@if (selectedTemplate.referenceUserIds.length > 0) {
|
|
2591
|
+
<div class="arv-step-preview arv-step-preview-cc">
|
|
2592
|
+
<span class="arv-step-preview-num">CC</span>
|
|
2593
|
+
<span class="arv-step-preview-name">{{ selectedTemplate.referenceUserIds.length }} reference user(s) from template</span>
|
|
2594
|
+
</div>
|
|
2595
|
+
}
|
|
2596
|
+
</div>
|
|
2597
|
+
}
|
|
2598
|
+
</div>
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
<!-- Ad-hoc steps -->
|
|
2602
|
+
@if (routingMode === 'adhoc') {
|
|
2603
|
+
<div class="arv-steps">
|
|
2604
|
+
@for (step of adHocSteps; track step.stepOrder; let i = $index) {
|
|
2605
|
+
<div class="arv-step">
|
|
2606
|
+
<div class="arv-step-header">
|
|
2607
|
+
<span class="arv-step-num">Step {{ i + 1 }}</span>
|
|
2608
|
+
<input class="arv-input" [value]="step.stepName" (input)="step.stepName = $any($event.target).value" placeholder="Step name" />
|
|
2609
|
+
<button class="arv-btn-icon arv-btn-danger" (click)="removeStep(i)" title="Remove step">
|
|
2610
|
+
<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>
|
|
2611
|
+
</button>
|
|
2612
|
+
</div>
|
|
2613
|
+
<div class="arv-approvers">
|
|
2614
|
+
<div class="arv-approver-tags">
|
|
2615
|
+
@for (uid of step.approverUserIds; track uid; let j = $index) {
|
|
2616
|
+
<span class="arv-tag">
|
|
2617
|
+
{{ userLabelMap[uid] || uid }}
|
|
2618
|
+
<button class="arv-tag-remove" (click)="removeApprover(i, j)">x</button>
|
|
2619
|
+
</span>
|
|
2620
|
+
}
|
|
2621
|
+
</div>
|
|
2622
|
+
<div class="arv-user-search">
|
|
2623
|
+
<input class="arv-input arv-input-sm" [value]="userSearchQuery[i] || ''"
|
|
2624
|
+
(input)="onUserSearchInput(i, $any($event.target).value)"
|
|
2625
|
+
placeholder="Search approver..." />
|
|
2626
|
+
@if (userSearchResults[i]?.length) {
|
|
2627
|
+
<div class="arv-search-results">
|
|
2628
|
+
@for (u of userSearchResults[i]; track u.id) {
|
|
2629
|
+
<div class="arv-search-item" (click)="addApprover(i, u.id)">
|
|
2630
|
+
{{ u.fullName || u.userName }}
|
|
2631
|
+
</div>
|
|
2632
|
+
}
|
|
2633
|
+
</div>
|
|
2634
|
+
}
|
|
2635
|
+
</div>
|
|
2636
|
+
</div>
|
|
2637
|
+
</div>
|
|
2638
|
+
}
|
|
2639
|
+
<button class="arv-btn arv-btn-outline" (click)="addStep()">+ Add Step</button>
|
|
2640
|
+
</div>
|
|
2641
|
+
}
|
|
2565
2642
|
</div>
|
|
2566
2643
|
|
|
2567
|
-
<!--
|
|
2568
|
-
<div
|
|
2569
|
-
<
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
<
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
<div class="arv-
|
|
2585
|
-
|
|
2586
|
-
(
|
|
2587
|
-
placeholder="Search approver..." />
|
|
2588
|
-
<div class="arv-search-results" *ngIf="userSearchResults[i]?.length">
|
|
2589
|
-
<div class="arv-search-item"
|
|
2590
|
-
*ngFor="let u of userSearchResults[i]"
|
|
2591
|
-
(click)="addApprover(i, u.id)">
|
|
2644
|
+
<!-- Reference / CC users -->
|
|
2645
|
+
<div class="arv-references">
|
|
2646
|
+
<h4 class="arv-section-title">CC / Reference</h4>
|
|
2647
|
+
<p class="arv-hint">These users will be notified when the approval completes, but won't be asked to approve.</p>
|
|
2648
|
+
<div class="arv-approver-tags">
|
|
2649
|
+
@for (uid of referenceUserIds; track uid; let j = $index) {
|
|
2650
|
+
<span class="arv-tag">
|
|
2651
|
+
{{ userLabelMap[uid] || uid }}
|
|
2652
|
+
<button class="arv-tag-remove" (click)="removeReference(j)">x</button>
|
|
2653
|
+
</span>
|
|
2654
|
+
}
|
|
2655
|
+
</div>
|
|
2656
|
+
<div class="arv-user-search">
|
|
2657
|
+
<input class="arv-input arv-input-sm" [value]="refSearchQuery"
|
|
2658
|
+
(input)="onRefSearchInput($any($event.target).value)"
|
|
2659
|
+
placeholder="Search CC user..." />
|
|
2660
|
+
@if (refSearchResults?.length) {
|
|
2661
|
+
<div class="arv-search-results">
|
|
2662
|
+
@for (u of refSearchResults; track u.id) {
|
|
2663
|
+
<div class="arv-search-item" (click)="addReference(u.id)">
|
|
2592
2664
|
{{ u.fullName || u.userName }}
|
|
2593
2665
|
</div>
|
|
2594
|
-
|
|
2666
|
+
}
|
|
2595
2667
|
</div>
|
|
2596
|
-
|
|
2668
|
+
}
|
|
2597
2669
|
</div>
|
|
2598
|
-
<button class="arv-btn arv-btn-outline" (click)="addStep()">+ Add Step</button>
|
|
2599
2670
|
</div>
|
|
2600
|
-
</div>
|
|
2601
2671
|
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
</
|
|
2611
|
-
</div>
|
|
2612
|
-
<div class="arv-user-search">
|
|
2613
|
-
<input class="arv-input arv-input-sm" [value]="refSearchQuery"
|
|
2614
|
-
(input)="onRefSearchInput($any($event.target).value)"
|
|
2615
|
-
placeholder="Search CC user..." />
|
|
2616
|
-
<div class="arv-search-results" *ngIf="refSearchResults?.length">
|
|
2617
|
-
<div class="arv-search-item"
|
|
2618
|
-
*ngFor="let u of refSearchResults"
|
|
2619
|
-
(click)="addReference(u.id)">
|
|
2620
|
-
{{ u.fullName || u.userName }}
|
|
2621
|
-
</div>
|
|
2622
|
-
</div>
|
|
2672
|
+
<!-- Actions -->
|
|
2673
|
+
<div class="arv-actions">
|
|
2674
|
+
<button class="arv-btn arv-btn-secondary" (click)="onCancel()">Cancel</button>
|
|
2675
|
+
<button class="arv-btn arv-btn-primary" [disabled]="submitting" (click)="submit()">
|
|
2676
|
+
@if (submitting) {
|
|
2677
|
+
<span class="arv-spinner"></span>
|
|
2678
|
+
}
|
|
2679
|
+
{{ submitting ? 'Submitting...' : 'Submit for Approval' }}
|
|
2680
|
+
</button>
|
|
2623
2681
|
</div>
|
|
2624
|
-
</div>
|
|
2625
2682
|
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
<button class="arv-btn arv-btn-primary" [disabled]="submitting" (click)="submit()">
|
|
2630
|
-
<span *ngIf="submitting" class="arv-spinner"></span>
|
|
2631
|
-
{{ submitting ? 'Submitting...' : 'Submit for Approval' }}
|
|
2632
|
-
</button>
|
|
2683
|
+
@if (errorMessage) {
|
|
2684
|
+
<div class="arv-error">{{ errorMessage }}</div>
|
|
2685
|
+
}
|
|
2633
2686
|
</div>
|
|
2634
|
-
|
|
2635
|
-
<div class="arv-error" *ngIf="errorMessage">{{ errorMessage }}</div>
|
|
2636
|
-
</div>
|
|
2687
|
+
}
|
|
2637
2688
|
</div>
|
|
2638
2689
|
|
|
2639
2690
|
<!-- Success state -->
|
|
2640
|
-
|
|
2641
|
-
<
|
|
2642
|
-
<
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2691
|
+
@if (isSubmitted) {
|
|
2692
|
+
<div class="arv-success">
|
|
2693
|
+
<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">
|
|
2694
|
+
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
|
|
2695
|
+
<polyline points="22 4 12 14.01 9 11.01"/>
|
|
2696
|
+
</svg>
|
|
2697
|
+
<p>Submitted for approval successfully.</p>
|
|
2698
|
+
</div>
|
|
2699
|
+
}
|
|
2647
2700
|
</div>
|
|
2648
|
-
`, isInline: true, styles: [":host{display:block;--arv-primary: #90caf9;--arv-primary-hover: #64b5f6;--arv-success: #66bb6a;--arv-danger: #ef5350;--arv-text: #e0e0e0;--arv-text-muted: #9e9e9e;--arv-bg: #1e1e2e;--arv-bg2: #27273a;--arv-border: #383850;--arv-radius: 8px}:host(.theme-light){--arv-primary: #1565c0;--arv-primary-hover: #0d47a1;--arv-success: #2e7d32;--arv-danger: #c62828;--arv-text: #212121;--arv-text-muted: #616161;--arv-bg: #ffffff;--arv-bg2: #f5f5f5;--arv-border: #e0e0e0}.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-select{width:100%;padding:8px 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{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:4px}.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-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-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:8px 10px}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"]
|
|
2701
|
+
`, isInline: true, styles: [":host{display:block;--arv-primary: #90caf9;--arv-primary-hover: #64b5f6;--arv-success: #66bb6a;--arv-danger: #ef5350;--arv-text: #e0e0e0;--arv-text-muted: #9e9e9e;--arv-bg: #1e1e2e;--arv-bg2: #27273a;--arv-border: #383850;--arv-radius: 8px}:host(.theme-light){--arv-primary: #1565c0;--arv-primary-hover: #0d47a1;--arv-success: #2e7d32;--arv-danger: #c62828;--arv-text: #212121;--arv-text-muted: #616161;--arv-bg: #ffffff;--arv-bg2: #f5f5f5;--arv-border: #e0e0e0}.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-select{width:100%;padding:8px 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{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:4px}.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-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-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:8px 10px}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"] });
|
|
2649
2702
|
}
|
|
2650
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2703
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: MaArvContainerComponent, decorators: [{
|
|
2651
2704
|
type: Component,
|
|
2652
|
-
args: [{ selector: 'ma-arv-container', standalone: true,
|
|
2653
|
-
|
|
2705
|
+
args: [{ selector: 'ma-arv-container', standalone: true, template: `
|
|
2706
|
+
<div class="arv-container">
|
|
2654
2707
|
<!-- Content Area -->
|
|
2655
2708
|
<div class="arv-content-body" #contentBody>
|
|
2656
2709
|
<ng-content></ng-content>
|
|
2657
2710
|
</div>
|
|
2658
2711
|
|
|
2659
2712
|
<!-- Approval Footer -->
|
|
2660
|
-
<div class="arv-footer"
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
<div class="arv-routing
|
|
2666
|
-
<
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
<
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
<div *ngIf="templateId && routingMode === 'template'" class="arv-template-select">
|
|
2680
|
-
<div *ngIf="loadingTemplate" class="arv-template-loading">Loading template...</div>
|
|
2681
|
-
<div *ngIf="selectedTemplate && !loadingTemplate" class="arv-locked-template">
|
|
2682
|
-
<span class="arv-locked-label">Template</span>
|
|
2683
|
-
<span class="arv-locked-name">{{ selectedTemplate.name }}</span>
|
|
2713
|
+
<div class="arv-footer">
|
|
2714
|
+
@if (!isSubmitted) {
|
|
2715
|
+
<div class="arv-footer-inner">
|
|
2716
|
+
|
|
2717
|
+
<!-- Routing mode -->
|
|
2718
|
+
<div class="arv-routing">
|
|
2719
|
+
<div class="arv-routing-header">
|
|
2720
|
+
<h4 class="arv-section-title">Approval Routing</h4>
|
|
2721
|
+
<!-- Show routing toggle only when templateId is NOT locked to a single template -->
|
|
2722
|
+
@if (!templateId || (templateIds && templateIds.length > 0)) {
|
|
2723
|
+
<div class="arv-routing-mode">
|
|
2724
|
+
<label class="arv-radio">
|
|
2725
|
+
<input type="radio" name="routingMode" value="template" [checked]="routingMode === 'template'" (change)="routingMode = 'template'"> Use Template
|
|
2726
|
+
</label>
|
|
2727
|
+
<label class="arv-radio">
|
|
2728
|
+
<input type="radio" name="routingMode" value="adhoc" [checked]="routingMode === 'adhoc'" (change)="routingMode = 'adhoc'"> Custom Steps
|
|
2729
|
+
</label>
|
|
2730
|
+
</div>
|
|
2731
|
+
}
|
|
2684
2732
|
</div>
|
|
2685
|
-
</div>
|
|
2686
2733
|
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
<div class="arv-step-card" *ngFor="let s of selectedTemplate.steps; let i = index">
|
|
2700
|
-
<div class="arv-step-card-header">
|
|
2701
|
-
<span class="arv-step-preview-num">Step {{ s.stepOrder }}</span>
|
|
2702
|
-
<span class="arv-step-preview-name">{{ s.stepName }}</span>
|
|
2703
|
-
<span *ngIf="s.roles && s.roles.length > 0" class="arv-step-role-badge">
|
|
2704
|
-
{{ s.roles[0].positionLevel }}{{ s.roles[0].orgName ? ' · ' + s.roles[0].orgName : '' }}
|
|
2705
|
-
</span>
|
|
2706
|
-
</div>
|
|
2707
|
-
<!-- Selectable step (role-based or multi-assignee): show approver picker -->
|
|
2708
|
-
<div *ngIf="stepCandidates[i]?.length > 1 || stepLoadingCandidates[i]" class="arv-step-picker">
|
|
2709
|
-
<div *ngIf="stepLoadingCandidates[i]" class="arv-template-loading">Loading candidates...</div>
|
|
2710
|
-
<select *ngIf="!stepLoadingCandidates[i]" class="arv-select arv-select-sm"
|
|
2711
|
-
(change)="onStepUserChange(i, $event)">
|
|
2712
|
-
<option value="">-- Select approver --</option>
|
|
2713
|
-
<option *ngFor="let u of stepCandidates[i]" [value]="u.userId"
|
|
2714
|
-
[selected]="u.userId === stepSelectedUsers[i]">
|
|
2715
|
-
{{ u.fullName || u.userId }}{{ u.department ? ' · ' + u.department : '' }}{{ u.position ? ' (' + u.position + ')' : '' }}
|
|
2716
|
-
</option>
|
|
2717
|
-
</select>
|
|
2718
|
-
</div>
|
|
2719
|
-
<!-- Single fixed-user step: show who is assigned -->
|
|
2720
|
-
<div *ngIf="!stepLoadingCandidates[i] && stepCandidates[i]?.length === 1" class="arv-step-fixed">
|
|
2721
|
-
{{ stepCandidates[i][0].fullName || stepCandidates[i][0].userId }}{{ stepCandidates[i][0].department ? ' · ' + stepCandidates[i][0].department : '' }}{{ stepCandidates[i][0].position ? ' (' + stepCandidates[i][0].position + ')' : '' }}
|
|
2722
|
-
</div>
|
|
2734
|
+
<!-- Locked template: only when templateId set and no multi-choice -->
|
|
2735
|
+
@if (templateId && (!templateIds || templateIds.length <= 1) && routingMode === 'template') {
|
|
2736
|
+
<div class="arv-template-select">
|
|
2737
|
+
@if (loadingTemplate) {
|
|
2738
|
+
<div class="arv-template-loading">Loading template...</div>
|
|
2739
|
+
}
|
|
2740
|
+
@if (selectedTemplate && !loadingTemplate) {
|
|
2741
|
+
<div class="arv-locked-template">
|
|
2742
|
+
<span class="arv-locked-label">Template</span>
|
|
2743
|
+
<span class="arv-locked-name">{{ selectedTemplate.name }}</span>
|
|
2744
|
+
</div>
|
|
2745
|
+
}
|
|
2723
2746
|
</div>
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
<!-- Template selector: shown when no templateId, OR when templateIds has multiple choices -->
|
|
2750
|
+
@if ((!templateId || (templateIds && templateIds.length > 1)) && routingMode === 'template') {
|
|
2751
|
+
<div class="arv-template-select">
|
|
2752
|
+
<label class="arv-label">Select Template</label>
|
|
2753
|
+
<select class="arv-select" (change)="onTemplateChange($event)">
|
|
2754
|
+
<option value="">-- Select a template --</option>
|
|
2755
|
+
@for (t of templates; track t.id) {
|
|
2756
|
+
<option [value]="t.id" [selected]="t.id === selectedTemplateId">{{ t.name }}</option>
|
|
2757
|
+
}
|
|
2758
|
+
</select>
|
|
2727
2759
|
</div>
|
|
2728
|
-
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
<!-- Step pickers (shared for both locked and free template) -->
|
|
2763
|
+
@if (routingMode === 'template') {
|
|
2764
|
+
<div class="arv-template-select">
|
|
2765
|
+
@if (!loadingTemplate && selectedTemplate) {
|
|
2766
|
+
<div class="arv-template-steps">
|
|
2767
|
+
@for (s of selectedTemplate.steps; track s.stepOrder; let i = $index) {
|
|
2768
|
+
<div class="arv-step-card">
|
|
2769
|
+
<div class="arv-step-card-header">
|
|
2770
|
+
<span class="arv-step-preview-num">Step {{ s.stepOrder }}</span>
|
|
2771
|
+
<span class="arv-step-preview-name">{{ s.stepName }}</span>
|
|
2772
|
+
@if (s.roles && s.roles.length > 0) {
|
|
2773
|
+
<span class="arv-step-role-badge">
|
|
2774
|
+
{{ s.roles[0].positionLevel }}{{ s.roles[0].orgName ? ' · ' + s.roles[0].orgName : '' }}
|
|
2775
|
+
</span>
|
|
2776
|
+
}
|
|
2777
|
+
</div>
|
|
2778
|
+
<!-- Selectable step: show approver picker -->
|
|
2779
|
+
@if (stepCandidates[i]?.length > 1 || stepLoadingCandidates[i]) {
|
|
2780
|
+
<div class="arv-step-picker">
|
|
2781
|
+
@if (stepLoadingCandidates[i]) {
|
|
2782
|
+
<div class="arv-template-loading">Loading candidates...</div>
|
|
2783
|
+
}
|
|
2784
|
+
@if (!stepLoadingCandidates[i]) {
|
|
2785
|
+
<select class="arv-select arv-select-sm" (change)="onStepUserChange(i, $event)">
|
|
2786
|
+
<option value="">-- Select approver --</option>
|
|
2787
|
+
@for (u of stepCandidates[i]; track u.userId) {
|
|
2788
|
+
<option [value]="u.userId" [selected]="u.userId === stepSelectedUsers[i]">
|
|
2789
|
+
{{ u.fullName || u.userId }}{{ u.department ? ' · ' + u.department : '' }}{{ u.position ? ' (' + u.position + ')' : '' }}
|
|
2790
|
+
</option>
|
|
2791
|
+
}
|
|
2792
|
+
</select>
|
|
2793
|
+
}
|
|
2794
|
+
</div>
|
|
2795
|
+
}
|
|
2796
|
+
<!-- Single fixed-user step: show who is assigned -->
|
|
2797
|
+
@if (!stepLoadingCandidates[i] && stepCandidates[i]?.length === 1) {
|
|
2798
|
+
<div class="arv-step-fixed">
|
|
2799
|
+
{{ stepCandidates[i][0].fullName || stepCandidates[i][0].userId }}{{ stepCandidates[i][0].department ? ' · ' + stepCandidates[i][0].department : '' }}{{ stepCandidates[i][0].position ? ' (' + stepCandidates[i][0].position + ')' : '' }}
|
|
2800
|
+
</div>
|
|
2801
|
+
}
|
|
2802
|
+
</div>
|
|
2803
|
+
}
|
|
2804
|
+
@if (selectedTemplate.referenceUserIds.length > 0) {
|
|
2805
|
+
<div class="arv-step-preview arv-step-preview-cc">
|
|
2806
|
+
<span class="arv-step-preview-num">CC</span>
|
|
2807
|
+
<span class="arv-step-preview-name">{{ selectedTemplate.referenceUserIds.length }} reference user(s) from template</span>
|
|
2808
|
+
</div>
|
|
2809
|
+
}
|
|
2810
|
+
</div>
|
|
2811
|
+
}
|
|
2812
|
+
</div>
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
<!-- Ad-hoc steps -->
|
|
2816
|
+
@if (routingMode === 'adhoc') {
|
|
2817
|
+
<div class="arv-steps">
|
|
2818
|
+
@for (step of adHocSteps; track step.stepOrder; let i = $index) {
|
|
2819
|
+
<div class="arv-step">
|
|
2820
|
+
<div class="arv-step-header">
|
|
2821
|
+
<span class="arv-step-num">Step {{ i + 1 }}</span>
|
|
2822
|
+
<input class="arv-input" [value]="step.stepName" (input)="step.stepName = $any($event.target).value" placeholder="Step name" />
|
|
2823
|
+
<button class="arv-btn-icon arv-btn-danger" (click)="removeStep(i)" title="Remove step">
|
|
2824
|
+
<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>
|
|
2825
|
+
</button>
|
|
2826
|
+
</div>
|
|
2827
|
+
<div class="arv-approvers">
|
|
2828
|
+
<div class="arv-approver-tags">
|
|
2829
|
+
@for (uid of step.approverUserIds; track uid; let j = $index) {
|
|
2830
|
+
<span class="arv-tag">
|
|
2831
|
+
{{ userLabelMap[uid] || uid }}
|
|
2832
|
+
<button class="arv-tag-remove" (click)="removeApprover(i, j)">x</button>
|
|
2833
|
+
</span>
|
|
2834
|
+
}
|
|
2835
|
+
</div>
|
|
2836
|
+
<div class="arv-user-search">
|
|
2837
|
+
<input class="arv-input arv-input-sm" [value]="userSearchQuery[i] || ''"
|
|
2838
|
+
(input)="onUserSearchInput(i, $any($event.target).value)"
|
|
2839
|
+
placeholder="Search approver..." />
|
|
2840
|
+
@if (userSearchResults[i]?.length) {
|
|
2841
|
+
<div class="arv-search-results">
|
|
2842
|
+
@for (u of userSearchResults[i]; track u.id) {
|
|
2843
|
+
<div class="arv-search-item" (click)="addApprover(i, u.id)">
|
|
2844
|
+
{{ u.fullName || u.userName }}
|
|
2845
|
+
</div>
|
|
2846
|
+
}
|
|
2847
|
+
</div>
|
|
2848
|
+
}
|
|
2849
|
+
</div>
|
|
2850
|
+
</div>
|
|
2851
|
+
</div>
|
|
2852
|
+
}
|
|
2853
|
+
<button class="arv-btn arv-btn-outline" (click)="addStep()">+ Add Step</button>
|
|
2854
|
+
</div>
|
|
2855
|
+
}
|
|
2729
2856
|
</div>
|
|
2730
2857
|
|
|
2731
|
-
<!--
|
|
2732
|
-
<div
|
|
2733
|
-
<
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
<
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
<div class="arv-
|
|
2749
|
-
|
|
2750
|
-
(
|
|
2751
|
-
placeholder="Search approver..." />
|
|
2752
|
-
<div class="arv-search-results" *ngIf="userSearchResults[i]?.length">
|
|
2753
|
-
<div class="arv-search-item"
|
|
2754
|
-
*ngFor="let u of userSearchResults[i]"
|
|
2755
|
-
(click)="addApprover(i, u.id)">
|
|
2858
|
+
<!-- Reference / CC users -->
|
|
2859
|
+
<div class="arv-references">
|
|
2860
|
+
<h4 class="arv-section-title">CC / Reference</h4>
|
|
2861
|
+
<p class="arv-hint">These users will be notified when the approval completes, but won't be asked to approve.</p>
|
|
2862
|
+
<div class="arv-approver-tags">
|
|
2863
|
+
@for (uid of referenceUserIds; track uid; let j = $index) {
|
|
2864
|
+
<span class="arv-tag">
|
|
2865
|
+
{{ userLabelMap[uid] || uid }}
|
|
2866
|
+
<button class="arv-tag-remove" (click)="removeReference(j)">x</button>
|
|
2867
|
+
</span>
|
|
2868
|
+
}
|
|
2869
|
+
</div>
|
|
2870
|
+
<div class="arv-user-search">
|
|
2871
|
+
<input class="arv-input arv-input-sm" [value]="refSearchQuery"
|
|
2872
|
+
(input)="onRefSearchInput($any($event.target).value)"
|
|
2873
|
+
placeholder="Search CC user..." />
|
|
2874
|
+
@if (refSearchResults?.length) {
|
|
2875
|
+
<div class="arv-search-results">
|
|
2876
|
+
@for (u of refSearchResults; track u.id) {
|
|
2877
|
+
<div class="arv-search-item" (click)="addReference(u.id)">
|
|
2756
2878
|
{{ u.fullName || u.userName }}
|
|
2757
2879
|
</div>
|
|
2758
|
-
|
|
2880
|
+
}
|
|
2759
2881
|
</div>
|
|
2760
|
-
|
|
2882
|
+
}
|
|
2761
2883
|
</div>
|
|
2762
|
-
<button class="arv-btn arv-btn-outline" (click)="addStep()">+ Add Step</button>
|
|
2763
2884
|
</div>
|
|
2764
|
-
</div>
|
|
2765
2885
|
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
</
|
|
2775
|
-
</div>
|
|
2776
|
-
<div class="arv-user-search">
|
|
2777
|
-
<input class="arv-input arv-input-sm" [value]="refSearchQuery"
|
|
2778
|
-
(input)="onRefSearchInput($any($event.target).value)"
|
|
2779
|
-
placeholder="Search CC user..." />
|
|
2780
|
-
<div class="arv-search-results" *ngIf="refSearchResults?.length">
|
|
2781
|
-
<div class="arv-search-item"
|
|
2782
|
-
*ngFor="let u of refSearchResults"
|
|
2783
|
-
(click)="addReference(u.id)">
|
|
2784
|
-
{{ u.fullName || u.userName }}
|
|
2785
|
-
</div>
|
|
2786
|
-
</div>
|
|
2886
|
+
<!-- Actions -->
|
|
2887
|
+
<div class="arv-actions">
|
|
2888
|
+
<button class="arv-btn arv-btn-secondary" (click)="onCancel()">Cancel</button>
|
|
2889
|
+
<button class="arv-btn arv-btn-primary" [disabled]="submitting" (click)="submit()">
|
|
2890
|
+
@if (submitting) {
|
|
2891
|
+
<span class="arv-spinner"></span>
|
|
2892
|
+
}
|
|
2893
|
+
{{ submitting ? 'Submitting...' : 'Submit for Approval' }}
|
|
2894
|
+
</button>
|
|
2787
2895
|
</div>
|
|
2788
|
-
</div>
|
|
2789
2896
|
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
<button class="arv-btn arv-btn-primary" [disabled]="submitting" (click)="submit()">
|
|
2794
|
-
<span *ngIf="submitting" class="arv-spinner"></span>
|
|
2795
|
-
{{ submitting ? 'Submitting...' : 'Submit for Approval' }}
|
|
2796
|
-
</button>
|
|
2897
|
+
@if (errorMessage) {
|
|
2898
|
+
<div class="arv-error">{{ errorMessage }}</div>
|
|
2899
|
+
}
|
|
2797
2900
|
</div>
|
|
2798
|
-
|
|
2799
|
-
<div class="arv-error" *ngIf="errorMessage">{{ errorMessage }}</div>
|
|
2800
|
-
</div>
|
|
2901
|
+
}
|
|
2801
2902
|
</div>
|
|
2802
2903
|
|
|
2803
2904
|
<!-- Success state -->
|
|
2804
|
-
|
|
2805
|
-
<
|
|
2806
|
-
<
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2905
|
+
@if (isSubmitted) {
|
|
2906
|
+
<div class="arv-success">
|
|
2907
|
+
<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">
|
|
2908
|
+
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
|
|
2909
|
+
<polyline points="22 4 12 14.01 9 11.01"/>
|
|
2910
|
+
</svg>
|
|
2911
|
+
<p>Submitted for approval successfully.</p>
|
|
2912
|
+
</div>
|
|
2913
|
+
}
|
|
2811
2914
|
</div>
|
|
2812
2915
|
`, styles: [":host{display:block;--arv-primary: #90caf9;--arv-primary-hover: #64b5f6;--arv-success: #66bb6a;--arv-danger: #ef5350;--arv-text: #e0e0e0;--arv-text-muted: #9e9e9e;--arv-bg: #1e1e2e;--arv-bg2: #27273a;--arv-border: #383850;--arv-radius: 8px}:host(.theme-light){--arv-primary: #1565c0;--arv-primary-hover: #0d47a1;--arv-success: #2e7d32;--arv-danger: #c62828;--arv-text: #212121;--arv-text-muted: #616161;--arv-bg: #ffffff;--arv-bg2: #f5f5f5;--arv-border: #e0e0e0}.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-select{width:100%;padding:8px 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{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:4px}.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-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-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:8px 10px}.arv-select-sm{font-size:12px;padding:6px 8px}.arv-step-fixed{padding:6px 10px;font-size:12px;color:var(--arv-text-muted)}\n"] }]
|
|
2813
2916
|
}], propDecorators: { title: [{
|
|
@@ -2818,6 +2921,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
2818
2921
|
type: Input
|
|
2819
2922
|
}], templateId: [{
|
|
2820
2923
|
type: Input
|
|
2924
|
+
}], templateIds: [{
|
|
2925
|
+
type: Input
|
|
2821
2926
|
}], callbackUrl: [{
|
|
2822
2927
|
type: Input
|
|
2823
2928
|
}], deadlineHours: [{
|