@foxeltech/angular-ui 0.3.0 → 0.4.0
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.
- package/fesm2022/foxeltech-angular-ui-chart.mjs +392 -0
- package/fesm2022/foxeltech-angular-ui-chart.mjs.map +1 -0
- package/fesm2022/foxeltech-angular-ui-flow.mjs +38 -0
- package/fesm2022/foxeltech-angular-ui-flow.mjs.map +1 -0
- package/fesm2022/foxeltech-angular-ui-rich-text.mjs +156 -0
- package/fesm2022/foxeltech-angular-ui-rich-text.mjs.map +1 -0
- package/fesm2022/foxeltech-angular-ui.mjs +890 -1499
- package/fesm2022/foxeltech-angular-ui.mjs.map +1 -1
- package/fx-icons.svg +97 -0
- package/package.json +23 -16
- package/src/lib/styles/tailwind.css +0 -1
- package/src/lib/ui/components/button/button.component.html +14 -14
- package/src/lib/ui/components/checkbox/checkbox.component.html +2 -2
- package/src/lib/ui/components/circle-progress-bar/circle-progress-bar.component.html +2 -2
- package/src/lib/ui/components/datetime-picker/datetime-picker.component.html +54 -28
- package/src/lib/ui/components/datetime-picker/datetime-picker.component.scss +25 -137
- package/src/lib/ui/components/dnd-upload/dnd-upload.component.html +3 -3
- package/src/lib/ui/components/drawer/drawer.component.html +75 -61
- package/src/lib/ui/components/empty-state/empty-state.component.html +2 -2
- package/src/lib/ui/components/hero-icon/hero-icon.component.html +10 -9
- package/src/lib/ui/components/info-field/info-field.component.html +1 -1
- package/src/lib/ui/components/input/input.component.html +6 -6
- package/src/lib/ui/components/kanban-board/kanban-board.component.html +1 -1
- package/src/lib/ui/components/loading-panel/loading-panel.component.html +53 -53
- package/src/lib/ui/components/master-detail/master-detail.component.html +9 -9
- package/src/lib/ui/components/menu/menu.component.html +27 -0
- package/src/lib/ui/components/radio-button/radio-button.component.html +26 -26
- package/src/lib/ui/components/radio-button-toggle/radio-button-toggle.component.html +3 -3
- package/src/lib/ui/components/search-bar/search-bar.component.html +12 -11
- package/src/lib/ui/components/section-card/section-card.component.html +1 -1
- package/src/lib/ui/components/select/select.component.html +14 -12
- package/src/lib/ui/components/skeleton-detail/skeleton-detail.component.html +2 -2
- package/src/lib/ui/components/skeleton-list/skeleton-list.component.html +1 -1
- package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.html +5 -5
- package/src/lib/ui/components/slider/slider.component.html +22 -20
- package/src/lib/ui/components/stat-cards/stat-cards.component.html +1 -1
- package/src/lib/ui/components/switch/switch.component.html +1 -1
- package/src/lib/ui/components/tab-group/tab-group.component.html +35 -32
- package/src/lib/ui/components/table-cell/table-cell.component.html +2 -2
- package/src/lib/ui/components/tag/tag.component.html +4 -4
- package/src/lib/ui/components/toast/toast.component.html +42 -40
- package/src/lib/ui/components/toast-container/toast-container.component.html +1 -0
- package/src/lib/ui/components/tree-diagram/tree-diagram.component.html +22 -20
- package/tailwind.css +0 -1
- package/types/foxeltech-angular-ui-chart.d.ts +53 -0
- package/types/foxeltech-angular-ui-flow.d.ts +14 -0
- package/types/foxeltech-angular-ui-rich-text.d.ts +35 -0
- package/{index.d.ts → types/foxeltech-angular-ui.d.ts} +394 -387
- package/src/lib/ui/components/chart/chart.component.html +0 -20
- package/src/lib/ui/components/chart/chart.component.scss +0 -49
- package/src/lib/ui/components/flow-connection/flow-connection.component.html +0 -10
- package/src/lib/ui/components/flow-connection/flow-connection.component.scss +0 -0
- package/src/lib/ui/components/rich-text-area/rich-text-area.component.html +0 -3
- package/src/lib/ui/components/rich-text-area/rich-text-area.component.scss +0 -18
|
@@ -1,68 +1,35 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, DestroyRef, Injector, Directive,
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import { MatTableDataSource, MatTable, MatTableModule } from '@angular/material/table';
|
|
7
|
-
import * as i1$1 from '@angular/common';
|
|
8
|
-
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
9
|
-
import * as i1 from '@dimaslz/ng-heroicons';
|
|
10
|
-
import { NgHeroiconsModule } from '@dimaslz/ng-heroicons';
|
|
11
|
-
import _, { clamp } from 'lodash';
|
|
2
|
+
import { inject, DestroyRef, Injector, Directive, InjectionToken, input, isDevMode, ChangeDetectionStrategy, Component, Input, createComponent, Injectable, viewChild, ViewChild, Inject, EventEmitter, NgModule, HostListener, output, ChangeDetectorRef, TemplateRef, contentChildren, Output, ViewChildren, contentChild } from '@angular/core';
|
|
3
|
+
import { MatPaginator } from '@angular/material/paginator';
|
|
4
|
+
import { MatTableDataSource, MatTable } from '@angular/material/table';
|
|
5
|
+
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
|
|
12
6
|
import { Observable, firstValueFrom, Subject, debounceTime, distinctUntilChanged, BehaviorSubject, throwError, filter, takeUntil } from 'rxjs';
|
|
13
|
-
import moment from 'moment';
|
|
14
7
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
15
8
|
import * as i2 from '@angular/common/http';
|
|
16
9
|
import { HttpRequest, HttpClient } from '@angular/common/http';
|
|
17
|
-
import * as i1
|
|
18
|
-
import { MAT_DIALOG_DATA,
|
|
19
|
-
import * as i1$
|
|
10
|
+
import * as i1 from '@angular/material/dialog';
|
|
11
|
+
import { MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialog } from '@angular/material/dialog';
|
|
12
|
+
import * as i1$1 from '@ngx-translate/core';
|
|
20
13
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
21
14
|
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
|
22
|
-
import * as
|
|
15
|
+
import * as i1$3 from '@angular/forms';
|
|
23
16
|
import { NgControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
24
|
-
import * as
|
|
25
|
-
import { NavigationEnd, RouterModule } from '@angular/router';
|
|
17
|
+
import * as i2$1 from '@angular/router';
|
|
18
|
+
import { NavigationEnd, RouterLink, RouterModule } from '@angular/router';
|
|
26
19
|
import { catchError } from 'rxjs/operators';
|
|
27
20
|
import * as signalR from '@microsoft/signalr';
|
|
28
|
-
import
|
|
29
|
-
import
|
|
30
|
-
import * as i42 from '@angular/material/radio';
|
|
31
|
-
import { MatRadioModule } from '@angular/material/radio';
|
|
32
|
-
import * as i43 from '@angular/material/button';
|
|
33
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
34
|
-
import * as i44 from '@angular/material/icon';
|
|
35
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
36
|
-
import * as i47 from '@angular/material/snack-bar';
|
|
37
|
-
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
38
|
-
import * as i49 from '@angular/material/checkbox';
|
|
39
|
-
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
40
|
-
import * as i50 from '@angular/material/card';
|
|
41
|
-
import { MatCardModule } from '@angular/material/card';
|
|
42
|
-
import * as i51 from '@angular/material/datepicker';
|
|
21
|
+
import { CdkScrollable } from '@angular/cdk/scrolling';
|
|
22
|
+
import * as i1$2 from '@angular/material/datepicker';
|
|
43
23
|
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
44
|
-
import * as
|
|
24
|
+
import * as i2$2 from '@angular/material/timepicker';
|
|
45
25
|
import { MatTimepickerModule } from '@angular/material/timepicker';
|
|
46
|
-
import
|
|
47
|
-
import {
|
|
48
|
-
import
|
|
49
|
-
import {
|
|
50
|
-
import
|
|
51
|
-
import
|
|
52
|
-
import * as i56 from '@angular/material/menu';
|
|
26
|
+
import { MAT_DATE_LOCALE, provideNativeDateAdapter } from '@angular/material/core';
|
|
27
|
+
import { MatTooltip } from '@angular/material/tooltip';
|
|
28
|
+
import { MatFormField, MatSelect, MatOption } from '@angular/material/select';
|
|
29
|
+
import { moveItemInArray, transferArrayItem, CdkDropList, CdkDrag, CdkDragPlaceholder } from '@angular/cdk/drag-drop';
|
|
30
|
+
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
31
|
+
import * as i1$4 from '@angular/material/menu';
|
|
53
32
|
import { MatMenuModule } from '@angular/material/menu';
|
|
54
|
-
import * as i57 from '@angular/material/tooltip';
|
|
55
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
56
|
-
import * as i2$3 from '@angular/cdk/drag-drop';
|
|
57
|
-
import { DragDropModule, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
|
|
58
|
-
import * as i2$2 from '@danielmoncada/angular-datetime-picker';
|
|
59
|
-
import { OwlDateTimeModule, OwlNativeDateTimeModule, OWL_DATE_TIME_FORMATS } from '@danielmoncada/angular-datetime-picker';
|
|
60
|
-
import * as i1$5 from 'ngx-echarts';
|
|
61
|
-
import { NgxEchartsModule } from 'ngx-echarts';
|
|
62
|
-
import * as i39 from 'ngx-vflow';
|
|
63
|
-
import { Vflow } from 'ngx-vflow';
|
|
64
|
-
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
65
|
-
import { OwlMomentDateTimeModule } from '@danielmoncada/angular-datetime-picker-moment-adapter';
|
|
66
33
|
|
|
67
34
|
class BaseComponent {
|
|
68
35
|
injector;
|
|
@@ -76,63 +43,79 @@ class BaseComponent {
|
|
|
76
43
|
}
|
|
77
44
|
// eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method -- subclasses across host apps call super.ngOnDestroy(); removing this breaks them at runtime
|
|
78
45
|
ngOnDestroy() { }
|
|
79
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
80
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
46
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive });
|
|
47
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: BaseComponent, isStandalone: true, ngImport: i0 });
|
|
81
48
|
}
|
|
82
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
49
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseComponent, decorators: [{
|
|
83
50
|
type: Directive
|
|
84
51
|
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
85
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Where the generated Heroicons sprite is served from. Defaults to
|
|
55
|
+
* 'fx-icons.svg' at the app base — consumers copy it from the package via an
|
|
56
|
+
* angular.json assets glob (same pattern as the lib fonts):
|
|
57
|
+
* { "input": "node_modules/@foxeltech/angular-ui", "glob": "fx-icons.svg", "output": "." }
|
|
58
|
+
*/
|
|
59
|
+
const FX_ICON_SPRITE_URL = new InjectionToken('FX_ICON_SPRITE_URL', {
|
|
60
|
+
providedIn: 'root',
|
|
61
|
+
factory: () => 'fx-icons.svg',
|
|
62
|
+
});
|
|
63
|
+
let spriteChecked = false;
|
|
64
|
+
/**
|
|
65
|
+
* Heroicons rendered from the self-hosted sprite (see
|
|
66
|
+
* scripts/generate-icon-sprite.mjs) — every 24px outline/solid icon is
|
|
67
|
+
* available by name with no per-icon registration and no runtime icon
|
|
68
|
+
* library. API kept compatible with the old @dimaslz/ng-heroicons wrapper.
|
|
69
|
+
*/
|
|
86
70
|
class HeroIconComponent {
|
|
87
|
-
stroke = 1.5;
|
|
88
|
-
icon;
|
|
89
|
-
solid;
|
|
90
|
-
outline;
|
|
91
|
-
size;
|
|
92
|
-
color;
|
|
93
|
-
class;
|
|
94
|
-
|
|
95
|
-
|
|
71
|
+
stroke = input(1.5, ...(ngDevMode ? [{ debugName: "stroke" }] : /* istanbul ignore next */ []));
|
|
72
|
+
icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
73
|
+
solid = input(...(ngDevMode ? [undefined, { debugName: "solid" }] : /* istanbul ignore next */ []));
|
|
74
|
+
outline = input(...(ngDevMode ? [undefined, { debugName: "outline" }] : /* istanbul ignore next */ []));
|
|
75
|
+
size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : /* istanbul ignore next */ []));
|
|
76
|
+
color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : /* istanbul ignore next */ []));
|
|
77
|
+
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : /* istanbul ignore next */ []));
|
|
78
|
+
spriteUrl = inject(FX_ICON_SPRITE_URL);
|
|
79
|
+
constructor() {
|
|
80
|
+
// One warning per app when the sprite asset was not copied — otherwise
|
|
81
|
+
// every icon just renders blank and nobody knows why.
|
|
82
|
+
if (isDevMode() && !spriteChecked && typeof fetch === 'function') {
|
|
83
|
+
spriteChecked = true;
|
|
84
|
+
fetch(this.spriteUrl, { method: 'HEAD' })
|
|
85
|
+
.then((r) => {
|
|
86
|
+
if (!r.ok)
|
|
87
|
+
throw new Error(String(r.status));
|
|
88
|
+
})
|
|
89
|
+
.catch(() => console.warn(`[fx-ui-hero-icon] Sprite '${this.spriteUrl}' not found — add the fx-icons.svg ` +
|
|
90
|
+
`assets glob from @foxeltech/angular-ui to angular.json (see FX_ICON_SPRITE_URL docs).`));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
get href() {
|
|
94
|
+
const name = this.solid() ? `${this.icon()}-solid` : this.icon();
|
|
95
|
+
return `${this.spriteUrl}#${name}`;
|
|
96
|
+
}
|
|
97
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HeroIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
98
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.20", type: HeroIconComponent, isStandalone: true, selector: "fx-ui-hero-icon", inputs: { stroke: { classPropertyName: "stroke", publicName: "stroke", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, solid: { classPropertyName: "solid", publicName: "solid", isSignal: true, isRequired: false, transformFunction: null }, outline: { classPropertyName: "outline", publicName: "outline", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<svg\n [attr.width]=\"size() || 24\"\n [attr.height]=\"size() || 24\"\n [attr.stroke-width]=\"solid() ? null : stroke()\"\n [style.color]=\"color() || null\"\n [class]=\"class()\"\n aria-hidden=\"true\"\n>\n <use [attr.href]=\"href\" />\n</svg>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
96
99
|
}
|
|
97
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HeroIconComponent, decorators: [{
|
|
98
101
|
type: Component,
|
|
99
|
-
args: [{ selector: 'fx-ui-hero-icon',
|
|
100
|
-
}], propDecorators: { stroke: [{
|
|
101
|
-
type: Input
|
|
102
|
-
}], icon: [{
|
|
103
|
-
type: Input
|
|
104
|
-
}], solid: [{
|
|
105
|
-
type: Input
|
|
106
|
-
}], outline: [{
|
|
107
|
-
type: Input
|
|
108
|
-
}], size: [{
|
|
109
|
-
type: Input
|
|
110
|
-
}], color: [{
|
|
111
|
-
type: Input
|
|
112
|
-
}], class: [{
|
|
113
|
-
type: Input
|
|
114
|
-
}] } });
|
|
102
|
+
args: [{ selector: 'fx-ui-hero-icon', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg\n [attr.width]=\"size() || 24\"\n [attr.height]=\"size() || 24\"\n [attr.stroke-width]=\"solid() ? null : stroke()\"\n [style.color]=\"color() || null\"\n [class]=\"class()\"\n aria-hidden=\"true\"\n>\n <use [attr.href]=\"href\" />\n</svg>\n" }]
|
|
103
|
+
}], ctorParameters: () => [], propDecorators: { stroke: [{ type: i0.Input, args: [{ isSignal: true, alias: "stroke", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], solid: [{ type: i0.Input, args: [{ isSignal: true, alias: "solid", required: false }] }], outline: [{ type: i0.Input, args: [{ isSignal: true, alias: "outline", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
115
104
|
|
|
116
105
|
class ToastComponent {
|
|
117
|
-
toastId;
|
|
106
|
+
toastId = input.required(...(ngDevMode ? [{ debugName: "toastId" }] : /* istanbul ignore next */ []));
|
|
118
107
|
title = '';
|
|
119
|
-
message = '';
|
|
120
|
-
type;
|
|
121
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
122
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
108
|
+
message = input('', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
109
|
+
type = input(...(ngDevMode ? [undefined, { debugName: "type" }] : /* istanbul ignore next */ []));
|
|
110
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
111
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ToastComponent, isStandalone: true, selector: "fx-ui-toast", inputs: { toastId: { classPropertyName: "toastId", publicName: "toastId", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: false, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n animate.enter=\"horizontal-fade-in-animation\"\n animate.leave=\"horizontal-fade-out-animation\"\n [attr.role]=\"type() === 'error' ? 'alert' : 'status'\"\n class=\"flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0\"\n [ngClass]=\"{\n 'border-success': type() === 'success',\n 'border-critical': type() === 'error',\n 'border-warning': type() === 'warning',\n 'border-information': type() === 'info'\n }\"\n >\n <div class=\"\" aria-hidden=\"true\">\n @switch (type()) { @case('success') {\n <fx-ui-hero-icon\n icon=\"check-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-success\"\n ></fx-ui-hero-icon>\n } @case('error') {\n <fx-ui-hero-icon\n icon=\"exclamation-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-critical\"\n ></fx-ui-hero-icon>\n } @case('warning') {\n <fx-ui-hero-icon\n icon=\"exclamation-triangle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-warning\"\n ></fx-ui-hero-icon>\n } @default {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-information\"\n ></fx-ui-hero-icon>\n } }\n </div>\n\n <div class=\"flex flex-col\">\n @if (title) {\n <strong class=\"txt-field-label\">{{ title }}</strong>\n }\n <p class=\"txt-default\">{{ message() }}</p>\n </div>\n </div>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
123
112
|
}
|
|
124
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
113
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastComponent, decorators: [{
|
|
125
114
|
type: Component,
|
|
126
|
-
args: [{ selector: 'fx-ui-toast',
|
|
127
|
-
}], propDecorators: { toastId: [{
|
|
128
|
-
type: Input
|
|
129
|
-
}], title: [{
|
|
115
|
+
args: [{ selector: 'fx-ui-toast', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, HeroIconComponent], template: "<div\n animate.enter=\"horizontal-fade-in-animation\"\n animate.leave=\"horizontal-fade-out-animation\"\n [attr.role]=\"type() === 'error' ? 'alert' : 'status'\"\n class=\"flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0\"\n [ngClass]=\"{\n 'border-success': type() === 'success',\n 'border-critical': type() === 'error',\n 'border-warning': type() === 'warning',\n 'border-information': type() === 'info'\n }\"\n >\n <div class=\"\" aria-hidden=\"true\">\n @switch (type()) { @case('success') {\n <fx-ui-hero-icon\n icon=\"check-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-success\"\n ></fx-ui-hero-icon>\n } @case('error') {\n <fx-ui-hero-icon\n icon=\"exclamation-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-critical\"\n ></fx-ui-hero-icon>\n } @case('warning') {\n <fx-ui-hero-icon\n icon=\"exclamation-triangle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-warning\"\n ></fx-ui-hero-icon>\n } @default {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-information\"\n ></fx-ui-hero-icon>\n } }\n </div>\n\n <div class=\"flex flex-col\">\n @if (title) {\n <strong class=\"txt-field-label\">{{ title }}</strong>\n }\n <p class=\"txt-default\">{{ message() }}</p>\n </div>\n </div>\n" }]
|
|
116
|
+
}], propDecorators: { toastId: [{ type: i0.Input, args: [{ isSignal: true, alias: "toastId", required: true }] }], title: [{
|
|
130
117
|
type: Input
|
|
131
|
-
}], message: [{
|
|
132
|
-
type: Input
|
|
133
|
-
}], type: [{
|
|
134
|
-
type: Input
|
|
135
|
-
}] } });
|
|
118
|
+
}], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }] } });
|
|
136
119
|
|
|
137
120
|
// import { ToastData } from '../../../../public-api';
|
|
138
121
|
class ToastContainerComponent {
|
|
@@ -150,12 +133,12 @@ class ToastContainerComponent {
|
|
|
150
133
|
this.toasts = this.toasts.filter(t => t.id !== id);
|
|
151
134
|
this.ref.detectChanges();
|
|
152
135
|
}
|
|
153
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
154
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
136
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastContainerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
137
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ToastContainerComponent, isStandalone: true, selector: "fx-ui-toast-container", ngImport: i0, template: "<div\n class=\"fixed top-5 right-5 flex flex-col items-end gap-3 z-[10000] pointer-events-none\"\n>\n @for (toast of toasts; track toast) {\n <fx-ui-toast\n class=\"pointer-events-auto\"\n [toastId]=\"toast.id\"\n [message]=\"toast.message\"\n [title]=\"toast.title\"\n [type]=\"toast.type\"\n ></fx-ui-toast>\n }\n</div>", styles: [""], dependencies: [{ kind: "component", type: ToastComponent, selector: "fx-ui-toast", inputs: ["toastId", "title", "message", "type"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
155
138
|
}
|
|
156
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
139
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastContainerComponent, decorators: [{
|
|
157
140
|
type: Component,
|
|
158
|
-
args: [{ selector: 'fx-ui-toast-container',
|
|
141
|
+
args: [{ selector: 'fx-ui-toast-container', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ToastComponent], template: "<div\n class=\"fixed top-5 right-5 flex flex-col items-end gap-3 z-[10000] pointer-events-none\"\n>\n @for (toast of toasts; track toast) {\n <fx-ui-toast\n class=\"pointer-events-auto\"\n [toastId]=\"toast.id\"\n [message]=\"toast.message\"\n [title]=\"toast.title\"\n [type]=\"toast.type\"\n ></fx-ui-toast>\n }\n</div>" }]
|
|
159
142
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
160
143
|
|
|
161
144
|
class FxToastrService {
|
|
@@ -203,10 +186,10 @@ class FxToastrService {
|
|
|
203
186
|
warning(message, title) {
|
|
204
187
|
this.show(message, 'warning', title);
|
|
205
188
|
}
|
|
206
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
207
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
189
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxToastrService, deps: [{ token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
190
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxToastrService, providedIn: 'root' });
|
|
208
191
|
}
|
|
209
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
192
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxToastrService, decorators: [{
|
|
210
193
|
type: Injectable,
|
|
211
194
|
args: [{
|
|
212
195
|
providedIn: 'root',
|
|
@@ -214,6 +197,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
214
197
|
}], ctorParameters: () => [{ type: i0.ApplicationRef }] });
|
|
215
198
|
|
|
216
199
|
class FxUtils {
|
|
200
|
+
/** Dot-path accessor (lodash _.get replacement — supports 'a.b.c'). */
|
|
201
|
+
static get(obj, path, defaultValue) {
|
|
202
|
+
if (obj == null)
|
|
203
|
+
return defaultValue;
|
|
204
|
+
let cur = obj;
|
|
205
|
+
for (const key of path.split('.')) {
|
|
206
|
+
if (cur == null)
|
|
207
|
+
return defaultValue;
|
|
208
|
+
cur = cur[key];
|
|
209
|
+
}
|
|
210
|
+
return cur === undefined ? defaultValue : cur;
|
|
211
|
+
}
|
|
212
|
+
/** Dot-path setter (lodash _.set replacement — creates missing objects). */
|
|
213
|
+
static set(obj, path, value) {
|
|
214
|
+
const keys = path.split('.');
|
|
215
|
+
let cur = obj;
|
|
216
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
217
|
+
if (cur[keys[i]] == null || typeof cur[keys[i]] !== 'object')
|
|
218
|
+
cur[keys[i]] = {};
|
|
219
|
+
cur = cur[keys[i]];
|
|
220
|
+
}
|
|
221
|
+
cur[keys[keys.length - 1]] = value;
|
|
222
|
+
return obj;
|
|
223
|
+
}
|
|
224
|
+
/** Structural equality (lodash _.isEqual replacement for plain data). */
|
|
225
|
+
static deepEqual(a, b) {
|
|
226
|
+
if (a === b)
|
|
227
|
+
return true;
|
|
228
|
+
if (a instanceof Date && b instanceof Date)
|
|
229
|
+
return a.getTime() === b.getTime();
|
|
230
|
+
if (a == null || b == null || typeof a !== 'object' || typeof b !== 'object')
|
|
231
|
+
return false;
|
|
232
|
+
if (Array.isArray(a) !== Array.isArray(b))
|
|
233
|
+
return false;
|
|
234
|
+
const ka = Object.keys(a);
|
|
235
|
+
const kb = Object.keys(b);
|
|
236
|
+
if (ka.length !== kb.length)
|
|
237
|
+
return false;
|
|
238
|
+
return ka.every((k) => FxUtils.deepEqual(a[k], b[k]));
|
|
239
|
+
}
|
|
240
|
+
/** Deep clone for plain data (objects/arrays/Date); functions stay by reference. */
|
|
241
|
+
static cloneDeep(v) {
|
|
242
|
+
if (v === null || typeof v !== 'object')
|
|
243
|
+
return v;
|
|
244
|
+
if (v instanceof Date)
|
|
245
|
+
return new Date(v.getTime());
|
|
246
|
+
if (Array.isArray(v))
|
|
247
|
+
return v.map((x) => FxUtils.cloneDeep(x));
|
|
248
|
+
const out = {};
|
|
249
|
+
for (const k of Object.keys(v))
|
|
250
|
+
out[k] = FxUtils.cloneDeep(v[k]);
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
217
253
|
static async preresolve(promises, value, key) {
|
|
218
254
|
if (key === 'callback' || key === 'socket' || key === 'listener') {
|
|
219
255
|
promises.push(value);
|
|
@@ -254,7 +290,7 @@ class FxUtils {
|
|
|
254
290
|
const values = await Promise.all(promises);
|
|
255
291
|
const raw = {};
|
|
256
292
|
keys.forEach((key, index) => {
|
|
257
|
-
|
|
293
|
+
FxUtils.set(raw, key, values[index]);
|
|
258
294
|
});
|
|
259
295
|
return raw;
|
|
260
296
|
}
|
|
@@ -313,13 +349,15 @@ class FxUtils {
|
|
|
313
349
|
}
|
|
314
350
|
}
|
|
315
351
|
static isSameCollection(collection, compareCollection) {
|
|
316
|
-
|
|
352
|
+
const a = new Set(collection ?? []);
|
|
353
|
+
const b = new Set(compareCollection ?? []);
|
|
354
|
+
return a.size === b.size && [...a].every((x) => b.has(x));
|
|
317
355
|
}
|
|
318
356
|
static isSameValue(model, compareModel) {
|
|
319
|
-
return
|
|
357
|
+
return FxUtils.deepEqual(model, compareModel);
|
|
320
358
|
}
|
|
321
359
|
static parseError(err) {
|
|
322
|
-
const status =
|
|
360
|
+
const status = err?.status;
|
|
323
361
|
switch (status) {
|
|
324
362
|
case 401:
|
|
325
363
|
return 'Session timeout. Please login again.';
|
|
@@ -346,13 +384,13 @@ class FxUtils {
|
|
|
346
384
|
case 504:
|
|
347
385
|
return 'The server took too long to respond. Please try again later.';
|
|
348
386
|
}
|
|
349
|
-
const message = this.isStringEmpty(
|
|
350
|
-
?
|
|
351
|
-
:
|
|
352
|
-
if (this.isStringEmpty(
|
|
387
|
+
const message = this.isStringEmpty(err?.error?.errors ?? '')
|
|
388
|
+
? (err?.error?.message ?? 'Unknown Error')
|
|
389
|
+
: err?.error?.errors;
|
|
390
|
+
if (this.isStringEmpty(err?.error?.code)) {
|
|
353
391
|
return message;
|
|
354
392
|
}
|
|
355
|
-
return `${
|
|
393
|
+
return `${err?.error?.code}: ${message}`;
|
|
356
394
|
}
|
|
357
395
|
/**
|
|
358
396
|
* Resolve a theme channel triple (`--danger: 255 122 0`) to a CSS colour.
|
|
@@ -418,7 +456,7 @@ class FxUtils {
|
|
|
418
456
|
}
|
|
419
457
|
/** Safe deep accessor with the org-wide empty placeholder. */
|
|
420
458
|
static value(model, key, defaultValue = '---') {
|
|
421
|
-
return
|
|
459
|
+
return FxUtils.get(model, key, defaultValue);
|
|
422
460
|
}
|
|
423
461
|
/**
|
|
424
462
|
* Severity weight for ordering — kept next to getTagClass so ordering and
|
|
@@ -445,12 +483,16 @@ class FxUtils {
|
|
|
445
483
|
static formatDateTime(time) {
|
|
446
484
|
if (FxUtils.isNull(time))
|
|
447
485
|
return '';
|
|
448
|
-
|
|
486
|
+
const d = time instanceof Date ? time : new Date(String(time).replace(' ', 'T'));
|
|
487
|
+
if (isNaN(d.getTime()))
|
|
488
|
+
return '';
|
|
489
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
490
|
+
return `${p(d.getDate())}/${p(d.getMonth() + 1)}/${d.getFullYear()} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
|
449
491
|
}
|
|
450
492
|
/** Seconds → compact duration ("2d 4h", "3h 12m", "45s"). */
|
|
451
493
|
static formatDuration(totalSeconds) {
|
|
452
494
|
const sec = Number(totalSeconds);
|
|
453
|
-
if (!
|
|
495
|
+
if (!Number.isFinite(sec) || sec < 0)
|
|
454
496
|
return '';
|
|
455
497
|
const d = Math.floor(sec / 86400);
|
|
456
498
|
const h = Math.floor((sec % 86400) / 3600);
|
|
@@ -468,8 +510,20 @@ class FxUtils {
|
|
|
468
510
|
static formatRelative(time) {
|
|
469
511
|
if (FxUtils.isNull(time))
|
|
470
512
|
return '';
|
|
471
|
-
const
|
|
472
|
-
|
|
513
|
+
const d = time instanceof Date ? time : new Date(String(time).replace(' ', 'T'));
|
|
514
|
+
if (isNaN(d.getTime()))
|
|
515
|
+
return '';
|
|
516
|
+
const diffMs = Date.now() - d.getTime();
|
|
517
|
+
if (diffMs < 24 * 3600_000) {
|
|
518
|
+
// Same wording moment.fromNow() produced for the < 24h range.
|
|
519
|
+
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
|
|
520
|
+
const mins = Math.round(diffMs / 60_000);
|
|
521
|
+
if (Math.abs(mins) < 60)
|
|
522
|
+
return rtf.format(-mins, 'minute');
|
|
523
|
+
return rtf.format(-Math.round(mins / 60), 'hour');
|
|
524
|
+
}
|
|
525
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
526
|
+
return `${p(d.getDate())}/${p(d.getMonth() + 1)}/${d.getFullYear()}`;
|
|
473
527
|
}
|
|
474
528
|
/**
|
|
475
529
|
* Normalize a snake_case + protobuf-Long API payload for camelCase binding:
|
|
@@ -493,7 +547,7 @@ class FxUtils {
|
|
|
493
547
|
}
|
|
494
548
|
const out = {};
|
|
495
549
|
for (const k of keys) {
|
|
496
|
-
const nk = /^[a-z][a-z0-9]*(_[a-z0-9]+)+$/.test(k) ? _.
|
|
550
|
+
const nk = /^[a-z][a-z0-9]*(_[a-z0-9]+)+$/.test(k) ? k.replace(/_([a-z0-9])/g, (_m, c) => c.toUpperCase()) : k;
|
|
497
551
|
out[nk] = FxUtils.camelizeDeep(input[k]);
|
|
498
552
|
}
|
|
499
553
|
return out;
|
|
@@ -629,7 +683,7 @@ class BaseTableComponent extends BaseComponent {
|
|
|
629
683
|
dataSourcePlaceholder;
|
|
630
684
|
config;
|
|
631
685
|
paginator;
|
|
632
|
-
table;
|
|
686
|
+
table = viewChild.required(MatTable);
|
|
633
687
|
constructor(injector, api, modal, ref) {
|
|
634
688
|
super(injector);
|
|
635
689
|
this.api = api;
|
|
@@ -675,8 +729,8 @@ class BaseTableComponent extends BaseComponent {
|
|
|
675
729
|
listKey = 'data';
|
|
676
730
|
totalKey = 'total';
|
|
677
731
|
setDataSource(result) {
|
|
678
|
-
this.dataSource.data =
|
|
679
|
-
this.total =
|
|
732
|
+
this.dataSource.data = FxUtils.get(result, this.listKey);
|
|
733
|
+
this.total = FxUtils.get(result, this.totalKey);
|
|
680
734
|
}
|
|
681
735
|
_fetchSeq = 0;
|
|
682
736
|
async fetch() {
|
|
@@ -723,10 +777,10 @@ class BaseTableComponent extends BaseComponent {
|
|
|
723
777
|
this.keywordChange$.next(keyword);
|
|
724
778
|
}
|
|
725
779
|
async create() {
|
|
726
|
-
const conf =
|
|
727
|
-
const dialog =
|
|
728
|
-
const size =
|
|
729
|
-
if (
|
|
780
|
+
const conf = this.config?.create;
|
|
781
|
+
const dialog = conf?.dialog;
|
|
782
|
+
const size = conf?.size;
|
|
783
|
+
if (conf == null || dialog == null) {
|
|
730
784
|
return;
|
|
731
785
|
}
|
|
732
786
|
if (this._lock) {
|
|
@@ -758,10 +812,10 @@ class BaseTableComponent extends BaseComponent {
|
|
|
758
812
|
});
|
|
759
813
|
}
|
|
760
814
|
async update(model) {
|
|
761
|
-
const conf =
|
|
762
|
-
const dialog =
|
|
763
|
-
const size =
|
|
764
|
-
if (
|
|
815
|
+
const conf = this.config?.update;
|
|
816
|
+
const dialog = conf?.dialog;
|
|
817
|
+
const size = conf?.size;
|
|
818
|
+
if (dialog == null || conf == null) {
|
|
765
819
|
return;
|
|
766
820
|
}
|
|
767
821
|
if (this._lock) {
|
|
@@ -793,10 +847,10 @@ class BaseTableComponent extends BaseComponent {
|
|
|
793
847
|
});
|
|
794
848
|
}
|
|
795
849
|
async view(model) {
|
|
796
|
-
const conf =
|
|
797
|
-
const dialog =
|
|
798
|
-
const size =
|
|
799
|
-
if (
|
|
850
|
+
const conf = this.config?.view;
|
|
851
|
+
const dialog = conf?.dialog;
|
|
852
|
+
const size = conf?.size;
|
|
853
|
+
if (dialog == null || conf == null) {
|
|
800
854
|
return;
|
|
801
855
|
}
|
|
802
856
|
if (this._lock) {
|
|
@@ -826,9 +880,9 @@ class BaseTableComponent extends BaseComponent {
|
|
|
826
880
|
});
|
|
827
881
|
}
|
|
828
882
|
async delete(model) {
|
|
829
|
-
const conf =
|
|
830
|
-
const dialog =
|
|
831
|
-
if (
|
|
883
|
+
const conf = this.config?.delete;
|
|
884
|
+
const dialog = conf?.dialog;
|
|
885
|
+
if (conf == null || dialog == null) {
|
|
832
886
|
return;
|
|
833
887
|
}
|
|
834
888
|
if (this._lock) {
|
|
@@ -841,10 +895,10 @@ class BaseTableComponent extends BaseComponent {
|
|
|
841
895
|
autoFocus: 'first-tabbable',
|
|
842
896
|
width: '400px',
|
|
843
897
|
data: {
|
|
844
|
-
title:
|
|
845
|
-
message:
|
|
846
|
-
cancelLabel:
|
|
847
|
-
confirmLabel:
|
|
898
|
+
title: conf?.title,
|
|
899
|
+
message: conf?.message,
|
|
900
|
+
cancelLabel: conf?.cancelTitle,
|
|
901
|
+
confirmLabel: conf?.confirmTitle,
|
|
848
902
|
callback: async () => {
|
|
849
903
|
await this.remove(model);
|
|
850
904
|
},
|
|
@@ -876,10 +930,10 @@ class BaseTableComponent extends BaseComponent {
|
|
|
876
930
|
return FxUtils.getTagClass(tag, true);
|
|
877
931
|
}
|
|
878
932
|
capitalize(label) {
|
|
879
|
-
return
|
|
933
|
+
return label ? label.charAt(0).toUpperCase() + label.slice(1).toLowerCase() : label;
|
|
880
934
|
}
|
|
881
935
|
value(model, key, defaultValue = '---') {
|
|
882
|
-
return
|
|
936
|
+
return FxUtils.get(model, key, defaultValue);
|
|
883
937
|
}
|
|
884
938
|
toggleExpand(element) {
|
|
885
939
|
this.expandedElement = this.expandedElement === element ? null : element;
|
|
@@ -887,7 +941,7 @@ class BaseTableComponent extends BaseComponent {
|
|
|
887
941
|
async updateStatus(params) {
|
|
888
942
|
try {
|
|
889
943
|
await this.api.updateStatus(params);
|
|
890
|
-
this.toastr.success(
|
|
944
|
+
this.toastr.success(this.config?.updateStatus?.message ?? 'Update Success');
|
|
891
945
|
}
|
|
892
946
|
catch (err) {
|
|
893
947
|
this.toastr.error(FxUtils.parseError(err));
|
|
@@ -896,18 +950,15 @@ class BaseTableComponent extends BaseComponent {
|
|
|
896
950
|
await this.refresh();
|
|
897
951
|
}
|
|
898
952
|
}
|
|
899
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
900
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
953
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseTableComponent, deps: [{ token: i0.Injector }, { token: HttpWrapper }, { token: i1.MatDialog }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
954
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.20", type: BaseTableComponent, isStandalone: true, viewQueries: [{ propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }], usesInheritance: true, ngImport: i0 });
|
|
901
955
|
}
|
|
902
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
956
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseTableComponent, decorators: [{
|
|
903
957
|
type: Directive
|
|
904
|
-
}], ctorParameters: () => [{ type: i0.Injector }, { type: HttpWrapper }, { type:
|
|
958
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: HttpWrapper }, { type: i1.MatDialog }, { type: i0.ChangeDetectorRef }], propDecorators: { paginator: [{
|
|
905
959
|
type: ViewChild,
|
|
906
960
|
args: [MatPaginator]
|
|
907
|
-
}], table: [{
|
|
908
|
-
type: ViewChild,
|
|
909
|
-
args: [MatTable]
|
|
910
|
-
}] } });
|
|
961
|
+
}], table: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTable), { isSignal: true }] }] } });
|
|
911
962
|
|
|
912
963
|
/**
|
|
913
964
|
* List + detail-pane counterpart of BaseTableComponent: the page keeps a
|
|
@@ -989,12 +1040,12 @@ class BaseMasterDetailComponent extends BaseTableComponent {
|
|
|
989
1040
|
this.ref.detectChanges();
|
|
990
1041
|
});
|
|
991
1042
|
}
|
|
992
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
993
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1043
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseMasterDetailComponent, deps: [{ token: i0.Injector }, { token: HttpWrapper }, { token: i1.MatDialog }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1044
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: BaseMasterDetailComponent, isStandalone: true, usesInheritance: true, ngImport: i0 });
|
|
994
1045
|
}
|
|
995
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1046
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseMasterDetailComponent, decorators: [{
|
|
996
1047
|
type: Directive
|
|
997
|
-
}], ctorParameters: () => [{ type: i0.Injector }, { type: HttpWrapper }, { type:
|
|
1048
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: HttpWrapper }, { type: i1.MatDialog }, { type: i0.ChangeDetectorRef }] });
|
|
998
1049
|
|
|
999
1050
|
class BaseDialogComponent extends BaseComponent {
|
|
1000
1051
|
ref;
|
|
@@ -1002,7 +1053,7 @@ class BaseDialogComponent extends BaseComponent {
|
|
|
1002
1053
|
toastr;
|
|
1003
1054
|
api;
|
|
1004
1055
|
dialog;
|
|
1005
|
-
ngForm;
|
|
1056
|
+
ngForm = viewChild('f', ...(ngDevMode ? [{ debugName: "ngForm" }] : /* istanbul ignore next */ []));
|
|
1006
1057
|
method;
|
|
1007
1058
|
title;
|
|
1008
1059
|
model;
|
|
@@ -1021,12 +1072,12 @@ class BaseDialogComponent extends BaseComponent {
|
|
|
1021
1072
|
this.dialog = dialog;
|
|
1022
1073
|
// Deep clone: a shallow clone let dialog edits mutate nested fields of
|
|
1023
1074
|
// the live table row even when the user cancelled.
|
|
1024
|
-
this.model =
|
|
1025
|
-
this.method =
|
|
1026
|
-
this.title =
|
|
1027
|
-
this.disabled =
|
|
1028
|
-
this.message =
|
|
1029
|
-
this.resolve =
|
|
1075
|
+
this.model = FxUtils.cloneDeep(bindings?.['data']);
|
|
1076
|
+
this.method = bindings?.['method'];
|
|
1077
|
+
this.title = bindings?.['title'];
|
|
1078
|
+
this.disabled = bindings?.['disabled'];
|
|
1079
|
+
this.message = bindings?.['message'];
|
|
1080
|
+
this.resolve = bindings?.['resolve'];
|
|
1030
1081
|
}
|
|
1031
1082
|
// eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method -- subclasses across host apps call super lifecycle methods; removing these breaks them at runtime
|
|
1032
1083
|
ngAfterViewInit() { }
|
|
@@ -1108,18 +1159,15 @@ class BaseDialogComponent extends BaseComponent {
|
|
|
1108
1159
|
validate() {
|
|
1109
1160
|
return true;
|
|
1110
1161
|
}
|
|
1111
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1112
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
1162
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: FxToastrService }, { token: HttpWrapper }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1163
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.20", type: BaseDialogComponent, isStandalone: true, viewQueries: [{ propertyName: "ngForm", first: true, predicate: ["f"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 });
|
|
1113
1164
|
}
|
|
1114
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1165
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseDialogComponent, decorators: [{
|
|
1115
1166
|
type: Directive
|
|
1116
|
-
}], ctorParameters: () => [{ type: i1
|
|
1167
|
+
}], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
|
|
1117
1168
|
type: Inject,
|
|
1118
1169
|
args: [MAT_DIALOG_DATA]
|
|
1119
|
-
}] }, { type: FxToastrService }, { type: HttpWrapper }, { type: i1
|
|
1120
|
-
type: ViewChild,
|
|
1121
|
-
args: ['f', { static: true }]
|
|
1122
|
-
}] } });
|
|
1170
|
+
}] }, { type: FxToastrService }, { type: HttpWrapper }, { type: i1.MatDialog }], propDecorators: { ngForm: [{ type: i0.ViewChild, args: ['f', { isSignal: true }] }] } });
|
|
1123
1171
|
|
|
1124
1172
|
class FxLoadingService {
|
|
1125
1173
|
listener = new EventEmitter();
|
|
@@ -1136,10 +1184,10 @@ class FxLoadingService {
|
|
|
1136
1184
|
stopAction() {
|
|
1137
1185
|
this.listenerAction.emit(false);
|
|
1138
1186
|
}
|
|
1139
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1140
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1187
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxLoadingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1188
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxLoadingService, providedIn: 'root' });
|
|
1141
1189
|
}
|
|
1142
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxLoadingService, decorators: [{
|
|
1143
1191
|
type: Injectable,
|
|
1144
1192
|
args: [{
|
|
1145
1193
|
providedIn: 'root'
|
|
@@ -1169,10 +1217,10 @@ class FxStorageService {
|
|
|
1169
1217
|
remove(key) {
|
|
1170
1218
|
localStorage.removeItem(key);
|
|
1171
1219
|
}
|
|
1172
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1173
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1220
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1221
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxStorageService, providedIn: 'root' });
|
|
1174
1222
|
}
|
|
1175
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1223
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxStorageService, decorators: [{
|
|
1176
1224
|
type: Injectable,
|
|
1177
1225
|
args: [{
|
|
1178
1226
|
providedIn: 'root',
|
|
@@ -1401,7 +1449,7 @@ const TONE_BADGE = {
|
|
|
1401
1449
|
information: 'bg-information/10 text-information',
|
|
1402
1450
|
};
|
|
1403
1451
|
function hasVal(v) {
|
|
1404
|
-
if (
|
|
1452
|
+
if (v == null)
|
|
1405
1453
|
return false;
|
|
1406
1454
|
const s = String(v).trim();
|
|
1407
1455
|
return s !== '' && s !== '-' && s !== '--';
|
|
@@ -1420,7 +1468,7 @@ function severityTone(value) {
|
|
|
1420
1468
|
*/
|
|
1421
1469
|
function scoreTone(score) {
|
|
1422
1470
|
let n = Number(score);
|
|
1423
|
-
if (!
|
|
1471
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
1424
1472
|
return null;
|
|
1425
1473
|
if (n > 10)
|
|
1426
1474
|
n = n / 10;
|
|
@@ -1440,7 +1488,7 @@ function scoreTone(score) {
|
|
|
1440
1488
|
*/
|
|
1441
1489
|
function countTone(count, positiveTone = 'danger') {
|
|
1442
1490
|
const n = Number(count);
|
|
1443
|
-
if (!
|
|
1491
|
+
if (!Number.isFinite(n))
|
|
1444
1492
|
return null;
|
|
1445
1493
|
return n > 0 ? positiveTone : 'success';
|
|
1446
1494
|
}
|
|
@@ -1604,11 +1652,11 @@ class TranslationModule {
|
|
|
1604
1652
|
providers: []
|
|
1605
1653
|
};
|
|
1606
1654
|
}
|
|
1607
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1608
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
1609
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
1655
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1656
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, imports: [TranslateModule], exports: [TranslateModule] });
|
|
1657
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, imports: [TranslateModule, TranslateModule] });
|
|
1610
1658
|
}
|
|
1611
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1659
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, decorators: [{
|
|
1612
1660
|
type: NgModule,
|
|
1613
1661
|
args: [{
|
|
1614
1662
|
imports: [TranslateModule],
|
|
@@ -1652,13 +1700,13 @@ class TranslationService {
|
|
|
1652
1700
|
onLanguageChange(callback) {
|
|
1653
1701
|
this.currentLang$.subscribe(callback);
|
|
1654
1702
|
}
|
|
1655
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1656
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1703
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationService, deps: [{ token: i1$1.TranslateService }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1704
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationService, providedIn: 'root' });
|
|
1657
1705
|
}
|
|
1658
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1706
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationService, decorators: [{
|
|
1659
1707
|
type: Injectable,
|
|
1660
1708
|
args: [{ providedIn: 'root' }]
|
|
1661
|
-
}], ctorParameters: () => [{ type: i1$
|
|
1709
|
+
}], ctorParameters: () => [{ type: i1$1.TranslateService }, { type: i2.HttpClient }] });
|
|
1662
1710
|
|
|
1663
1711
|
class PermissionService {
|
|
1664
1712
|
permissions = [];
|
|
@@ -1666,15 +1714,15 @@ class PermissionService {
|
|
|
1666
1714
|
this.permissions = perms;
|
|
1667
1715
|
}
|
|
1668
1716
|
hasPermission(requiredPermissions) {
|
|
1669
|
-
return
|
|
1717
|
+
return requiredPermissions.some((permission) => this.permissions.includes(permission));
|
|
1670
1718
|
}
|
|
1671
1719
|
getPermissions() {
|
|
1672
1720
|
return [...this.permissions];
|
|
1673
1721
|
}
|
|
1674
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1675
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1722
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1723
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionService, providedIn: 'root' });
|
|
1676
1724
|
}
|
|
1677
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1725
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionService, decorators: [{
|
|
1678
1726
|
type: Injectable,
|
|
1679
1727
|
args: [{
|
|
1680
1728
|
providedIn: 'root'
|
|
@@ -1691,16 +1739,16 @@ class HasPermissionDirective {
|
|
|
1691
1739
|
this.permissionService = permissionService;
|
|
1692
1740
|
}
|
|
1693
1741
|
set hasPermission(required) {
|
|
1694
|
-
const requiredPermissions =
|
|
1742
|
+
const requiredPermissions = Array.isArray(required) ? required : [required];
|
|
1695
1743
|
this.viewContainerRef.clear();
|
|
1696
1744
|
if (this.permissionService.hasPermission(requiredPermissions)) {
|
|
1697
1745
|
this.viewContainerRef.createEmbeddedView(this.templateRef);
|
|
1698
1746
|
}
|
|
1699
1747
|
}
|
|
1700
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1701
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1748
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: PermissionService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1749
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: HasPermissionDirective, isStandalone: true, selector: "[hasPermission]", inputs: { hasPermission: "hasPermission" }, ngImport: i0 });
|
|
1702
1750
|
}
|
|
1703
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1751
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HasPermissionDirective, decorators: [{
|
|
1704
1752
|
type: Directive,
|
|
1705
1753
|
args: [{
|
|
1706
1754
|
// eslint-disable-next-line @angular-eslint/directive-selector -- renaming is a breaking change for all host-app templates
|
|
@@ -1712,18 +1760,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
1712
1760
|
|
|
1713
1761
|
class TrimOnBlurDirective {
|
|
1714
1762
|
el;
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1763
|
+
collapseWhitespace = input(false, { ...(ngDevMode ? { debugName: "collapseWhitespace" } : /* istanbul ignore next */ {}), alias: "appTrimOnBlurCollapse" });
|
|
1764
|
+
/* Optional on purpose: the onBlur fallback below already handles the
|
|
1765
|
+
* no-form case, but the injection was required and crashed any unbound
|
|
1766
|
+
* input once the directive actually entered the compilation scope. */
|
|
1767
|
+
ngControl = inject(NgControl, { optional: true });
|
|
1768
|
+
constructor(el) {
|
|
1718
1769
|
this.el = el;
|
|
1719
|
-
this.ngControl = ngControl;
|
|
1720
1770
|
}
|
|
1721
1771
|
onBlur() {
|
|
1722
1772
|
const native = this.el.nativeElement;
|
|
1723
1773
|
if (!native)
|
|
1724
1774
|
return;
|
|
1725
1775
|
let value = native.value ?? '';
|
|
1726
|
-
if (this.collapseWhitespace) {
|
|
1776
|
+
if (this.collapseWhitespace()) {
|
|
1727
1777
|
value = value.replace(/\s+/g, ' ').trim();
|
|
1728
1778
|
}
|
|
1729
1779
|
else {
|
|
@@ -1740,19 +1790,16 @@ class TrimOnBlurDirective {
|
|
|
1740
1790
|
native.dispatchEvent(ev);
|
|
1741
1791
|
}
|
|
1742
1792
|
}
|
|
1743
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1744
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
1793
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TrimOnBlurDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
1794
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.20", type: TrimOnBlurDirective, isStandalone: true, selector: "[appTrimOnBlur]", inputs: { collapseWhitespace: { classPropertyName: "collapseWhitespace", publicName: "appTrimOnBlurCollapse", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "blur": "onBlur()" } }, ngImport: i0 });
|
|
1745
1795
|
}
|
|
1746
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1796
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TrimOnBlurDirective, decorators: [{
|
|
1747
1797
|
type: Directive,
|
|
1748
1798
|
args: [{
|
|
1749
1799
|
// eslint-disable-next-line @angular-eslint/directive-selector -- renaming is a breaking change for all host-app templates
|
|
1750
1800
|
selector: '[appTrimOnBlur]'
|
|
1751
1801
|
}]
|
|
1752
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type:
|
|
1753
|
-
type: Input,
|
|
1754
|
-
args: ['appTrimOnBlurCollapse']
|
|
1755
|
-
}], onBlur: [{
|
|
1802
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { collapseWhitespace: [{ type: i0.Input, args: [{ isSignal: true, alias: "appTrimOnBlurCollapse", required: false }] }], onBlur: [{
|
|
1756
1803
|
type: HostListener,
|
|
1757
1804
|
args: ['blur']
|
|
1758
1805
|
}] } });
|
|
@@ -1772,15 +1819,15 @@ class PermissionGuard {
|
|
|
1772
1819
|
this.router.navigate(['/unauthorized']);
|
|
1773
1820
|
return false;
|
|
1774
1821
|
}
|
|
1775
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1776
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1822
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionGuard, deps: [{ token: PermissionService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1823
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionGuard, providedIn: 'root' });
|
|
1777
1824
|
}
|
|
1778
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1825
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionGuard, decorators: [{
|
|
1779
1826
|
type: Injectable,
|
|
1780
1827
|
args: [{
|
|
1781
1828
|
providedIn: 'root',
|
|
1782
1829
|
}]
|
|
1783
|
-
}], ctorParameters: () => [{ type: PermissionService }, { type:
|
|
1830
|
+
}], ctorParameters: () => [{ type: PermissionService }, { type: i2$1.Router }] });
|
|
1784
1831
|
|
|
1785
1832
|
class AuthStateService {
|
|
1786
1833
|
_isLoggedIn$ = new BehaviorSubject(null);
|
|
@@ -1797,10 +1844,10 @@ class AuthStateService {
|
|
|
1797
1844
|
this.setLoggedIn(false);
|
|
1798
1845
|
this.unauthorized$.next();
|
|
1799
1846
|
}
|
|
1800
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1801
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1847
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1848
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthStateService, providedIn: 'root' });
|
|
1802
1849
|
}
|
|
1803
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1850
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthStateService, decorators: [{
|
|
1804
1851
|
type: Injectable,
|
|
1805
1852
|
args: [{ providedIn: 'root' }]
|
|
1806
1853
|
}], ctorParameters: () => [] });
|
|
@@ -1830,10 +1877,10 @@ class AuthInterceptor {
|
|
|
1830
1877
|
return throwError(() => error);
|
|
1831
1878
|
}));
|
|
1832
1879
|
}
|
|
1833
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1834
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1880
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthInterceptor, deps: [{ token: AuthStateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1881
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthInterceptor });
|
|
1835
1882
|
}
|
|
1836
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1883
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthInterceptor, decorators: [{
|
|
1837
1884
|
type: Injectable
|
|
1838
1885
|
}], ctorParameters: () => [{ type: AuthStateService }] });
|
|
1839
1886
|
|
|
@@ -1848,81 +1895,16 @@ class BreadcrumbService {
|
|
|
1848
1895
|
clear() {
|
|
1849
1896
|
this.breadcrumbs$.next([]);
|
|
1850
1897
|
}
|
|
1851
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1852
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1898
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BreadcrumbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1899
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BreadcrumbService, providedIn: 'root' });
|
|
1853
1900
|
}
|
|
1854
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1901
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BreadcrumbService, decorators: [{
|
|
1855
1902
|
type: Injectable,
|
|
1856
1903
|
args: [{
|
|
1857
1904
|
providedIn: 'root'
|
|
1858
1905
|
}]
|
|
1859
1906
|
}] });
|
|
1860
1907
|
|
|
1861
|
-
class QuillStyleLoaderService {
|
|
1862
|
-
platformId;
|
|
1863
|
-
loaded = false;
|
|
1864
|
-
loadingPromise = null;
|
|
1865
|
-
constructor(platformId) {
|
|
1866
|
-
this.platformId = platformId;
|
|
1867
|
-
}
|
|
1868
|
-
/**
|
|
1869
|
-
* Load Quill CSS (only in browser). Returns a promise that resolves when
|
|
1870
|
-
* the CSS links have been appended.
|
|
1871
|
-
*/
|
|
1872
|
-
load() {
|
|
1873
|
-
if (!isPlatformBrowser(this.platformId)) {
|
|
1874
|
-
// Server: do nothing and resolve immediately.
|
|
1875
|
-
return Promise.resolve();
|
|
1876
|
-
}
|
|
1877
|
-
if (this.loaded)
|
|
1878
|
-
return Promise.resolve();
|
|
1879
|
-
if (this.loadingPromise)
|
|
1880
|
-
return this.loadingPromise;
|
|
1881
|
-
this.loadingPromise = new Promise((resolve) => {
|
|
1882
|
-
const cssUrls = [
|
|
1883
|
-
// Using CDN is simplest — no consumer angular.json edits needed.
|
|
1884
|
-
'https://cdn.jsdelivr.net/npm/quill/dist/quill.core.css',
|
|
1885
|
-
'https://cdn.jsdelivr.net/npm/quill/dist/quill.snow.css'
|
|
1886
|
-
];
|
|
1887
|
-
let remaining = cssUrls.length;
|
|
1888
|
-
const onLoad = () => {
|
|
1889
|
-
remaining -= 1;
|
|
1890
|
-
if (remaining === 0) {
|
|
1891
|
-
this.loaded = true;
|
|
1892
|
-
resolve();
|
|
1893
|
-
}
|
|
1894
|
-
};
|
|
1895
|
-
cssUrls.forEach((href) => {
|
|
1896
|
-
// Do not add duplicate links
|
|
1897
|
-
if (document.querySelector(`link[href="${href}"]`)) {
|
|
1898
|
-
onLoad();
|
|
1899
|
-
return;
|
|
1900
|
-
}
|
|
1901
|
-
const link = document.createElement('link');
|
|
1902
|
-
link.rel = 'stylesheet';
|
|
1903
|
-
link.href = href;
|
|
1904
|
-
link.onload = () => onLoad();
|
|
1905
|
-
link.onerror = () => {
|
|
1906
|
-
// still count it as loaded to avoid hanging if CDN fails
|
|
1907
|
-
console.warn(`[QuillStyleLoader] failed to load: ${href}`);
|
|
1908
|
-
onLoad();
|
|
1909
|
-
};
|
|
1910
|
-
document.head.appendChild(link);
|
|
1911
|
-
});
|
|
1912
|
-
});
|
|
1913
|
-
return this.loadingPromise;
|
|
1914
|
-
}
|
|
1915
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1916
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, providedIn: 'root' });
|
|
1917
|
-
}
|
|
1918
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, decorators: [{
|
|
1919
|
-
type: Injectable,
|
|
1920
|
-
args: [{ providedIn: 'root' }]
|
|
1921
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1922
|
-
type: Inject,
|
|
1923
|
-
args: [PLATFORM_ID]
|
|
1924
|
-
}] }] });
|
|
1925
|
-
|
|
1926
1908
|
class ThemeService {
|
|
1927
1909
|
renderer;
|
|
1928
1910
|
lightClass = 'light_theme';
|
|
@@ -1967,10 +1949,10 @@ class ThemeService {
|
|
|
1967
1949
|
getLogoPath() {
|
|
1968
1950
|
return 'assets/images/logo.png';
|
|
1969
1951
|
}
|
|
1970
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1971
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1952
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ThemeService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1953
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ThemeService, providedIn: 'root' });
|
|
1972
1954
|
}
|
|
1973
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1955
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ThemeService, decorators: [{
|
|
1974
1956
|
type: Injectable,
|
|
1975
1957
|
args: [{ providedIn: 'root' }]
|
|
1976
1958
|
}], ctorParameters: () => [{ type: i0.RendererFactory2 }] });
|
|
@@ -2192,482 +2174,115 @@ class NotificationService {
|
|
|
2192
2174
|
getConnectionId() {
|
|
2193
2175
|
return this.hubConnection?.connectionId ?? null;
|
|
2194
2176
|
}
|
|
2195
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2196
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2177
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2178
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: NotificationService, providedIn: 'root' });
|
|
2197
2179
|
}
|
|
2198
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2180
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: NotificationService, decorators: [{
|
|
2199
2181
|
type: Injectable,
|
|
2200
2182
|
args: [{
|
|
2201
2183
|
providedIn: 'root'
|
|
2202
2184
|
}]
|
|
2203
2185
|
}] });
|
|
2204
2186
|
|
|
2205
|
-
const MATERIAL_MODULE = [
|
|
2206
|
-
MatSelectModule,
|
|
2207
|
-
MatRadioModule,
|
|
2208
|
-
MatButtonModule,
|
|
2209
|
-
MatIconModule,
|
|
2210
|
-
MatPaginatorModule,
|
|
2211
|
-
MatTableModule,
|
|
2212
|
-
MatSnackBarModule,
|
|
2213
|
-
MatDialogModule,
|
|
2214
|
-
MatCheckboxModule,
|
|
2215
|
-
MatCardModule,
|
|
2216
|
-
MatDatepickerModule,
|
|
2217
|
-
MatTimepickerModule,
|
|
2218
|
-
MatBadgeModule,
|
|
2219
|
-
MatExpansionModule,
|
|
2220
|
-
MatFormFieldModule,
|
|
2221
|
-
MatMenuModule,
|
|
2222
|
-
MatTooltipModule,
|
|
2223
|
-
DragDropModule,
|
|
2224
|
-
];
|
|
2225
|
-
|
|
2226
2187
|
class ButtonComponent {
|
|
2227
2188
|
label;
|
|
2228
|
-
disabled = false;
|
|
2229
|
-
buttonVariant = 'alternative';
|
|
2189
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
2190
|
+
buttonVariant = input('alternative', ...(ngDevMode ? [{ debugName: "buttonVariant" }] : /* istanbul ignore next */ []));
|
|
2230
2191
|
icon;
|
|
2231
|
-
class;
|
|
2232
|
-
loading = false;
|
|
2192
|
+
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2193
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2233
2194
|
/** Native button type. Defaults to 'button' so it never implicitly submits a form. */
|
|
2234
|
-
type = 'button';
|
|
2195
|
+
type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
2235
2196
|
/** Accessible name for icon-only usage (icon set, no label). */
|
|
2236
|
-
ariaLabel = '';
|
|
2237
|
-
clicked =
|
|
2197
|
+
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
2198
|
+
clicked = output();
|
|
2238
2199
|
onClick() {
|
|
2239
|
-
if (!this.disabled)
|
|
2200
|
+
if (!this.disabled())
|
|
2240
2201
|
this.clicked.emit();
|
|
2241
2202
|
}
|
|
2242
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2243
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2203
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2204
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ButtonComponent, isStandalone: true, selector: "fx-ui-button", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, buttonVariant: { classPropertyName: "buttonVariant", publicName: "buttonVariant", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: false, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n [attr.type]=\"type()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-busy]=\"loading() || null\"\n [class]=\"class()\"\n [ngClass]=\"{\n 'btn-default': buttonVariant() === 'default',\n 'btn-primary': buttonVariant() === 'primary',\n 'btn-success': buttonVariant() === 'success',\n 'btn-alternative': buttonVariant() === 'alternative',\n }\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"onClick()\"\n>\n @if (loading()) {\n <div class=\"flex w-full items-center justify-center\" aria-hidden=\"true\">\n <svg\n [attr.fill]=\"\n buttonVariant() !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'\n \"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_lo66\"\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_z0Or\"\n begin=\"spinner_lo66.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_JsnR\"\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_Aguh\"\n begin=\"spinner_JsnR.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_hSjk\"\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_UHR2\"\n begin=\"spinner_hSjk.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate\n id=\"spinner_4v5M\"\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_OLMs\"\n begin=\"spinner_4v5M.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n </circle>\n </svg>\n </div>\n } @else {\n <ng-container>\n <div class=\"flex items-center justify-center gap-small\">\n @if (icon) {\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"20\"\n class=\"flex\"\n [ngClass]=\"{\n 'text-text-inverse': buttonVariant() === 'default',\n 'text-text-primary': buttonVariant() === 'alternative',\n 'text-white': buttonVariant() === 'primary' || buttonVariant() === 'success',\n }\"\n ></fx-ui-hero-icon>\n }\n @if (label) {\n <div>{{ label }}</div>\n }\n </div>\n </ng-container>\n }\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2244
2205
|
}
|
|
2245
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
2246
2207
|
type: Component,
|
|
2247
|
-
args: [{ selector: 'fx-ui-button',
|
|
2208
|
+
args: [{ selector: 'fx-ui-button', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, HeroIconComponent], template: "<button\n [attr.type]=\"type()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-busy]=\"loading() || null\"\n [class]=\"class()\"\n [ngClass]=\"{\n 'btn-default': buttonVariant() === 'default',\n 'btn-primary': buttonVariant() === 'primary',\n 'btn-success': buttonVariant() === 'success',\n 'btn-alternative': buttonVariant() === 'alternative',\n }\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"onClick()\"\n>\n @if (loading()) {\n <div class=\"flex w-full items-center justify-center\" aria-hidden=\"true\">\n <svg\n [attr.fill]=\"\n buttonVariant() !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'\n \"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_lo66\"\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_z0Or\"\n begin=\"spinner_lo66.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_JsnR\"\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_Aguh\"\n begin=\"spinner_JsnR.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_hSjk\"\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_UHR2\"\n begin=\"spinner_hSjk.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate\n id=\"spinner_4v5M\"\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_OLMs\"\n begin=\"spinner_4v5M.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n </circle>\n </svg>\n </div>\n } @else {\n <ng-container>\n <div class=\"flex items-center justify-center gap-small\">\n @if (icon) {\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"20\"\n class=\"flex\"\n [ngClass]=\"{\n 'text-text-inverse': buttonVariant() === 'default',\n 'text-text-primary': buttonVariant() === 'alternative',\n 'text-white': buttonVariant() === 'primary' || buttonVariant() === 'success',\n }\"\n ></fx-ui-hero-icon>\n }\n @if (label) {\n <div>{{ label }}</div>\n }\n </div>\n </ng-container>\n }\n</button>\n" }]
|
|
2248
2209
|
}], propDecorators: { label: [{
|
|
2249
2210
|
type: Input
|
|
2250
|
-
}], disabled: [{
|
|
2251
|
-
type: Input
|
|
2252
|
-
}], buttonVariant: [{
|
|
2253
|
-
type: Input
|
|
2254
|
-
}], icon: [{
|
|
2255
|
-
type: Input
|
|
2256
|
-
}], class: [{
|
|
2257
|
-
type: Input
|
|
2258
|
-
}], loading: [{
|
|
2259
|
-
type: Input
|
|
2260
|
-
}], type: [{
|
|
2211
|
+
}], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], buttonVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonVariant", required: false }] }], icon: [{
|
|
2261
2212
|
type: Input
|
|
2262
|
-
}], ariaLabel: [{
|
|
2263
|
-
type: Input
|
|
2264
|
-
}], clicked: [{
|
|
2265
|
-
type: Output
|
|
2266
|
-
}] } });
|
|
2213
|
+
}], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
|
|
2267
2214
|
|
|
2268
|
-
class
|
|
2215
|
+
class ConfirmationDialogComponent {
|
|
2269
2216
|
ref;
|
|
2270
|
-
|
|
2271
|
-
/* ================= INPUTS ================= */
|
|
2272
|
-
type = 'auto';
|
|
2273
|
-
data;
|
|
2274
|
-
options;
|
|
2275
|
-
palette;
|
|
2276
|
-
height = '400px';
|
|
2217
|
+
bindings;
|
|
2277
2218
|
loading = false;
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
labelFontFamily = 'Roboto';
|
|
2284
|
-
emptyText = 'No data available';
|
|
2285
|
-
/* ================= OUTPUTS ================= */
|
|
2286
|
-
chartClick = new EventEmitter();
|
|
2287
|
-
chartInit = new EventEmitter();
|
|
2288
|
-
/* ================= INTERNAL ================= */
|
|
2289
|
-
chartOptions = {};
|
|
2290
|
-
isEmpty = false;
|
|
2291
|
-
labelFontSize = 12;
|
|
2292
|
-
chartInstance;
|
|
2293
|
-
resizeObserver;
|
|
2294
|
-
intersectionObserver;
|
|
2295
|
-
canInit = false;
|
|
2296
|
-
isMobile = false;
|
|
2297
|
-
containerWidth = 0;
|
|
2298
|
-
constructor(ref, cdr) {
|
|
2219
|
+
title = '';
|
|
2220
|
+
message = '';
|
|
2221
|
+
cancelLabel = 'Cancel';
|
|
2222
|
+
confirmLabel = 'Submit';
|
|
2223
|
+
constructor(ref, bindings) {
|
|
2299
2224
|
this.ref = ref;
|
|
2300
|
-
this.
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
this.intersectionObserver = new IntersectionObserver(([entry]) => {
|
|
2306
|
-
if (entry.isIntersecting && !this.canInit) {
|
|
2307
|
-
this.canInit = true;
|
|
2308
|
-
this.updateResponsiveState();
|
|
2309
|
-
this.rebuildChart();
|
|
2310
|
-
this.cdr.detectChanges();
|
|
2311
|
-
}
|
|
2312
|
-
}, { threshold: 0.1 });
|
|
2313
|
-
this.intersectionObserver.observe(this.ref.nativeElement);
|
|
2314
|
-
// Resize-safe (tabs, flex, async layout)
|
|
2315
|
-
this.resizeObserver = new ResizeObserver(() => {
|
|
2316
|
-
if (!this.canInit)
|
|
2317
|
-
return;
|
|
2318
|
-
this.updateResponsiveState();
|
|
2319
|
-
this.forceMediaRecalc();
|
|
2320
|
-
});
|
|
2321
|
-
this.resizeObserver.observe(this.ref.nativeElement);
|
|
2322
|
-
}
|
|
2323
|
-
ngOnChanges() {
|
|
2324
|
-
if (this.canInit) {
|
|
2325
|
-
this.updateResponsiveState();
|
|
2326
|
-
this.rebuildChart();
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
ngOnDestroy() {
|
|
2330
|
-
this.resizeObserver?.disconnect();
|
|
2331
|
-
this.intersectionObserver?.disconnect();
|
|
2332
|
-
}
|
|
2333
|
-
onThemeChange() {
|
|
2334
|
-
if (!this.canInit)
|
|
2335
|
-
return;
|
|
2336
|
-
requestAnimationFrame(() => this.rebuildChart());
|
|
2337
|
-
}
|
|
2338
|
-
/* ================= EVENTS ================= */
|
|
2339
|
-
onChartClick(event) {
|
|
2340
|
-
this.chartClick.emit(event);
|
|
2341
|
-
}
|
|
2342
|
-
onChartInit(chart) {
|
|
2343
|
-
this.chartInstance = chart;
|
|
2344
|
-
this.chartInit.emit(chart);
|
|
2345
|
-
requestAnimationFrame(() => this.forceMediaRecalc());
|
|
2346
|
-
}
|
|
2347
|
-
/* ================= CORE FIX ================= */
|
|
2348
|
-
updateResponsiveState() {
|
|
2349
|
-
const { width } = this.ref.nativeElement.getBoundingClientRect();
|
|
2350
|
-
if (width > 0) {
|
|
2351
|
-
this.containerWidth = width;
|
|
2352
|
-
this.isMobile = width < this.mobileWidth;
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
forceMediaRecalc(retry = 0) {
|
|
2356
|
-
if (!this.chartInstance)
|
|
2357
|
-
return;
|
|
2358
|
-
const { width, height } = this.ref.nativeElement.getBoundingClientRect();
|
|
2359
|
-
if ((width === 0 || height === 0) && retry < 10) {
|
|
2360
|
-
requestAnimationFrame(() => this.forceMediaRecalc(retry + 1));
|
|
2361
|
-
return;
|
|
2362
|
-
}
|
|
2363
|
-
this.rebuildChart();
|
|
2364
|
-
this.chartInstance.resize();
|
|
2365
|
-
}
|
|
2366
|
-
rebuildChart() {
|
|
2367
|
-
this.isEmpty = this.checkEmpty();
|
|
2368
|
-
if (this.isEmpty) {
|
|
2369
|
-
if (this.chartInstance) {
|
|
2370
|
-
this.chartInstance.clear();
|
|
2371
|
-
}
|
|
2372
|
-
return;
|
|
2373
|
-
}
|
|
2374
|
-
this.chartOptions = this.buildOptions();
|
|
2375
|
-
if (this.chartInstance) {
|
|
2376
|
-
this.chartInstance.clear();
|
|
2377
|
-
this.chartInstance.setOption(this.chartOptions, true);
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2380
|
-
checkEmpty() {
|
|
2381
|
-
const type = this.detectType();
|
|
2382
|
-
if (type === 'bar') {
|
|
2383
|
-
const categories = this.data?.categories;
|
|
2384
|
-
const values = this.data?.values;
|
|
2385
|
-
return !categories?.length || !values?.length;
|
|
2386
|
-
}
|
|
2387
|
-
if (type === 'pie') {
|
|
2388
|
-
if (!Array.isArray(this.data) || this.data.length === 0)
|
|
2389
|
-
return true;
|
|
2390
|
-
const total = this.data.reduce((sum, d) => sum + (d.value || 0), 0);
|
|
2391
|
-
return total === 0;
|
|
2392
|
-
}
|
|
2393
|
-
return false;
|
|
2225
|
+
this.bindings = bindings;
|
|
2226
|
+
this.title = bindings?.['title'];
|
|
2227
|
+
this.message = bindings?.['message'];
|
|
2228
|
+
this.cancelLabel = bindings?.['cancelLabel'];
|
|
2229
|
+
this.confirmLabel = bindings?.['confirmLabel'];
|
|
2394
2230
|
}
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
grid: { left: '5%', right: '5%', bottom: '10%', containLabel: true },
|
|
2401
|
-
xAxis: {
|
|
2402
|
-
type: 'category',
|
|
2403
|
-
data: data?.categories || [],
|
|
2404
|
-
axisLabel: {
|
|
2405
|
-
interval: 0,
|
|
2406
|
-
width: 80,
|
|
2407
|
-
overflow: 'truncate',
|
|
2408
|
-
ellipsis: '…',
|
|
2409
|
-
fontFamily: this.labelFontFamily,
|
|
2410
|
-
fontSize: this.labelFontSize,
|
|
2411
|
-
color: FxUtils.convertColorFromVariable('--text-secondary'),
|
|
2412
|
-
},
|
|
2413
|
-
axisLine: {
|
|
2414
|
-
lineStyle: {
|
|
2415
|
-
color: FxUtils.convertColorFromVariable('--border-strong'),
|
|
2416
|
-
},
|
|
2417
|
-
},
|
|
2418
|
-
},
|
|
2419
|
-
yAxis: {
|
|
2420
|
-
type: 'value',
|
|
2421
|
-
axisLabel: {
|
|
2422
|
-
fontFamily: this.labelFontFamily,
|
|
2423
|
-
fontSize: this.labelFontSize,
|
|
2424
|
-
color: FxUtils.convertColorFromVariable('--text-secondary'),
|
|
2425
|
-
},
|
|
2426
|
-
axisLine: {
|
|
2427
|
-
lineStyle: {
|
|
2428
|
-
color: FxUtils.convertColorFromVariable('--border-strong'),
|
|
2429
|
-
},
|
|
2430
|
-
},
|
|
2431
|
-
splitLine: {
|
|
2432
|
-
lineStyle: {
|
|
2433
|
-
color: FxUtils.convertColorFromVariable('--border-default'),
|
|
2434
|
-
},
|
|
2435
|
-
},
|
|
2436
|
-
},
|
|
2437
|
-
series: [
|
|
2438
|
-
{
|
|
2439
|
-
type: 'bar',
|
|
2440
|
-
data: data?.values || [],
|
|
2441
|
-
barMaxWidth: 70,
|
|
2442
|
-
itemStyle: {
|
|
2443
|
-
color: (p) => colors[p.dataIndex % colors.length],
|
|
2444
|
-
},
|
|
2445
|
-
label: {
|
|
2446
|
-
show: true,
|
|
2447
|
-
position: 'top',
|
|
2448
|
-
fontFamily: this.labelFontFamily,
|
|
2449
|
-
fontSize: this.labelFontSize,
|
|
2450
|
-
color: FxUtils.convertColorFromVariable('--text-primary'),
|
|
2451
|
-
},
|
|
2452
|
-
},
|
|
2453
|
-
],
|
|
2454
|
-
}),
|
|
2455
|
-
pie: (data, colors) => {
|
|
2456
|
-
const total = data.reduce((sum, d) => sum + d.value, 0);
|
|
2457
|
-
const layout = this.calcPieLayout(data);
|
|
2458
|
-
return {
|
|
2459
|
-
color: colors,
|
|
2460
|
-
tooltip: { trigger: 'item' },
|
|
2461
|
-
legend: {
|
|
2462
|
-
type: 'scroll',
|
|
2463
|
-
orient: layout.legendOrient,
|
|
2464
|
-
icon: 'circle',
|
|
2465
|
-
itemGap: 12,
|
|
2466
|
-
right: layout.legendRight,
|
|
2467
|
-
top: layout.legendTop,
|
|
2468
|
-
left: layout.legendLeft,
|
|
2469
|
-
bottom: layout.legendBottom,
|
|
2470
|
-
width: layout.legendWidth,
|
|
2471
|
-
formatter: (name) => {
|
|
2472
|
-
const item = data.find((d) => d.name === name);
|
|
2473
|
-
return item ? `${name}: ${item.value}` : name;
|
|
2474
|
-
},
|
|
2475
|
-
textStyle: {
|
|
2476
|
-
fontFamily: this.labelFontFamily,
|
|
2477
|
-
fontSize: 13,
|
|
2478
|
-
fontWeight: 500,
|
|
2479
|
-
color: FxUtils.convertColorFromVariable('--text-primary'),
|
|
2480
|
-
overflow: 'truncate',
|
|
2481
|
-
},
|
|
2482
|
-
},
|
|
2483
|
-
series: [
|
|
2484
|
-
{
|
|
2485
|
-
type: 'pie',
|
|
2486
|
-
radius: ['40%', '70%'],
|
|
2487
|
-
center: layout.pieCenter,
|
|
2488
|
-
data,
|
|
2489
|
-
label: {
|
|
2490
|
-
show: this.showPieLabel,
|
|
2491
|
-
position: 'outside',
|
|
2492
|
-
formatter: '{d}%',
|
|
2493
|
-
fontSize: this.labelFontSize,
|
|
2494
|
-
fontFamily: this.labelFontFamily,
|
|
2495
|
-
color: FxUtils.convertColorFromVariable('--text-primary'),
|
|
2496
|
-
textBorderWidth: 0,
|
|
2497
|
-
textBorderColor: 'transparent',
|
|
2498
|
-
},
|
|
2499
|
-
labelLine: {
|
|
2500
|
-
show: this.showPieLabel,
|
|
2501
|
-
length: 7,
|
|
2502
|
-
length2: 7,
|
|
2503
|
-
},
|
|
2504
|
-
},
|
|
2505
|
-
],
|
|
2506
|
-
graphic: {
|
|
2507
|
-
type: 'group',
|
|
2508
|
-
left: layout.graphicLeft,
|
|
2509
|
-
top: layout.graphicTop,
|
|
2510
|
-
bounding: 'raw',
|
|
2511
|
-
children: [
|
|
2512
|
-
{
|
|
2513
|
-
type: 'text',
|
|
2514
|
-
style: {
|
|
2515
|
-
text: total.toString(),
|
|
2516
|
-
fontSize: 24,
|
|
2517
|
-
fontWeight: 600,
|
|
2518
|
-
fontFamily: this.labelFontFamily,
|
|
2519
|
-
fill: FxUtils.convertColorFromVariable('--text-primary'),
|
|
2520
|
-
align: 'center',
|
|
2521
|
-
verticalAlign: 'middle',
|
|
2522
|
-
},
|
|
2523
|
-
},
|
|
2524
|
-
],
|
|
2525
|
-
},
|
|
2526
|
-
};
|
|
2527
|
-
},
|
|
2528
|
-
sunburst: (data, colors) => ({
|
|
2529
|
-
color: colors,
|
|
2530
|
-
series: [
|
|
2531
|
-
{
|
|
2532
|
-
type: 'sunburst',
|
|
2533
|
-
data,
|
|
2534
|
-
radius: ['15%', '90%'],
|
|
2535
|
-
itemStyle: {
|
|
2536
|
-
borderWidth: 1,
|
|
2537
|
-
borderColor: FxUtils.convertColorFromVariable('--border-default'),
|
|
2538
|
-
},
|
|
2539
|
-
label: {
|
|
2540
|
-
rotate: 'tangential',
|
|
2541
|
-
fontSize: this.labelFontSize,
|
|
2542
|
-
fontFamily: this.labelFontFamily,
|
|
2543
|
-
color: FxUtils.convertColorFromVariable('--text-primary'),
|
|
2544
|
-
textBorderWidth: 0,
|
|
2545
|
-
textBorderColor: 'transparent',
|
|
2546
|
-
},
|
|
2547
|
-
},
|
|
2548
|
-
],
|
|
2549
|
-
}),
|
|
2550
|
-
};
|
|
2551
|
-
/* ================= PIE LAYOUT ================= */
|
|
2552
|
-
calcPieLayout(data) {
|
|
2553
|
-
const cw = this.containerWidth || 400;
|
|
2554
|
-
if (this.isMobile) {
|
|
2555
|
-
return {
|
|
2556
|
-
legendOrient: 'horizontal',
|
|
2557
|
-
legendLeft: 'center',
|
|
2558
|
-
legendRight: undefined,
|
|
2559
|
-
legendTop: undefined,
|
|
2560
|
-
legendBottom: 0,
|
|
2561
|
-
legendWidth: undefined,
|
|
2562
|
-
pieCenter: ['50%', '40%'],
|
|
2563
|
-
graphicLeft: '50%',
|
|
2564
|
-
graphicTop: '40%',
|
|
2565
|
-
};
|
|
2231
|
+
async accept() {
|
|
2232
|
+
this.loading = true;
|
|
2233
|
+
if (this.bindings?.['callback']) {
|
|
2234
|
+
await this.bindings.callback();
|
|
2235
|
+
this.loading = false;
|
|
2566
2236
|
}
|
|
2567
|
-
|
|
2568
|
-
const CHAR_WIDTH = 7.5; // approx px per char at fontSize 13
|
|
2569
|
-
const ICON_GAP = 30; // legend icon + padding
|
|
2570
|
-
const longestLabel = data.reduce((max, d) => {
|
|
2571
|
-
return Math.max(max, `${d.name}: ${d.value}`.length);
|
|
2572
|
-
}, 0);
|
|
2573
|
-
const rawLegendPx = longestLabel * CHAR_WIDTH + ICON_GAP;
|
|
2574
|
-
// Clamp: min 100px, max 45% of container
|
|
2575
|
-
const legendPx = Math.max(100, Math.min(rawLegendPx, cw * 0.45));
|
|
2576
|
-
const legendPct = (legendPx / cw) * 100;
|
|
2577
|
-
// Pie center: middle of the remaining space after legend
|
|
2578
|
-
const pieCenterX = Math.round((100 - legendPct) / 2);
|
|
2579
|
-
return {
|
|
2580
|
-
legendOrient: 'vertical',
|
|
2581
|
-
legendLeft: undefined,
|
|
2582
|
-
legendRight: '2%',
|
|
2583
|
-
legendTop: 'middle',
|
|
2584
|
-
legendBottom: undefined,
|
|
2585
|
-
legendWidth: Math.round(legendPx),
|
|
2586
|
-
pieCenter: [`${pieCenterX}%`, '50%'],
|
|
2587
|
-
graphicLeft: `${pieCenterX}%`,
|
|
2588
|
-
graphicTop: '50%',
|
|
2589
|
-
};
|
|
2590
|
-
}
|
|
2591
|
-
/* ================= BUILD ================= */
|
|
2592
|
-
detectType() {
|
|
2593
|
-
if (this.type !== 'auto')
|
|
2594
|
-
return this.type;
|
|
2595
|
-
if (this.data?.children)
|
|
2596
|
-
return 'sunburst';
|
|
2597
|
-
if (this.data?.categories && this.data?.values)
|
|
2598
|
-
return 'bar';
|
|
2599
|
-
if (Array.isArray(this.data))
|
|
2600
|
-
return 'pie';
|
|
2601
|
-
return 'bar';
|
|
2602
|
-
}
|
|
2603
|
-
buildOptions() {
|
|
2604
|
-
const type = this.detectType();
|
|
2605
|
-
const palette = this.resolvePalette();
|
|
2606
|
-
const base = this.registry[type]?.(this.data, palette) || {};
|
|
2607
|
-
return {
|
|
2608
|
-
...base,
|
|
2609
|
-
...this.options,
|
|
2610
|
-
};
|
|
2237
|
+
this.ref.close(true);
|
|
2611
2238
|
}
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
'rgba(var(--success) / 1)',
|
|
2615
|
-
'rgba(var(--information) / 1)',
|
|
2616
|
-
'rgba(var(--critical) / 1)',
|
|
2617
|
-
'rgba(var(--danger) / 1)',
|
|
2618
|
-
'rgba(var(--warning) / 1)',
|
|
2619
|
-
'rgba(var(--discovery) / 1)',
|
|
2620
|
-
];
|
|
2621
|
-
const palette = this.palette?.length ? this.palette : defaults;
|
|
2622
|
-
return palette.map((raw) => {
|
|
2623
|
-
if (!raw.includes('var('))
|
|
2624
|
-
return raw;
|
|
2625
|
-
const cssVar = raw.match(/var\((.*?)\)/)?.[1];
|
|
2626
|
-
const rgb = getComputedStyle(document.body)
|
|
2627
|
-
.getPropertyValue(cssVar || '')
|
|
2628
|
-
.trim()
|
|
2629
|
-
.replace(/\s+/g, ',');
|
|
2630
|
-
return `rgba(${rgb},1)`;
|
|
2631
|
-
});
|
|
2239
|
+
cancel() {
|
|
2240
|
+
this.ref.close(false);
|
|
2632
2241
|
}
|
|
2633
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2634
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2242
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ConfirmationDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
2243
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: ConfirmationDialogComponent, isStandalone: true, selector: "fx-ui-confirmation-dialog", ngImport: i0, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 mat-dialog-title class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: ButtonComponent, selector: "fx-ui-button", inputs: ["label", "disabled", "buttonVariant", "icon", "class", "loading", "type", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2635
2244
|
}
|
|
2636
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2245
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
|
|
2637
2246
|
type: Component,
|
|
2638
|
-
args: [{ selector: 'fx-ui-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2247
|
+
args: [{ selector: 'fx-ui-confirmation-dialog', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2248
|
+
MatDialogTitle,
|
|
2249
|
+
CdkScrollable,
|
|
2250
|
+
MatDialogContent,
|
|
2251
|
+
MatDialogActions,
|
|
2252
|
+
ButtonComponent,
|
|
2253
|
+
], template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 mat-dialog-title class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n" }]
|
|
2254
|
+
}], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
|
|
2255
|
+
type: Inject,
|
|
2256
|
+
args: [MAT_DIALOG_DATA]
|
|
2257
|
+
}] }] });
|
|
2258
|
+
|
|
2259
|
+
/**
|
|
2260
|
+
* Thin façade over MatDialog so app code never imports @angular/material
|
|
2261
|
+
* directly (behavior-layer rule, Playbook §5.1). Same semantics — the
|
|
2262
|
+
* returned ref is the Material one, typed through this service.
|
|
2263
|
+
*/
|
|
2264
|
+
class FxDialogService {
|
|
2265
|
+
dialog = inject(MatDialog);
|
|
2266
|
+
open(component, config) {
|
|
2267
|
+
return this.dialog.open(component, config);
|
|
2268
|
+
}
|
|
2269
|
+
/** Standard confirmation flow — resolves true when the user confirms. */
|
|
2270
|
+
async confirm(options = {}) {
|
|
2271
|
+
// ConfirmationDialogComponent reads MAT_DIALOG_DATA as its bindings and
|
|
2272
|
+
// closes with true/false.
|
|
2273
|
+
const ref = this.dialog.open(ConfirmationDialogComponent, { data: { ...options } });
|
|
2274
|
+
return !!(await firstValueFrom(ref.afterClosed()));
|
|
2275
|
+
}
|
|
2276
|
+
closeAll() {
|
|
2277
|
+
this.dialog.closeAll();
|
|
2278
|
+
}
|
|
2279
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2280
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxDialogService, providedIn: 'root' });
|
|
2281
|
+
}
|
|
2282
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxDialogService, decorators: [{
|
|
2283
|
+
type: Injectable,
|
|
2284
|
+
args: [{ providedIn: 'root' }]
|
|
2285
|
+
}] });
|
|
2671
2286
|
|
|
2672
2287
|
class FxComponent {
|
|
2673
2288
|
/**
|
|
@@ -2677,6 +2292,9 @@ class FxComponent {
|
|
|
2677
2292
|
* bind to an ancestor's NgControl.
|
|
2678
2293
|
*/
|
|
2679
2294
|
ngControl = inject(NgControl, { optional: true, self: true });
|
|
2295
|
+
/** With OnPush, programmatic writes (form.setValue / setDisabledState) must
|
|
2296
|
+
* mark the view — CVA calls come from outside the component's own events. */
|
|
2297
|
+
cdr = inject(ChangeDetectorRef);
|
|
2680
2298
|
disabled = false;
|
|
2681
2299
|
value;
|
|
2682
2300
|
onChange = () => undefined;
|
|
@@ -2701,6 +2319,7 @@ class FxComponent {
|
|
|
2701
2319
|
// Pass through as-is. Coercing null to '' here broke boolean/number
|
|
2702
2320
|
// controls; string controls that want '' as their empty value override.
|
|
2703
2321
|
this.value = value;
|
|
2322
|
+
this.cdr.markForCheck();
|
|
2704
2323
|
}
|
|
2705
2324
|
registerOnChange(fn) {
|
|
2706
2325
|
this.onChange = fn;
|
|
@@ -2710,6 +2329,7 @@ class FxComponent {
|
|
|
2710
2329
|
}
|
|
2711
2330
|
setDisabledState(isDisabled) {
|
|
2712
2331
|
this.disabled = isDisabled;
|
|
2332
|
+
this.cdr.markForCheck();
|
|
2713
2333
|
}
|
|
2714
2334
|
get invalid() {
|
|
2715
2335
|
return !!(this.ngControl?.invalid && this.ngControl?.touched);
|
|
@@ -2763,10 +2383,10 @@ class FxComponent {
|
|
|
2763
2383
|
const firstKey = Object.keys(this.errors)[0];
|
|
2764
2384
|
return messages[firstKey] || `Invalid ${label ?? 'value'}`;
|
|
2765
2385
|
}
|
|
2766
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2767
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
2386
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2387
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: FxComponent, isStandalone: true, inputs: { disabled: "disabled" }, ngImport: i0 });
|
|
2768
2388
|
}
|
|
2769
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2389
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxComponent, decorators: [{
|
|
2770
2390
|
type: Directive
|
|
2771
2391
|
}], ctorParameters: () => [], propDecorators: { disabled: [{
|
|
2772
2392
|
type: Input
|
|
@@ -2775,8 +2395,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2775
2395
|
class CheckboxComponent extends FxComponent {
|
|
2776
2396
|
ref;
|
|
2777
2397
|
label = '';
|
|
2778
|
-
rounded;
|
|
2779
|
-
valueChange =
|
|
2398
|
+
rounded = input(...(ngDevMode ? [undefined, { debugName: "rounded" }] : /* istanbul ignore next */ []));
|
|
2399
|
+
valueChange = output();
|
|
2780
2400
|
constructor(ref) {
|
|
2781
2401
|
super();
|
|
2782
2402
|
this.ref = ref;
|
|
@@ -2796,59 +2416,63 @@ class CheckboxComponent extends FxComponent {
|
|
|
2796
2416
|
markTouched() {
|
|
2797
2417
|
this.onTouched();
|
|
2798
2418
|
}
|
|
2799
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2800
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2419
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CheckboxComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2420
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: CheckboxComponent, isStandalone: true, selector: "fx-ui-checkbox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<label\n class=\"flex items-center gap-normal cursor-pointer select-none\"\n [class.opacity-50]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n>\n <!-- sr-only (not `hidden`): keeps the input focusable and in the a11y tree -->\n <input\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"relative w-4 h-4 border rounded-full transition-colors duration-150 shrink-0 peer-focus-visible:ring-2 peer-focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'rounded-full': rounded(),\n 'rounded-sm': !rounded(),\n 'border-border-strong bg-transparent': !value,\n 'border-transparent bg-gradient-primary': value,\n }\"\n >\n <!-- Keep SVG space reserved always -->\n <span class=\"absolute inset-0 flex items-center justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"text-white w-4 h-4 transition-opacity duration-150\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [style.opacity]=\"value ? 1 : 0\"\n >\n <path d=\"M5 13l4 4L19 7\" />\n </svg>\n </span>\n </span>\n\n @if (label) {\n <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2801
2421
|
}
|
|
2802
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2422
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CheckboxComponent, decorators: [{
|
|
2803
2423
|
type: Component,
|
|
2804
|
-
args: [{ selector: 'fx-ui-checkbox',
|
|
2424
|
+
args: [{ selector: 'fx-ui-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<label\n class=\"flex items-center gap-normal cursor-pointer select-none\"\n [class.opacity-50]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n>\n <!-- sr-only (not `hidden`): keeps the input focusable and in the a11y tree -->\n <input\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"relative w-4 h-4 border rounded-full transition-colors duration-150 shrink-0 peer-focus-visible:ring-2 peer-focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'rounded-full': rounded(),\n 'rounded-sm': !rounded(),\n 'border-border-strong bg-transparent': !value,\n 'border-transparent bg-gradient-primary': value,\n }\"\n >\n <!-- Keep SVG space reserved always -->\n <span class=\"absolute inset-0 flex items-center justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"text-white w-4 h-4 transition-opacity duration-150\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [style.opacity]=\"value ? 1 : 0\"\n >\n <path d=\"M5 13l4 4L19 7\" />\n </svg>\n </span>\n </span>\n\n @if (label) {\n <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n }\n</label>\n" }]
|
|
2805
2425
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
|
|
2806
2426
|
type: Input
|
|
2807
|
-
}], rounded: [{
|
|
2808
|
-
type: Input
|
|
2809
|
-
}], valueChange: [{
|
|
2810
|
-
type: Output
|
|
2811
|
-
}] } });
|
|
2427
|
+
}], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
2812
2428
|
|
|
2813
2429
|
class CircleProgressBar {
|
|
2814
|
-
percent = 0;
|
|
2815
|
-
showPercent = false;
|
|
2430
|
+
percent = input(0, ...(ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []));
|
|
2431
|
+
showPercent = input(false, ...(ngDevMode ? [{ debugName: "showPercent" }] : /* istanbul ignore next */ []));
|
|
2816
2432
|
radius = 35;
|
|
2817
2433
|
stroke = 10;
|
|
2818
2434
|
normalizedRadius = this.radius - this.stroke / 2;
|
|
2819
2435
|
circumference = 2 * Math.PI * this.normalizedRadius;
|
|
2820
2436
|
get dashOffset() {
|
|
2821
|
-
const clamped = Math.max(0, Math.min(100, this.percent));
|
|
2437
|
+
const clamped = Math.max(0, Math.min(100, this.percent()));
|
|
2822
2438
|
return this.circumference - (clamped / 100) * this.circumference;
|
|
2823
2439
|
}
|
|
2824
2440
|
get ariaLabel() {
|
|
2825
|
-
return `${Math.round(this.percent)}%`;
|
|
2441
|
+
return `${Math.round(this.percent())}%`;
|
|
2826
2442
|
}
|
|
2827
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2828
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2443
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CircleProgressBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2444
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: CircleProgressBar, isStandalone: true, selector: "fx-ui-circle-progress-bar", inputs: { percent: { classPropertyName: "percent", publicName: "percent", isSignal: true, isRequired: false, transformFunction: null }, showPercent: { classPropertyName: "showPercent", publicName: "showPercent", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex items-center justify-center w-full h-full\">\n <svg\n class=\"transform -rotate-90 block\"\n [attr.viewBox]=\"'0 0 ' + radius * 2 + ' ' + radius * 2\"\n width=\"100%\"\n height=\"100%\"\n >\n <circle\n class=\"opacity-20\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n ></circle>\n\n <circle\n class=\"stroke-current\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"circumference\"\n [attr.stroke-dashoffset]=\"dashOffset\"\n style=\"transition: stroke-dashoffset 300ms linear\"\n ></circle>\n\n @if(showPercent()){\n <text\n [attr.x]=\"radius\"\n [attr.y]=\"radius\"\n dominant-baseline=\"central\"\n text-anchor=\"middle\"\n class=\"text-xs font-medium\"\n fill=\"currentColor\"\n >\n {{ percent() }}%\n </text>\n }\n </svg>\n</div>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2829
2445
|
}
|
|
2830
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2446
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CircleProgressBar, decorators: [{
|
|
2831
2447
|
type: Component,
|
|
2832
|
-
args: [{ selector: 'fx-ui-circle-progress-bar',
|
|
2833
|
-
}], propDecorators: { percent: [{
|
|
2834
|
-
type: Input
|
|
2835
|
-
}], showPercent: [{
|
|
2836
|
-
type: Input
|
|
2837
|
-
}] } });
|
|
2448
|
+
args: [{ selector: 'fx-ui-circle-progress-bar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex items-center justify-center w-full h-full\">\n <svg\n class=\"transform -rotate-90 block\"\n [attr.viewBox]=\"'0 0 ' + radius * 2 + ' ' + radius * 2\"\n width=\"100%\"\n height=\"100%\"\n >\n <circle\n class=\"opacity-20\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n ></circle>\n\n <circle\n class=\"stroke-current\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"circumference\"\n [attr.stroke-dashoffset]=\"dashOffset\"\n style=\"transition: stroke-dashoffset 300ms linear\"\n ></circle>\n\n @if(showPercent()){\n <text\n [attr.x]=\"radius\"\n [attr.y]=\"radius\"\n dominant-baseline=\"central\"\n text-anchor=\"middle\"\n class=\"text-xs font-medium\"\n fill=\"currentColor\"\n >\n {{ percent() }}%\n </text>\n }\n </svg>\n</div>\n" }]
|
|
2449
|
+
}], propDecorators: { percent: [{ type: i0.Input, args: [{ isSignal: true, alias: "percent", required: false }] }], showPercent: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPercent", required: false }] }] } });
|
|
2838
2450
|
|
|
2839
2451
|
let nextPickerId = 0;
|
|
2452
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
2453
|
+
/**
|
|
2454
|
+
* Date/time field backed by first-party Material pickers (mat-datepicker +
|
|
2455
|
+
* mat-timepicker, the latter first-party since Material 19) — replaces the
|
|
2456
|
+
* former @danielmoncada/angular-datetime-picker + moment adapter stack.
|
|
2457
|
+
*
|
|
2458
|
+
* The public contract is unchanged: the CVA value is a plain string
|
|
2459
|
+
* ('YYYY-MM-DD HH:mm' for type 'both', 'YYYY-MM-DD' for 'calendar',
|
|
2460
|
+
* 'HH:mm' for 'timer'), so existing forms keep working as-is.
|
|
2461
|
+
*/
|
|
2840
2462
|
class DatetimePicker extends FxComponent {
|
|
2841
2463
|
ref;
|
|
2842
2464
|
label;
|
|
2843
|
-
placeholder = 'Select date and time';
|
|
2844
|
-
required = false;
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2465
|
+
placeholder = input('Select date and time', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
2466
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
2467
|
+
/** 'both' | 'calendar' | 'timer' — same values the Owl picker accepted. */
|
|
2468
|
+
type = input('both', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
2469
|
+
minDate = input(...(ngDevMode ? [undefined, { debugName: "minDate" }] : /* istanbul ignore next */ []));
|
|
2470
|
+
maxDate = input(...(ngDevMode ? [undefined, { debugName: "maxDate" }] : /* istanbul ignore next */ []));
|
|
2848
2471
|
errorMessages = {};
|
|
2849
|
-
validateFn;
|
|
2472
|
+
validateFn = input(...(ngDevMode ? [undefined, { debugName: "validateFn" }] : /* istanbul ignore next */ []));
|
|
2850
2473
|
fieldId = `fx-datetime-${nextPickerId++}`;
|
|
2851
|
-
|
|
2474
|
+
/** Internal Date the Material pickers operate on; `value` stays a string. */
|
|
2475
|
+
dateValue = null;
|
|
2852
2476
|
constructor(ref) {
|
|
2853
2477
|
super();
|
|
2854
2478
|
this.ref = ref;
|
|
@@ -2858,65 +2482,119 @@ class DatetimePicker extends FxComponent {
|
|
|
2858
2482
|
this.ref.detectChanges();
|
|
2859
2483
|
});
|
|
2860
2484
|
}
|
|
2485
|
+
get showDate() {
|
|
2486
|
+
return this.type() !== 'timer';
|
|
2487
|
+
}
|
|
2488
|
+
get showTime() {
|
|
2489
|
+
return this.type() !== 'calendar';
|
|
2490
|
+
}
|
|
2491
|
+
get min() {
|
|
2492
|
+
return this.toDate(this.minDate());
|
|
2493
|
+
}
|
|
2494
|
+
get max() {
|
|
2495
|
+
return this.toDate(this.maxDate());
|
|
2496
|
+
}
|
|
2861
2497
|
onBlur() {
|
|
2862
2498
|
this.onTouched();
|
|
2863
|
-
this.validate(this.validateFn);
|
|
2499
|
+
this.validate(this.validateFn());
|
|
2864
2500
|
}
|
|
2865
2501
|
writeValue(value) {
|
|
2866
2502
|
this.value = value ?? '';
|
|
2867
|
-
this.
|
|
2503
|
+
this.dateValue = this.toDate(value);
|
|
2868
2504
|
this.ref.markForCheck();
|
|
2869
2505
|
}
|
|
2870
|
-
|
|
2506
|
+
onDateChange(date) {
|
|
2871
2507
|
if (this.disabled)
|
|
2872
2508
|
return;
|
|
2873
|
-
|
|
2874
|
-
|
|
2509
|
+
const next = date ? new Date(date) : null;
|
|
2510
|
+
// Keep the already-picked time when only the calendar part changes.
|
|
2511
|
+
if (next && this.dateValue) {
|
|
2512
|
+
next.setHours(this.dateValue.getHours(), this.dateValue.getMinutes(), 0, 0);
|
|
2513
|
+
}
|
|
2514
|
+
this.commit(next);
|
|
2515
|
+
}
|
|
2516
|
+
onTimeChange(time) {
|
|
2517
|
+
if (this.disabled || !time)
|
|
2518
|
+
return;
|
|
2519
|
+
const next = this.dateValue ? new Date(this.dateValue) : new Date();
|
|
2520
|
+
next.setHours(time.getHours(), time.getMinutes(), 0, 0);
|
|
2521
|
+
this.commit(next);
|
|
2522
|
+
}
|
|
2523
|
+
commit(next) {
|
|
2524
|
+
this.dateValue = next;
|
|
2525
|
+
this.value = this.format(next);
|
|
2526
|
+
this.onChange(this.value);
|
|
2875
2527
|
this.onTouched();
|
|
2528
|
+
this.ref.markForCheck();
|
|
2876
2529
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2530
|
+
toDate(value) {
|
|
2531
|
+
if (!value)
|
|
2532
|
+
return null;
|
|
2533
|
+
if (value instanceof Date)
|
|
2534
|
+
return isNaN(value.getTime()) ? null : value;
|
|
2535
|
+
// Accepted string shapes: 'YYYY-MM-DD', 'YYYY-MM-DD HH:mm[:ss]', 'HH:mm'.
|
|
2536
|
+
const s = String(value).trim();
|
|
2537
|
+
if (/^\d{2}:\d{2}/.test(s)) {
|
|
2538
|
+
const d = new Date();
|
|
2539
|
+
d.setHours(+s.slice(0, 2), +s.slice(3, 5), 0, 0);
|
|
2540
|
+
return d;
|
|
2541
|
+
}
|
|
2542
|
+
const d = new Date(s.replace(' ', 'T'));
|
|
2543
|
+
return isNaN(d.getTime()) ? null : d;
|
|
2544
|
+
}
|
|
2545
|
+
format(d) {
|
|
2546
|
+
if (!d)
|
|
2547
|
+
return '';
|
|
2548
|
+
const date = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
2549
|
+
const time = `${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
2550
|
+
const type = this.type();
|
|
2551
|
+
if (type === 'calendar')
|
|
2552
|
+
return date;
|
|
2553
|
+
if (type === 'timer')
|
|
2554
|
+
return time;
|
|
2555
|
+
return `${date} ${time}`;
|
|
2556
|
+
}
|
|
2557
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DatetimePicker, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2558
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: DatetimePicker, isStandalone: true, selector: "fx-ui-datetime-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: false, isRequired: false, transformFunction: null }, validateFn: { classPropertyName: "validateFn", publicName: "validateFn", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
2559
|
+
provideNativeDateAdapter(),
|
|
2560
|
+
// en-GB display ⇒ DD/MM/YYYY + 24h — matches FxUtils.formatDateTime.
|
|
2561
|
+
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
|
|
2562
|
+
], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col mb-4 w-full text-left\">\n @if (label) {\n <label class=\"txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <div class=\"flex gap-normal\">\n @if (showDate) {\n <div class=\"relative flex-1\">\n <input\n [id]=\"fieldId\"\n [matDatepicker]=\"datePicker\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [min]=\"min\"\n [max]=\"max\"\n [value]=\"dateValue\"\n (dateChange)=\"onDateChange($event.value)\"\n (click)=\"!disabled && datePicker.open()\"\n (blur)=\"onBlur()\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n (click)=\"!disabled && datePicker.open()\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"calendar\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n <mat-datepicker #datePicker></mat-datepicker>\n </div>\n }\n @if (showTime) {\n <div class=\"relative\" [class.flex-1]=\"!showDate\" [class.w-32]=\"showDate\">\n <input\n [matTimepicker]=\"timePicker\"\n placeholder=\"HH:mm\"\n [disabled]=\"disabled\"\n [value]=\"dateValue\"\n (valueChange)=\"onTimeChange($event)\"\n (click)=\"!disabled && timePicker.open()\"\n (blur)=\"onBlur()\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n (click)=\"!disabled && timePicker.open()\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"clock\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n <mat-timepicker #timePicker></mat-timepicker>\n </div>\n }\n </div>\n @if (invalid) {\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;::ng-deep .mat-datepicker-content,::ng-deep mat-timepicker .mat-timepicker-panel,::ng-deep .mat-timepicker-panel{border-radius:.75rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 10px 10px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);color:rgb(var(--text-primary));--mat-datepicker-calendar-container-background-color: rgb(var(--bg-primary));--mat-datepicker-calendar-container-text-color: rgb(var(--text-primary));--mat-datepicker-calendar-date-text-color: rgb(var(--text-primary));--mat-datepicker-calendar-date-selected-state-background-color: rgb(var(--primary));--mat-datepicker-calendar-date-selected-state-text-color: #fff;--mat-datepicker-calendar-date-today-outline-color: rgb(var(--primary));--mat-datepicker-calendar-date-hover-state-background-color: rgb(var(--bg-primary-hover));--mat-datepicker-calendar-header-text-color: rgb(var(--text-secondary));--mat-datepicker-calendar-period-button-text-color: rgb(var(--text-primary));--mat-datepicker-calendar-navigation-button-icon-color: rgb(var(--text-primary));--mat-datepicker-calendar-date-disabled-state-text-color: rgb(var(--text-placeholder));--mat-timepicker-container-background-color: rgb(var(--bg-primary))}::ng-deep .mat-timepicker-panel .mat-mdc-option{color:rgb(var(--text-primary))}::ng-deep .mat-timepicker-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled){background-color:rgb(var(--bg-primary-hover))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i1$2.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i1$2.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "ngmodule", type: MatTimepickerModule }, { kind: "component", type: i2$2.MatTimepicker, selector: "mat-timepicker", inputs: ["interval", "options", "disableRipple", "aria-label", "aria-labelledby", "panelClass"], outputs: ["selected", "opened", "closed"], exportAs: ["matTimepicker"] }, { kind: "directive", type: i2$2.MatTimepickerInput, selector: "input[matTimepicker]", inputs: ["value", "matTimepicker", "matTimepickerMin", "matTimepickerMax", "matTimepickerOpenOnClick", "disabled"], outputs: ["valueChange"], exportAs: ["matTimepickerInput"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2879
2563
|
}
|
|
2880
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2564
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DatetimePicker, decorators: [{
|
|
2881
2565
|
type: Component,
|
|
2882
|
-
args: [{ selector: 'fx-ui-datetime-picker',
|
|
2566
|
+
args: [{ selector: 'fx-ui-datetime-picker', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatDatepickerModule, MatTimepickerModule, HeroIconComponent], providers: [
|
|
2567
|
+
provideNativeDateAdapter(),
|
|
2568
|
+
// en-GB display ⇒ DD/MM/YYYY + 24h — matches FxUtils.formatDateTime.
|
|
2569
|
+
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
|
|
2570
|
+
], template: "<div class=\"flex flex-col mb-4 w-full text-left\">\n @if (label) {\n <label class=\"txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <div class=\"flex gap-normal\">\n @if (showDate) {\n <div class=\"relative flex-1\">\n <input\n [id]=\"fieldId\"\n [matDatepicker]=\"datePicker\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [min]=\"min\"\n [max]=\"max\"\n [value]=\"dateValue\"\n (dateChange)=\"onDateChange($event.value)\"\n (click)=\"!disabled && datePicker.open()\"\n (blur)=\"onBlur()\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n (click)=\"!disabled && datePicker.open()\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"calendar\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n <mat-datepicker #datePicker></mat-datepicker>\n </div>\n }\n @if (showTime) {\n <div class=\"relative\" [class.flex-1]=\"!showDate\" [class.w-32]=\"showDate\">\n <input\n [matTimepicker]=\"timePicker\"\n placeholder=\"HH:mm\"\n [disabled]=\"disabled\"\n [value]=\"dateValue\"\n (valueChange)=\"onTimeChange($event)\"\n (click)=\"!disabled && timePicker.open()\"\n (blur)=\"onBlur()\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n (click)=\"!disabled && timePicker.open()\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"clock\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n <mat-timepicker #timePicker></mat-timepicker>\n </div>\n }\n </div>\n @if (invalid) {\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;::ng-deep .mat-datepicker-content,::ng-deep mat-timepicker .mat-timepicker-panel,::ng-deep .mat-timepicker-panel{border-radius:.75rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 10px 10px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);color:rgb(var(--text-primary));--mat-datepicker-calendar-container-background-color: rgb(var(--bg-primary));--mat-datepicker-calendar-container-text-color: rgb(var(--text-primary));--mat-datepicker-calendar-date-text-color: rgb(var(--text-primary));--mat-datepicker-calendar-date-selected-state-background-color: rgb(var(--primary));--mat-datepicker-calendar-date-selected-state-text-color: #fff;--mat-datepicker-calendar-date-today-outline-color: rgb(var(--primary));--mat-datepicker-calendar-date-hover-state-background-color: rgb(var(--bg-primary-hover));--mat-datepicker-calendar-header-text-color: rgb(var(--text-secondary));--mat-datepicker-calendar-period-button-text-color: rgb(var(--text-primary));--mat-datepicker-calendar-navigation-button-icon-color: rgb(var(--text-primary));--mat-datepicker-calendar-date-disabled-state-text-color: rgb(var(--text-placeholder));--mat-timepicker-container-background-color: rgb(var(--bg-primary))}::ng-deep .mat-timepicker-panel .mat-mdc-option{color:rgb(var(--text-primary))}::ng-deep .mat-timepicker-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled){background-color:rgb(var(--bg-primary-hover))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
2883
2571
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
|
|
2884
2572
|
type: Input
|
|
2885
|
-
}], placeholder: [{
|
|
2886
|
-
type: Input
|
|
2887
|
-
}], required: [{
|
|
2888
|
-
type: Input
|
|
2889
|
-
}], type: [{
|
|
2890
|
-
type: Input
|
|
2891
|
-
}], minDate: [{
|
|
2892
|
-
type: Input
|
|
2893
|
-
}], maxDate: [{
|
|
2894
|
-
type: Input
|
|
2895
|
-
}], errorMessages: [{
|
|
2896
|
-
type: Input
|
|
2897
|
-
}], validateFn: [{
|
|
2573
|
+
}], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], errorMessages: [{
|
|
2898
2574
|
type: Input
|
|
2899
|
-
}] } });
|
|
2575
|
+
}], validateFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "validateFn", required: false }] }] } });
|
|
2900
2576
|
|
|
2901
2577
|
class DndUploadComponent {
|
|
2902
|
-
|
|
2578
|
+
cdr = inject(ChangeDetectorRef);
|
|
2579
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
2903
2580
|
accept = '';
|
|
2904
|
-
maxSizeMB = 10;
|
|
2905
|
-
strictSize = true;
|
|
2581
|
+
maxSizeMB = input(10, ...(ngDevMode ? [{ debugName: "maxSizeMB" }] : /* istanbul ignore next */ []));
|
|
2582
|
+
strictSize = input(true, ...(ngDevMode ? [{ debugName: "strictSize" }] : /* istanbul ignore next */ []));
|
|
2906
2583
|
/** Icon name from heroicons (outline). Default: 'arrow-up-tray' */
|
|
2907
|
-
icon = 'arrow-up-tray';
|
|
2584
|
+
icon = input('arrow-up-tray', ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
2908
2585
|
/** CSS color value for accent (border, icon, link). Default uses --gradient-primary-start */
|
|
2909
|
-
accentColor = '';
|
|
2910
|
-
fileDrop =
|
|
2911
|
-
fileClick =
|
|
2912
|
-
uploadComplete =
|
|
2913
|
-
uploadError =
|
|
2586
|
+
accentColor = input('', ...(ngDevMode ? [{ debugName: "accentColor" }] : /* istanbul ignore next */ []));
|
|
2587
|
+
fileDrop = output();
|
|
2588
|
+
fileClick = output();
|
|
2589
|
+
uploadComplete = output();
|
|
2590
|
+
uploadError = output();
|
|
2914
2591
|
isDragOver = false;
|
|
2915
2592
|
isOpening = false;
|
|
2916
2593
|
get accentStyle() {
|
|
2917
|
-
|
|
2594
|
+
const accentColor = this.accentColor();
|
|
2595
|
+
if (!accentColor)
|
|
2918
2596
|
return {};
|
|
2919
|
-
return { '--dnd-accent':
|
|
2597
|
+
return { '--dnd-accent': accentColor };
|
|
2920
2598
|
}
|
|
2921
2599
|
onDragOver(event) {
|
|
2922
2600
|
event.preventDefault();
|
|
@@ -2943,6 +2621,7 @@ class DndUploadComponent {
|
|
|
2943
2621
|
setTimeout(() => {
|
|
2944
2622
|
inputEl?.click();
|
|
2945
2623
|
this.isOpening = false;
|
|
2624
|
+
this.cdr.markForCheck();
|
|
2946
2625
|
}, 0);
|
|
2947
2626
|
}
|
|
2948
2627
|
onFileSelected(event) {
|
|
@@ -2961,10 +2640,10 @@ class DndUploadComponent {
|
|
|
2961
2640
|
.filter((t) => t);
|
|
2962
2641
|
for (const file of files) {
|
|
2963
2642
|
const sizeMB = file.size / 1024 / 1024;
|
|
2964
|
-
if (this.strictSize && sizeMB > this.maxSizeMB) {
|
|
2643
|
+
if (this.strictSize() && sizeMB > this.maxSizeMB()) {
|
|
2965
2644
|
this.uploadError.emit({
|
|
2966
2645
|
file,
|
|
2967
|
-
reason: `File too large: ${sizeMB.toFixed(2)} MB > ${this.maxSizeMB} MB`,
|
|
2646
|
+
reason: `File too large: ${sizeMB.toFixed(2)} MB > ${this.maxSizeMB()} MB`,
|
|
2968
2647
|
});
|
|
2969
2648
|
continue;
|
|
2970
2649
|
}
|
|
@@ -2998,63 +2677,15 @@ class DndUploadComponent {
|
|
|
2998
2677
|
return a === fileType;
|
|
2999
2678
|
});
|
|
3000
2679
|
}
|
|
3001
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3002
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2680
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DndUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2681
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: DndUploadComponent, isStandalone: true, selector: "fx-ui-dnd-upload", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: false, isRequired: false, transformFunction: null }, maxSizeMB: { classPropertyName: "maxSizeMB", publicName: "maxSizeMB", isSignal: true, isRequired: false, transformFunction: null }, strictSize: { classPropertyName: "strictSize", publicName: "strictSize", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileDrop: "fileDrop", fileClick: "fileClick", uploadComplete: "uploadComplete", uploadError: "uploadError" }, ngImport: i0, template: "<div\n class=\"dnd-wrapper\"\n [ngStyle]=\"accentStyle\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div\n role=\"button\"\n tabindex=\"0\"\n class=\"dnd-area\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onAreaClick(fileInput, $event)\"\n (keydown.enter)=\"onAreaClick(fileInput, $event)\"\n >\n <fx-ui-hero-icon\n [icon]=\"icon()\"\n [size]=\"40\"\n class=\"flex dnd-icon\"\n ></fx-ui-hero-icon>\n <div class=\"dnd-text\">\n <span class=\"dnd-link\">Click to upload</span>\n <span class=\"dnd-or\">or drag and drop</span>\n </div>\n <div class=\"dnd-hint\">\n @if (accept) {\n Accepted: {{ accept }}\n } @else {\n Any file type\n }\n \u2014 Max {{ maxSizeMB() }} MB\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"dnd-input\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [attr.accept]=\"accept\"\n (change)=\"onFileSelected($event)\"\n />\n </div>\n</div>\n", styles: [":host{--dnd-accent: rgba(var(--gradient-primary-start) / 1)}.dnd-wrapper{display:block;width:100%}.dnd-area{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:160px;padding:32px 24px;border:2px dashed color-mix(in srgb,var(--dnd-accent) 40%,transparent);border-radius:12px;background:color-mix(in srgb,var(--dnd-accent) 4%,transparent);cursor:pointer;outline:none;transition:all .2s ease;position:relative}.dnd-area:hover{border-color:color-mix(in srgb,var(--dnd-accent) 70%,transparent);background:color-mix(in srgb,var(--dnd-accent) 8%,transparent)}.dnd-area:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--dnd-accent) 20%,transparent)}.dnd-area.drag-over{border-color:var(--dnd-accent);background:color-mix(in srgb,var(--dnd-accent) 10%,transparent)}.dnd-icon{color:var(--dnd-accent)}.dnd-text{display:flex;align-items:center;gap:4px;font-size:14px;flex-wrap:wrap;justify-content:center}.dnd-link{color:var(--dnd-accent);font-weight:600;text-decoration:underline}.dnd-or{color:rgba(var(--text-secondary)/1)}.dnd-hint{font-size:12px;color:rgba(var(--text-secondary)/.7)}.dnd-input{position:absolute;width:0;height:0;overflow:hidden;opacity:0}@media(max-width:640px){.dnd-area{min-height:120px;padding:24px 16px}.dnd-text{font-size:13px}}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3003
2682
|
}
|
|
3004
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2683
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DndUploadComponent, decorators: [{
|
|
3005
2684
|
type: Component,
|
|
3006
|
-
args: [{ selector: 'fx-ui-dnd-upload',
|
|
3007
|
-
}], propDecorators: { multiple: [{
|
|
3008
|
-
type: Input
|
|
3009
|
-
}], accept: [{
|
|
3010
|
-
type: Input
|
|
3011
|
-
}], maxSizeMB: [{
|
|
2685
|
+
args: [{ selector: 'fx-ui-dnd-upload', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle, HeroIconComponent], template: "<div\n class=\"dnd-wrapper\"\n [ngStyle]=\"accentStyle\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div\n role=\"button\"\n tabindex=\"0\"\n class=\"dnd-area\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onAreaClick(fileInput, $event)\"\n (keydown.enter)=\"onAreaClick(fileInput, $event)\"\n >\n <fx-ui-hero-icon\n [icon]=\"icon()\"\n [size]=\"40\"\n class=\"flex dnd-icon\"\n ></fx-ui-hero-icon>\n <div class=\"dnd-text\">\n <span class=\"dnd-link\">Click to upload</span>\n <span class=\"dnd-or\">or drag and drop</span>\n </div>\n <div class=\"dnd-hint\">\n @if (accept) {\n Accepted: {{ accept }}\n } @else {\n Any file type\n }\n \u2014 Max {{ maxSizeMB() }} MB\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"dnd-input\"\n [attr.multiple]=\"multiple() ? '' : null\"\n [attr.accept]=\"accept\"\n (change)=\"onFileSelected($event)\"\n />\n </div>\n</div>\n", styles: [":host{--dnd-accent: rgba(var(--gradient-primary-start) / 1)}.dnd-wrapper{display:block;width:100%}.dnd-area{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:160px;padding:32px 24px;border:2px dashed color-mix(in srgb,var(--dnd-accent) 40%,transparent);border-radius:12px;background:color-mix(in srgb,var(--dnd-accent) 4%,transparent);cursor:pointer;outline:none;transition:all .2s ease;position:relative}.dnd-area:hover{border-color:color-mix(in srgb,var(--dnd-accent) 70%,transparent);background:color-mix(in srgb,var(--dnd-accent) 8%,transparent)}.dnd-area:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--dnd-accent) 20%,transparent)}.dnd-area.drag-over{border-color:var(--dnd-accent);background:color-mix(in srgb,var(--dnd-accent) 10%,transparent)}.dnd-icon{color:var(--dnd-accent)}.dnd-text{display:flex;align-items:center;gap:4px;font-size:14px;flex-wrap:wrap;justify-content:center}.dnd-link{color:var(--dnd-accent);font-weight:600;text-decoration:underline}.dnd-or{color:rgba(var(--text-secondary)/1)}.dnd-hint{font-size:12px;color:rgba(var(--text-secondary)/.7)}.dnd-input{position:absolute;width:0;height:0;overflow:hidden;opacity:0}@media(max-width:640px){.dnd-area{min-height:120px;padding:24px 16px}.dnd-text{font-size:13px}}\n"] }]
|
|
2686
|
+
}], propDecorators: { multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{
|
|
3012
2687
|
type: Input
|
|
3013
|
-
}], strictSize: [{
|
|
3014
|
-
type: Input
|
|
3015
|
-
}], icon: [{
|
|
3016
|
-
type: Input
|
|
3017
|
-
}], accentColor: [{
|
|
3018
|
-
type: Input
|
|
3019
|
-
}], fileDrop: [{
|
|
3020
|
-
type: Output
|
|
3021
|
-
}], fileClick: [{
|
|
3022
|
-
type: Output
|
|
3023
|
-
}], uploadComplete: [{
|
|
3024
|
-
type: Output
|
|
3025
|
-
}], uploadError: [{
|
|
3026
|
-
type: Output
|
|
3027
|
-
}] } });
|
|
3028
|
-
|
|
3029
|
-
class FlowConnection {
|
|
3030
|
-
nodes = [];
|
|
3031
|
-
edges = [];
|
|
3032
|
-
backgroundColor = '--bg-hover-primary';
|
|
3033
|
-
view = ['100%', '400px'];
|
|
3034
|
-
handleConnection(connection) {
|
|
3035
|
-
this.edges = [
|
|
3036
|
-
...this.edges,
|
|
3037
|
-
{
|
|
3038
|
-
id: `${connection.source} -> ${connection.target}`,
|
|
3039
|
-
...connection,
|
|
3040
|
-
},
|
|
3041
|
-
];
|
|
3042
|
-
}
|
|
3043
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FlowConnection, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3044
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: FlowConnection, isStandalone: false, selector: "fx-ui-flow-connection", inputs: { nodes: "nodes", edges: "edges", backgroundColor: "backgroundColor", view: "view" }, ngImport: i0, template: "<vflow\n [background]=\"{\n type: 'solid',\n color: `rgba(var(${backgroundColor})`\n}\"\n [nodes]=\"nodes\"\n [edges]=\"edges\"\n (onConnect)=\"handleConnection($event)\"\n [view]=\"view\"\n/>\n", styles: [""], dependencies: [{ kind: "component", type: i39.VflowComponent, selector: "vflow", inputs: ["view", "minZoom", "maxZoom", "background", "optimization", "entitiesSelectable", "keyboardShortcuts", "connection", "snapGrid", "elevateNodesOnSelect", "elevateEdgesOnSelect", "nodes", "alignmentHelper", "edges"], outputs: ["onComponentNodeEvent"] }, { kind: "directive", type: i39.ConnectionControllerDirective, selector: "[onConnect], [onReconnect], [connect], [reconnect]", outputs: ["onConnect", "connect", "onReconnect", "reconnect"] }] });
|
|
3045
|
-
}
|
|
3046
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FlowConnection, decorators: [{
|
|
3047
|
-
type: Component,
|
|
3048
|
-
args: [{ selector: 'fx-ui-flow-connection', standalone: false, template: "<vflow\n [background]=\"{\n type: 'solid',\n color: `rgba(var(${backgroundColor})`\n}\"\n [nodes]=\"nodes\"\n [edges]=\"edges\"\n (onConnect)=\"handleConnection($event)\"\n [view]=\"view\"\n/>\n" }]
|
|
3049
|
-
}], propDecorators: { nodes: [{
|
|
3050
|
-
type: Input
|
|
3051
|
-
}], edges: [{
|
|
3052
|
-
type: Input
|
|
3053
|
-
}], backgroundColor: [{
|
|
3054
|
-
type: Input
|
|
3055
|
-
}], view: [{
|
|
3056
|
-
type: Input
|
|
3057
|
-
}] } });
|
|
2688
|
+
}], maxSizeMB: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSizeMB", required: false }] }], strictSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "strictSize", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], accentColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "accentColor", required: false }] }], fileDrop: [{ type: i0.Output, args: ["fileDrop"] }], fileClick: [{ type: i0.Output, args: ["fileClick"] }], uploadComplete: [{ type: i0.Output, args: ["uploadComplete"] }], uploadError: [{ type: i0.Output, args: ["uploadError"] }] } });
|
|
3058
2689
|
|
|
3059
2690
|
let nextInputId = 0;
|
|
3060
2691
|
class InputComponent extends FxComponent {
|
|
@@ -3062,18 +2693,18 @@ class InputComponent extends FxComponent {
|
|
|
3062
2693
|
label = '';
|
|
3063
2694
|
tooltip = '';
|
|
3064
2695
|
type = 'text';
|
|
3065
|
-
placeholder = '';
|
|
2696
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
3066
2697
|
errorMessages = {};
|
|
3067
|
-
required = false;
|
|
2698
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
3068
2699
|
suffixIcon;
|
|
3069
|
-
class;
|
|
3070
|
-
maxlength;
|
|
3071
|
-
validateFn;
|
|
3072
|
-
blurred =
|
|
3073
|
-
focused =
|
|
3074
|
-
suffixClick =
|
|
2700
|
+
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2701
|
+
maxlength = input(...(ngDevMode ? [undefined, { debugName: "maxlength" }] : /* istanbul ignore next */ []));
|
|
2702
|
+
validateFn = input(...(ngDevMode ? [undefined, { debugName: "validateFn" }] : /* istanbul ignore next */ []));
|
|
2703
|
+
blurred = output();
|
|
2704
|
+
focused = output();
|
|
2705
|
+
suffixClick = output();
|
|
3075
2706
|
/** Accessible name for the suffix icon button (it renders no text). */
|
|
3076
|
-
suffixAriaLabel = '';
|
|
2707
|
+
suffixAriaLabel = input('', ...(ngDevMode ? [{ debugName: "suffixAriaLabel" }] : /* istanbul ignore next */ []));
|
|
3077
2708
|
fieldId = `fx-input-${nextInputId++}`;
|
|
3078
2709
|
showPassword = false;
|
|
3079
2710
|
validateError = null;
|
|
@@ -3090,8 +2721,9 @@ class InputComponent extends FxComponent {
|
|
|
3090
2721
|
onInput(event) {
|
|
3091
2722
|
const input = event.target;
|
|
3092
2723
|
let newValue = input.value;
|
|
3093
|
-
|
|
3094
|
-
|
|
2724
|
+
const maxlength = this.maxlength();
|
|
2725
|
+
if (maxlength && newValue.length > maxlength) {
|
|
2726
|
+
newValue = newValue.slice(0, maxlength);
|
|
3095
2727
|
input.value = newValue;
|
|
3096
2728
|
}
|
|
3097
2729
|
this.value = newValue;
|
|
@@ -3104,9 +2736,10 @@ class InputComponent extends FxComponent {
|
|
|
3104
2736
|
onBlur() {
|
|
3105
2737
|
this.onTouched();
|
|
3106
2738
|
this.blurred.emit();
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
this.
|
|
2739
|
+
const validateFn = this.validateFn();
|
|
2740
|
+
if (validateFn) {
|
|
2741
|
+
this.validateError = validateFn(this.value);
|
|
2742
|
+
this.validate(validateFn);
|
|
3110
2743
|
}
|
|
3111
2744
|
}
|
|
3112
2745
|
togglePassword() {
|
|
@@ -3127,54 +2760,38 @@ class InputComponent extends FxComponent {
|
|
|
3127
2760
|
return 'number';
|
|
3128
2761
|
return this.type;
|
|
3129
2762
|
}
|
|
3130
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3131
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2763
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2764
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: InputComponent, isStandalone: true, selector: "fx-ui-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: false, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, suffixIcon: { classPropertyName: "suffixIcon", publicName: "suffixIcon", isSignal: false, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, validateFn: { classPropertyName: "validateFn", publicName: "validateFn", isSignal: true, isRequired: false, transformFunction: null }, suffixAriaLabel: { classPropertyName: "suffixAriaLabel", publicName: "suffixAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { blurred: "blurred", focused: "focused", suffixClick: "suffixClick" }, usesInheritance: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class()\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n appTrimOnBlur\n [appTrimOnBlurCollapse]=\"true\"\n [id]=\"fieldId\"\n [type]=\"displayType\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [class]=\"type === 'otp' ? 'input-otp' : 'input-default'\"\n [class.input-invalid]=\"invalid\"\n [class.pr-8]=\"type === 'password' || suffixIcon\"\n [class.txt-otp-input]=\"type === 'otp'\"\n />\n @if (type === 'password' || suffixIcon) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"onSuffixClick()\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"\n type === 'password'\n ? (showPassword ? 'Hide password' : 'Show password')\n : (suffixAriaLabel() || null)\n \"\n [attr.aria-pressed]=\"type === 'password' ? showPassword : null\"\n >\n @if (type === 'password') {\n <fx-ui-hero-icon\n [icon]=\"showPassword ? 'eye-slash' : 'eye'\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n } @else if (suffixIcon) {\n <fx-ui-hero-icon\n [icon]=\"suffixIcon\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n }\n </button>\n }\n </div>\n\n @if (invalid) {\n <div class=\"txt-invalid\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: TrimOnBlurDirective, selector: "[appTrimOnBlur]", inputs: ["appTrimOnBlurCollapse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3132
2765
|
}
|
|
3133
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2766
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InputComponent, decorators: [{
|
|
3134
2767
|
type: Component,
|
|
3135
|
-
args: [{ selector: 'fx-ui-input',
|
|
2768
|
+
args: [{ selector: 'fx-ui-input', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2769
|
+
HeroIconComponent,
|
|
2770
|
+
MatTooltip,
|
|
2771
|
+
TrimOnBlurDirective,
|
|
2772
|
+
], template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class()\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n appTrimOnBlur\n [appTrimOnBlurCollapse]=\"true\"\n [id]=\"fieldId\"\n [type]=\"displayType\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.maxlength]=\"maxlength()\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [attr.aria-required]=\"required() ? true : null\"\n [class]=\"type === 'otp' ? 'input-otp' : 'input-default'\"\n [class.input-invalid]=\"invalid\"\n [class.pr-8]=\"type === 'password' || suffixIcon\"\n [class.txt-otp-input]=\"type === 'otp'\"\n />\n @if (type === 'password' || suffixIcon) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"onSuffixClick()\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"\n type === 'password'\n ? (showPassword ? 'Hide password' : 'Show password')\n : (suffixAriaLabel() || null)\n \"\n [attr.aria-pressed]=\"type === 'password' ? showPassword : null\"\n >\n @if (type === 'password') {\n <fx-ui-hero-icon\n [icon]=\"showPassword ? 'eye-slash' : 'eye'\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n } @else if (suffixIcon) {\n <fx-ui-hero-icon\n [icon]=\"suffixIcon\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n }\n </button>\n }\n </div>\n\n @if (invalid) {\n <div class=\"txt-invalid\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
|
|
3136
2773
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
|
|
3137
2774
|
type: Input
|
|
3138
2775
|
}], tooltip: [{
|
|
3139
2776
|
type: Input
|
|
3140
2777
|
}], type: [{
|
|
3141
2778
|
type: Input
|
|
3142
|
-
}], placeholder: [{
|
|
3143
|
-
type: Input
|
|
3144
|
-
}], errorMessages: [{
|
|
3145
|
-
type: Input
|
|
3146
|
-
}], required: [{
|
|
3147
|
-
type: Input
|
|
3148
|
-
}], suffixIcon: [{
|
|
2779
|
+
}], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], errorMessages: [{
|
|
3149
2780
|
type: Input
|
|
3150
|
-
}],
|
|
2781
|
+
}], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], suffixIcon: [{
|
|
3151
2782
|
type: Input
|
|
3152
|
-
}], maxlength: [{
|
|
3153
|
-
type: Input
|
|
3154
|
-
}], validateFn: [{
|
|
3155
|
-
type: Input
|
|
3156
|
-
}], blurred: [{
|
|
3157
|
-
type: Output
|
|
3158
|
-
}], focused: [{
|
|
3159
|
-
type: Output
|
|
3160
|
-
}], suffixClick: [{
|
|
3161
|
-
type: Output
|
|
3162
|
-
}], suffixAriaLabel: [{
|
|
3163
|
-
type: Input
|
|
3164
|
-
}] } });
|
|
2783
|
+
}], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], validateFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "validateFn", required: false }] }], blurred: [{ type: i0.Output, args: ["blurred"] }], focused: [{ type: i0.Output, args: ["focused"] }], suffixClick: [{ type: i0.Output, args: ["suffixClick"] }], suffixAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixAriaLabel", required: false }] }] } });
|
|
3165
2784
|
|
|
3166
2785
|
class LoadingPanel {
|
|
3167
|
-
show = false;
|
|
2786
|
+
show = input(false, ...(ngDevMode ? [{ debugName: "show" }] : /* istanbul ignore next */ []));
|
|
3168
2787
|
message = "Loading";
|
|
3169
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3170
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2788
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: LoadingPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2789
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: LoadingPanel, isStandalone: true, selector: "fx-ui-loading-panel", inputs: { show: { classPropertyName: "show", publicName: "show", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: false, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- Full-screen glass overlay -->\n@if (show()) {\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center\"\n aria-hidden=\"false\"\n role=\"alert\"\n aria-busy=\"true\"\n >\n <div class=\"absolute inset-0 bg-bg-primary/30 backdrop-blur-xl\" aria-hidden=\"true\"></div>\n <div\n class=\"relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70\"\n style=\"min-width: 220px; max-width: 90%\"\n >\n <svg fill=\"url(#spinner-gradient)\" width=\"50\" height=\"50\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"spinner-gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" style=\"stop-color: rgb(var(--gradient-primary-start)); stop-opacity: 1\" />\n <stop offset=\"100%\" style=\"stop-color: rgb(var(--gradient-primary-end)); stop-opacity: 1\" />\n </linearGradient>\n </defs>\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_lo66\" begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_z0Or\" begin=\"spinner_lo66.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_JsnR\" begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_Aguh\" begin=\"spinner_JsnR.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_hSjk\" begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_UHR2\" begin=\"spinner_hSjk.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate id=\"spinner_4v5M\" begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_OLMs\" begin=\"spinner_4v5M.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n </circle>\n </svg>\n @if (message) {\n <div class=\"text-sm text-text-primary text-center\">\n {{ message }}\n </div>\n }\n </div>\n </div>\n}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3171
2790
|
}
|
|
3172
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2791
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: LoadingPanel, decorators: [{
|
|
3173
2792
|
type: Component,
|
|
3174
|
-
args: [{ selector: 'fx-ui-loading-panel',
|
|
3175
|
-
}], propDecorators: { show: [{
|
|
3176
|
-
type: Input
|
|
3177
|
-
}], message: [{
|
|
2793
|
+
args: [{ selector: 'fx-ui-loading-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Full-screen glass overlay -->\n@if (show()) {\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center\"\n aria-hidden=\"false\"\n role=\"alert\"\n aria-busy=\"true\"\n >\n <div class=\"absolute inset-0 bg-bg-primary/30 backdrop-blur-xl\" aria-hidden=\"true\"></div>\n <div\n class=\"relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70\"\n style=\"min-width: 220px; max-width: 90%\"\n >\n <svg fill=\"url(#spinner-gradient)\" width=\"50\" height=\"50\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"spinner-gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" style=\"stop-color: rgb(var(--gradient-primary-start)); stop-opacity: 1\" />\n <stop offset=\"100%\" style=\"stop-color: rgb(var(--gradient-primary-end)); stop-opacity: 1\" />\n </linearGradient>\n </defs>\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_lo66\" begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_z0Or\" begin=\"spinner_lo66.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_JsnR\" begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_Aguh\" begin=\"spinner_JsnR.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_hSjk\" begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_UHR2\" begin=\"spinner_hSjk.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate id=\"spinner_4v5M\" begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_OLMs\" begin=\"spinner_4v5M.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n </circle>\n </svg>\n @if (message) {\n <div class=\"text-sm text-text-primary text-center\">\n {{ message }}\n </div>\n }\n </div>\n </div>\n}\n" }]
|
|
2794
|
+
}], propDecorators: { show: [{ type: i0.Input, args: [{ isSignal: true, alias: "show", required: false }] }], message: [{
|
|
3178
2795
|
type: Input
|
|
3179
2796
|
}] } });
|
|
3180
2797
|
|
|
@@ -3183,10 +2800,10 @@ class RadioButtonToggleComponent extends FxComponent {
|
|
|
3183
2800
|
ref;
|
|
3184
2801
|
groupId = `fx-radio-toggle-${nextToggleGroupId++}`;
|
|
3185
2802
|
label;
|
|
3186
|
-
required = false;
|
|
3187
|
-
options = [];
|
|
2803
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
2804
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
3188
2805
|
errorMessages = {};
|
|
3189
|
-
class;
|
|
2806
|
+
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3190
2807
|
constructor(ref) {
|
|
3191
2808
|
super();
|
|
3192
2809
|
this.ref = ref;
|
|
@@ -3201,23 +2818,17 @@ class RadioButtonToggleComponent extends FxComponent {
|
|
|
3201
2818
|
this.onChange(value);
|
|
3202
2819
|
this.onTouched();
|
|
3203
2820
|
}
|
|
3204
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3205
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2821
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonToggleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2822
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: RadioButtonToggleComponent, isStandalone: true, selector: "fx-ui-radio-toggle, [fx-ui-radio-toggle]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: false, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col text-left mb-4 w-full\" [class]=\"class()\">\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if(label){<span class=\"txt-field-label\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if(required()) {<span class=\"txt-required\" aria-hidden=\"true\">*</span>} </span\n >}\n\n <div\n class=\"inline-flex w-full rounded-lg overflow-hidden\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n @for(opt of options(); track opt){<button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value\n }\"\n class=\"radio-container\"\n >\n @if(value === opt.value) {<span class=\"radio-dot\"></span>}\n </span>\n\n <span class=\"txt-field-label mb-0\">{{ opt.label }}</span></button\n >}\n </div>\n\n @if(invalid){\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3206
2823
|
}
|
|
3207
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2824
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonToggleComponent, decorators: [{
|
|
3208
2825
|
type: Component,
|
|
3209
|
-
args: [{ selector: 'fx-ui-radio-toggle, [fx-ui-radio-toggle]',
|
|
2826
|
+
args: [{ selector: 'fx-ui-radio-toggle, [fx-ui-radio-toggle]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<div class=\"flex flex-col text-left mb-4 w-full\" [class]=\"class()\">\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if(label){<span class=\"txt-field-label\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if(required()) {<span class=\"txt-required\" aria-hidden=\"true\">*</span>} </span\n >}\n\n <div\n class=\"inline-flex w-full rounded-lg overflow-hidden\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n @for(opt of options(); track opt){<button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value\n }\"\n class=\"radio-container\"\n >\n @if(value === opt.value) {<span class=\"radio-dot\"></span>}\n </span>\n\n <span class=\"txt-field-label mb-0\">{{ opt.label }}</span></button\n >}\n </div>\n\n @if(invalid){\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n" }]
|
|
3210
2827
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
|
|
3211
2828
|
type: Input
|
|
3212
|
-
}], required: [{
|
|
2829
|
+
}], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], errorMessages: [{
|
|
3213
2830
|
type: Input
|
|
3214
|
-
}],
|
|
3215
|
-
type: Input
|
|
3216
|
-
}], errorMessages: [{
|
|
3217
|
-
type: Input
|
|
3218
|
-
}], class: [{
|
|
3219
|
-
type: Input
|
|
3220
|
-
}] } });
|
|
2831
|
+
}], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3221
2832
|
|
|
3222
2833
|
let nextRadioGroupId = 0;
|
|
3223
2834
|
class RadioButtonComponent extends FxComponent {
|
|
@@ -3225,10 +2836,10 @@ class RadioButtonComponent extends FxComponent {
|
|
|
3225
2836
|
groupId = `fx-radio-${nextRadioGroupId++}`;
|
|
3226
2837
|
label;
|
|
3227
2838
|
tooltip = '';
|
|
3228
|
-
required = false;
|
|
3229
|
-
options = [];
|
|
2839
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
2840
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
3230
2841
|
errorMessages = {};
|
|
3231
|
-
class;
|
|
2842
|
+
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3232
2843
|
constructor(ref) {
|
|
3233
2844
|
super();
|
|
3234
2845
|
this.ref = ref;
|
|
@@ -3243,122 +2854,29 @@ class RadioButtonComponent extends FxComponent {
|
|
|
3243
2854
|
this.onChange(value);
|
|
3244
2855
|
this.onTouched();
|
|
3245
2856
|
}
|
|
3246
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3247
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2857
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2858
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: RadioButtonComponent, isStandalone: true, selector: "fx-ui-radio", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: false, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"w-full rounded-lg overflow-hidden\"\n [class]=\"class()\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if (label) {\n <span class=\"txt-field-label block\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </span>\n }\n\n @for (opt of options(); track opt) {\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n [matTooltip]=\"opt.tooltip || ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value,\n }\"\n class=\"radio-container\"\n >\n @if (value === opt.value) {\n <span class=\"radio-dot\"></span>\n }\n </span>\n <span class=\"txt-default mb-0\">{{ opt.label }}</span>\n </button>\n }\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3248
2859
|
}
|
|
3249
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2860
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonComponent, decorators: [{
|
|
3250
2861
|
type: Component,
|
|
3251
|
-
args: [{ selector: 'fx-ui-radio',
|
|
2862
|
+
args: [{ selector: 'fx-ui-radio', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2863
|
+
HeroIconComponent,
|
|
2864
|
+
MatTooltip,
|
|
2865
|
+
NgClass,
|
|
2866
|
+
], template: "<div\n class=\"w-full rounded-lg overflow-hidden\"\n [class]=\"class()\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if (label) {\n <span class=\"txt-field-label block\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </span>\n }\n\n @for (opt of options(); track opt) {\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n [matTooltip]=\"opt.tooltip || ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value,\n }\"\n class=\"radio-container\"\n >\n @if (value === opt.value) {\n <span class=\"radio-dot\"></span>\n }\n </span>\n <span class=\"txt-default mb-0\">{{ opt.label }}</span>\n </button>\n }\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
|
|
3252
2867
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
|
|
3253
2868
|
type: Input
|
|
3254
2869
|
}], tooltip: [{
|
|
3255
2870
|
type: Input
|
|
3256
|
-
}], required: [{
|
|
3257
|
-
type: Input
|
|
3258
|
-
}], options: [{
|
|
3259
|
-
type: Input
|
|
3260
|
-
}], errorMessages: [{
|
|
3261
|
-
type: Input
|
|
3262
|
-
}], class: [{
|
|
3263
|
-
type: Input
|
|
3264
|
-
}] } });
|
|
3265
|
-
|
|
3266
|
-
class RichTextAreaComponent extends FxComponent {
|
|
3267
|
-
cdr;
|
|
3268
|
-
styleLoader;
|
|
3269
|
-
platformId;
|
|
3270
|
-
editorContainer;
|
|
3271
|
-
placeholder = 'Write something...';
|
|
3272
|
-
toolbarOptions = [
|
|
3273
|
-
// ['undo', 'redo'],
|
|
3274
|
-
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
|
3275
|
-
[{ 'font': [] }],
|
|
3276
|
-
[{ 'size': ['small', false, 'large', 'huge'] }],
|
|
3277
|
-
[{ 'align': [] }],
|
|
3278
|
-
[{ 'color': [] }, { 'background': [] }],
|
|
3279
|
-
['bold', 'italic', 'underline', 'strike'],
|
|
3280
|
-
['blockquote', 'code-block'],
|
|
3281
|
-
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
|
3282
|
-
[{ 'indent': '-1' }, { 'indent': '+1' }],
|
|
3283
|
-
['link', 'image'],
|
|
3284
|
-
['clean']
|
|
3285
|
-
];
|
|
3286
|
-
contentChange = new EventEmitter();
|
|
3287
|
-
quillInstance;
|
|
3288
|
-
constructor(cdr, styleLoader, platformId) {
|
|
3289
|
-
super();
|
|
3290
|
-
this.cdr = cdr;
|
|
3291
|
-
this.styleLoader = styleLoader;
|
|
3292
|
-
this.platformId = platformId;
|
|
3293
|
-
}
|
|
3294
|
-
async ngAfterViewInit() {
|
|
3295
|
-
if (!isPlatformBrowser(this.platformId))
|
|
3296
|
-
return;
|
|
3297
|
-
await this.styleLoader.load();
|
|
3298
|
-
const QuillModule = await import('quill');
|
|
3299
|
-
const Quill = QuillModule.default || QuillModule;
|
|
3300
|
-
const icons = Quill.import('ui/icons');
|
|
3301
|
-
// icons['undo'] = `<svg viewBox="0 0 18 18"><path d="M6.4 5.2H3L6.8 1l3.8 4.2H7.9C10.2 5.4 12 7.4 12 9.8c0 2.7-2.2 4.9-4.9 4.9S2.2 12.5 2.2 9.8H0c0 3.8 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9S10.7 3 7 3v2.2z"></path></svg>`;
|
|
3302
|
-
// icons['redo'] = `<svg viewBox="0 0 18 18"><path d="M11.6 5.2H15L11.2 1 7.4 5.2h2.7C7.8 5.4 6 7.4 6 9.8c0 2.7 2.2 4.9 4.9 4.9s4.9-2.2 4.9-4.9H18c0 3.8-3.1 6.9-6.9 6.9S4.2 13.6 4.2 9.8 7.3 3 11 3v2.2z"></path></svg>`;
|
|
3303
|
-
this.quillInstance = new Quill(this.editorContainer.nativeElement, {
|
|
3304
|
-
theme: 'snow',
|
|
3305
|
-
placeholder: this.placeholder,
|
|
3306
|
-
modules: {
|
|
3307
|
-
history: true,
|
|
3308
|
-
toolbar: this.toolbarOptions,
|
|
3309
|
-
}
|
|
3310
|
-
});
|
|
3311
|
-
this.quillInstance.root.style.color = FxUtils.convertColorFromVariable('--text-primary');
|
|
3312
|
-
const toolbar = this.quillInstance.getModule('toolbar');
|
|
3313
|
-
toolbar.addHandler('undo', () => this.quillInstance.history.undo());
|
|
3314
|
-
toolbar.addHandler('redo', () => this.quillInstance.history.redo());
|
|
3315
|
-
if (this.value) {
|
|
3316
|
-
this.quillInstance.root.innerHTML = this.value;
|
|
3317
|
-
}
|
|
3318
|
-
this.quillInstance.on('text-change', () => {
|
|
3319
|
-
const html = this.quillInstance.root.innerHTML || '';
|
|
3320
|
-
this.value = html;
|
|
3321
|
-
this.onChange(html);
|
|
3322
|
-
this.contentChange.emit(html);
|
|
3323
|
-
});
|
|
3324
|
-
}
|
|
3325
|
-
writeValue(value) {
|
|
3326
|
-
this.value = value || '';
|
|
3327
|
-
if (this.quillInstance) {
|
|
3328
|
-
this.quillInstance.root.innerHTML = this.value;
|
|
3329
|
-
}
|
|
3330
|
-
}
|
|
3331
|
-
setDisabledState(isDisabled) {
|
|
3332
|
-
this.disabled = isDisabled;
|
|
3333
|
-
if (this.quillInstance) {
|
|
3334
|
-
this.quillInstance.enable(!isDisabled);
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RichTextAreaComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: QuillStyleLoaderService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
|
|
3338
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: RichTextAreaComponent, isStandalone: false, selector: "fx-ui-rich-text-area", inputs: { placeholder: "placeholder", toolbarOptions: "toolbarOptions" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-full rounded-2xl shadow-sm p-1 bg-bg-primary\">\n <div #editorContainer class=\"min-h-[200px] text-base\"></div>\n</div>", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block}.ql-toolbar{border-top-left-radius:.25rem;border-top-right-radius:.25rem;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:rgb(var(--border-default));padding:calc(var(--spacing, .25rem) * 2)}.ql-container{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.ql-editor{min-height:200px;padding:calc(var(--spacing, .25rem) * 3);font-size:1rem;line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] });
|
|
3339
|
-
}
|
|
3340
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RichTextAreaComponent, decorators: [{
|
|
3341
|
-
type: Component,
|
|
3342
|
-
args: [{ selector: 'fx-ui-rich-text-area', standalone: false, template: "<div class=\"w-full rounded-2xl shadow-sm p-1 bg-bg-primary\">\n <div #editorContainer class=\"min-h-[200px] text-base\"></div>\n</div>", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block}.ql-toolbar{border-top-left-radius:.25rem;border-top-right-radius:.25rem;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:rgb(var(--border-default));padding:calc(var(--spacing, .25rem) * 2)}.ql-container{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.ql-editor{min-height:200px;padding:calc(var(--spacing, .25rem) * 3);font-size:1rem;line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3343
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: QuillStyleLoaderService }, { type: undefined, decorators: [{
|
|
3344
|
-
type: Inject,
|
|
3345
|
-
args: [PLATFORM_ID]
|
|
3346
|
-
}] }], propDecorators: { editorContainer: [{
|
|
3347
|
-
type: ViewChild,
|
|
3348
|
-
args: ['editorContainer', { static: true }]
|
|
3349
|
-
}], placeholder: [{
|
|
3350
|
-
type: Input
|
|
3351
|
-
}], toolbarOptions: [{
|
|
2871
|
+
}], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], errorMessages: [{
|
|
3352
2872
|
type: Input
|
|
3353
|
-
}],
|
|
3354
|
-
type: Output
|
|
3355
|
-
}] } });
|
|
2873
|
+
}], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3356
2874
|
|
|
3357
2875
|
class SearchBarComponent extends FxComponent {
|
|
3358
2876
|
ref;
|
|
3359
|
-
placeholder = 'Search...';
|
|
3360
|
-
search =
|
|
3361
|
-
valueChange =
|
|
2877
|
+
placeholder = input('Search...', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
2878
|
+
search = output();
|
|
2879
|
+
valueChange = output();
|
|
3362
2880
|
constructor(ref) {
|
|
3363
2881
|
super();
|
|
3364
2882
|
this.ref = ref;
|
|
@@ -3384,35 +2902,29 @@ class SearchBarComponent extends FxComponent {
|
|
|
3384
2902
|
this.valueChange.emit('');
|
|
3385
2903
|
this.search.emit('');
|
|
3386
2904
|
}
|
|
3387
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3388
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2905
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SearchBarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2906
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SearchBarComponent, isStandalone: true, selector: "fx-ui-search-bar", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { search: "search", valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"relative\">\n <fx-ui-hero-icon icon=\"magnifying-glass\" [size]=\"18\" class=\"absolute left-1 top-[3px] text-text-primary\"></fx-ui-hero-icon>\n <input\n type=\"text\"\n class=\"input-default px-9\"\n [attr.placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (keydown.enter)=\"onEnterKey()\"\n />\n\n @if (value && !disabled) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"clear()\"\n aria-label=\"Clear\"\n >\n <i class=\"material-symbols-outlined text-lg select-none\">close</i>\n </button>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3389
2907
|
}
|
|
3390
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2908
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SearchBarComponent, decorators: [{
|
|
3391
2909
|
type: Component,
|
|
3392
|
-
args: [{ selector: 'fx-ui-search-bar',
|
|
3393
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{
|
|
3394
|
-
type: Input
|
|
3395
|
-
}], search: [{
|
|
3396
|
-
type: Output
|
|
3397
|
-
}], valueChange: [{
|
|
3398
|
-
type: Output
|
|
3399
|
-
}] } });
|
|
2910
|
+
args: [{ selector: 'fx-ui-search-bar', changeDetection: ChangeDetectionStrategy.OnPush, imports: [HeroIconComponent], template: "<div class=\"relative\">\n <fx-ui-hero-icon icon=\"magnifying-glass\" [size]=\"18\" class=\"absolute left-1 top-[3px] text-text-primary\"></fx-ui-hero-icon>\n <input\n type=\"text\"\n class=\"input-default px-9\"\n [attr.placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (keydown.enter)=\"onEnterKey()\"\n />\n\n @if (value && !disabled) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"clear()\"\n aria-label=\"Clear\"\n >\n <i class=\"material-symbols-outlined text-lg select-none\">close</i>\n </button>\n }\n</div>\n" }]
|
|
2911
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], search: [{ type: i0.Output, args: ["search"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
3400
2912
|
|
|
3401
2913
|
let nextSelectId = 0;
|
|
3402
2914
|
class SelectComponent extends FxComponent {
|
|
3403
2915
|
ref;
|
|
3404
2916
|
label = '';
|
|
3405
2917
|
tooltip = '';
|
|
3406
|
-
placeholder = '';
|
|
3407
|
-
options = [];
|
|
3408
|
-
multiple = false;
|
|
2918
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
2919
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
2920
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
3409
2921
|
errorMessages = {};
|
|
3410
|
-
required = false;
|
|
3411
|
-
class;
|
|
3412
|
-
enableSearch = false;
|
|
3413
|
-
searchFn;
|
|
2922
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
2923
|
+
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2924
|
+
enableSearch = input(false, ...(ngDevMode ? [{ debugName: "enableSearch" }] : /* istanbul ignore next */ []));
|
|
2925
|
+
searchFn = input(...(ngDevMode ? [undefined, { debugName: "searchFn" }] : /* istanbul ignore next */ []));
|
|
3414
2926
|
/** Emits the current value when the select panel closes (useful for multiple mode). */
|
|
3415
|
-
closed =
|
|
2927
|
+
closed = output();
|
|
3416
2928
|
fieldId = `fx-select-${nextSelectId++}`;
|
|
3417
2929
|
searchTerm = '';
|
|
3418
2930
|
filteredOptions = [];
|
|
@@ -3427,7 +2939,7 @@ class SelectComponent extends FxComponent {
|
|
|
3427
2939
|
this.value = value ?? '';
|
|
3428
2940
|
}
|
|
3429
2941
|
ngOnInit() {
|
|
3430
|
-
this.filteredOptions = this.options;
|
|
2942
|
+
this.filteredOptions = this.options();
|
|
3431
2943
|
this.search$
|
|
3432
2944
|
.pipe(debounceTime(300), distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
|
|
3433
2945
|
.subscribe((term) => this.performSearch(term));
|
|
@@ -3436,7 +2948,7 @@ class SelectComponent extends FxComponent {
|
|
|
3436
2948
|
// Sync the rendered list when options arrive/refresh asynchronously
|
|
3437
2949
|
// (ngOnInit captures the initial — often empty — array only).
|
|
3438
2950
|
if (changes['options']) {
|
|
3439
|
-
this.filteredOptions = this.options ?? [];
|
|
2951
|
+
this.filteredOptions = this.options() ?? [];
|
|
3440
2952
|
this.ref?.detectChanges();
|
|
3441
2953
|
}
|
|
3442
2954
|
}
|
|
@@ -3445,8 +2957,8 @@ class SelectComponent extends FxComponent {
|
|
|
3445
2957
|
}
|
|
3446
2958
|
onOpened(open) {
|
|
3447
2959
|
if (open) {
|
|
3448
|
-
this.filteredOptions = this.options;
|
|
3449
|
-
if (this.enableSearch)
|
|
2960
|
+
this.filteredOptions = this.options();
|
|
2961
|
+
if (this.enableSearch())
|
|
3450
2962
|
this.searchTerm = '';
|
|
3451
2963
|
}
|
|
3452
2964
|
else {
|
|
@@ -3454,19 +2966,20 @@ class SelectComponent extends FxComponent {
|
|
|
3454
2966
|
}
|
|
3455
2967
|
}
|
|
3456
2968
|
onSearchChange(value) {
|
|
3457
|
-
if (!this.enableSearch)
|
|
2969
|
+
if (!this.enableSearch())
|
|
3458
2970
|
return;
|
|
3459
2971
|
this.search$.next(value);
|
|
3460
2972
|
}
|
|
3461
2973
|
async performSearch(term) {
|
|
3462
|
-
if (!this.enableSearch)
|
|
2974
|
+
if (!this.enableSearch())
|
|
3463
2975
|
return;
|
|
3464
|
-
|
|
3465
|
-
|
|
2976
|
+
const searchFn = this.searchFn();
|
|
2977
|
+
if (!searchFn) {
|
|
2978
|
+
this.filteredOptions = this.options().filter((o) => o.label?.toLowerCase().includes(term.toLowerCase()));
|
|
3466
2979
|
this.ref.detectChanges();
|
|
3467
2980
|
return;
|
|
3468
2981
|
}
|
|
3469
|
-
const result = await
|
|
2982
|
+
const result = await searchFn(term);
|
|
3470
2983
|
this.filteredOptions = result;
|
|
3471
2984
|
Promise.resolve().then(() => this.ref.detectChanges());
|
|
3472
2985
|
}
|
|
@@ -3480,60 +2993,47 @@ class SelectComponent extends FxComponent {
|
|
|
3480
2993
|
}
|
|
3481
2994
|
return this.value === value;
|
|
3482
2995
|
}
|
|
3483
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3484
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2996
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SelectComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2997
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SelectComponent, isStandalone: true, selector: "fx-ui-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, enableSearch: { classPropertyName: "enableSearch", publicName: "enableSearch", isSignal: true, isRequired: false, transformFunction: null }, searchFn: { classPropertyName: "searchFn", publicName: "searchFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class()\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <mat-form-field\n [attr.invalid]=\"invalid || null\"\n class=\"fx-select-field w-full shadow-sm\"\n appearance=\"fill\"\n >\n <mat-select\n [id]=\"fieldId\"\n [required]=\"!!required()\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple()\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (openedChange)=\"onOpened($event)\"\n (blur)=\"onTouched()\"\n >\n @if (enableSearch()) {\n <div class=\"px-semi w-full\">\n <input\n type=\"text\"\n aria-label=\"Search\"\n [placeholder]=\"'Search'\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n class=\"text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-gradient-primary-start focus-visible:ring-2 focus-visible:ring-primary/50 text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out\"\n />\n </div>\n }\n @for (option of filteredOptions; track option) {\n <mat-option [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (invalid) {\n <div class=\"txt-invalid text-left\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: ["::ng-deep .fx-select-field{display:block!important;width:100%!important;margin:0!important;padding:0!important;border-radius:.75rem;box-shadow:0 1px 1px rgb(var(--border-default))}::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,::ng-deep .fx-select-field .mat-mdc-text-field-wrapper{padding:0!important;margin:0!important;width:100%!important}::ng-deep .fx-select-field .mdc-text-field{width:100%!important;margin:0!important;padding:0!important;--mdc-shape-small: 0 !important}::ng-deep .fx-select-field .mat-mdc-form-field-flex{width:100%!important;margin:0!important;padding:0 .75rem!important;border:1px solid rgb(var(--border-default));border-radius:.375rem;height:36px!important;align-items:center;background-color:rgb(var(--bg-primary))}::ng-deep .fx-select-field .mdc-notched-outline,::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex{border:2px solid rgb(var(--gradient-primary-start))!important;outline:none!important;border-radius:.375rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep mat-form-field[invalid] .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep .fx-select-field .mat-mdc-select-trigger{padding:0!important;margin:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper{margin-right:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow svg{display:none!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow{width:8px!important;height:8px!important;border-style:solid;border-color:currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);margin-top:-3px;color:rgb(var(--text-secondary))!important}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.375rem!important;box-shadow:0 2px 4px #0000001a!important}::ng-deep .fx-select-field .mat-mdc-select-placeholder{color:rgb(var(--text-placeholder))!important;font-size:14px}::ng-deep .fx-select-field .mat-mdc-select-value{color:rgb(var(--text-primary))!important;font-size:14px;font-weight:400}.mat-select-panel .search-option-full-width{padding-left:0!important;padding-right:0!important;display:block;pointer-events:none;line-height:initial;height:auto}.mat-select-panel .search-option-full-width .search-bar{width:100%;padding:8px 16px;border:none;border-bottom:1px solid #ddd;box-sizing:border-box}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-form-field-flex,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-form-field-flex{background-color:rgb(var(--bg-primary-hover))!important;border-color:rgb(var(--border-default))!important;cursor:not-allowed!important;opacity:.6;box-shadow:none!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-value,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-placeholder,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-arrow,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-value,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-placeholder,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-arrow{color:rgb(var(--text-placeholder))!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select{cursor:not-allowed!important}\n"], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3485
2998
|
}
|
|
3486
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2999
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SelectComponent, decorators: [{
|
|
3487
3000
|
type: Component,
|
|
3488
|
-
args: [{ selector: 'fx-ui-select',
|
|
3001
|
+
args: [{ selector: 'fx-ui-select', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3002
|
+
HeroIconComponent,
|
|
3003
|
+
MatTooltip,
|
|
3004
|
+
MatFormField,
|
|
3005
|
+
MatSelect,
|
|
3006
|
+
FormsModule,
|
|
3007
|
+
MatOption,
|
|
3008
|
+
], template: "<div class=\"mb-4 text-left w-full\" [class]=\"class()\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required()) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <mat-form-field\n [attr.invalid]=\"invalid || null\"\n class=\"fx-select-field w-full shadow-sm\"\n appearance=\"fill\"\n >\n <mat-select\n [id]=\"fieldId\"\n [required]=\"!!required()\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple()\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (openedChange)=\"onOpened($event)\"\n (blur)=\"onTouched()\"\n >\n @if (enableSearch()) {\n <div class=\"px-semi w-full\">\n <input\n type=\"text\"\n aria-label=\"Search\"\n [placeholder]=\"'Search'\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n class=\"text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-gradient-primary-start focus-visible:ring-2 focus-visible:ring-primary/50 text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out\"\n />\n </div>\n }\n @for (option of filteredOptions; track option) {\n <mat-option [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (invalid) {\n <div class=\"txt-invalid text-left\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: ["::ng-deep .fx-select-field{display:block!important;width:100%!important;margin:0!important;padding:0!important;border-radius:.75rem;box-shadow:0 1px 1px rgb(var(--border-default))}::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,::ng-deep .fx-select-field .mat-mdc-text-field-wrapper{padding:0!important;margin:0!important;width:100%!important}::ng-deep .fx-select-field .mdc-text-field{width:100%!important;margin:0!important;padding:0!important;--mdc-shape-small: 0 !important}::ng-deep .fx-select-field .mat-mdc-form-field-flex{width:100%!important;margin:0!important;padding:0 .75rem!important;border:1px solid rgb(var(--border-default));border-radius:.375rem;height:36px!important;align-items:center;background-color:rgb(var(--bg-primary))}::ng-deep .fx-select-field .mdc-notched-outline,::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex{border:2px solid rgb(var(--gradient-primary-start))!important;outline:none!important;border-radius:.375rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep mat-form-field[invalid] .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep .fx-select-field .mat-mdc-select-trigger{padding:0!important;margin:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper{margin-right:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow svg{display:none!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow{width:8px!important;height:8px!important;border-style:solid;border-color:currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);margin-top:-3px;color:rgb(var(--text-secondary))!important}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.375rem!important;box-shadow:0 2px 4px #0000001a!important}::ng-deep .fx-select-field .mat-mdc-select-placeholder{color:rgb(var(--text-placeholder))!important;font-size:14px}::ng-deep .fx-select-field .mat-mdc-select-value{color:rgb(var(--text-primary))!important;font-size:14px;font-weight:400}.mat-select-panel .search-option-full-width{padding-left:0!important;padding-right:0!important;display:block;pointer-events:none;line-height:initial;height:auto}.mat-select-panel .search-option-full-width .search-bar{width:100%;padding:8px 16px;border:none;border-bottom:1px solid #ddd;box-sizing:border-box}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-form-field-flex,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-form-field-flex{background-color:rgb(var(--bg-primary-hover))!important;border-color:rgb(var(--border-default))!important;cursor:not-allowed!important;opacity:.6;box-shadow:none!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-value,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-placeholder,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-arrow,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-value,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-placeholder,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-arrow{color:rgb(var(--text-placeholder))!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select{cursor:not-allowed!important}\n"] }]
|
|
3489
3009
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
|
|
3490
3010
|
type: Input
|
|
3491
3011
|
}], tooltip: [{
|
|
3492
3012
|
type: Input
|
|
3493
|
-
}], placeholder: [{
|
|
3494
|
-
type: Input
|
|
3495
|
-
}], options: [{
|
|
3496
|
-
type: Input
|
|
3497
|
-
}], multiple: [{
|
|
3498
|
-
type: Input
|
|
3499
|
-
}], errorMessages: [{
|
|
3500
|
-
type: Input
|
|
3501
|
-
}], required: [{
|
|
3502
|
-
type: Input
|
|
3503
|
-
}], class: [{
|
|
3504
|
-
type: Input
|
|
3505
|
-
}], enableSearch: [{
|
|
3013
|
+
}], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], errorMessages: [{
|
|
3506
3014
|
type: Input
|
|
3507
|
-
}], searchFn: [{
|
|
3508
|
-
type: Input
|
|
3509
|
-
}], closed: [{
|
|
3510
|
-
type: Output
|
|
3511
|
-
}] } });
|
|
3015
|
+
}], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], enableSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSearch", required: false }] }], searchFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchFn", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
3512
3016
|
|
|
3513
3017
|
class SkeletonTableLoadingComponent {
|
|
3514
|
-
columns = 5;
|
|
3515
|
-
rows = 5;
|
|
3516
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3517
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3018
|
+
columns = input(5, ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
3019
|
+
rows = input(5, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
3020
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonTableLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3021
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SkeletonTableLoadingComponent, isStandalone: true, selector: "fx-ui-skeleton-table-loading", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"w-full animate-pulse space-y-normal\">\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns() + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns()); track col) {\n <div class=\"h-6 bg-bg-hover rounded\"></div>\n }\n </div>\n\n @for(row of [].constructor(rows()); track row) {\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns() + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns()); track col) {\n <div class=\"h-7 bg-bg-hover rounded\"></div>\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3518
3022
|
}
|
|
3519
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3023
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonTableLoadingComponent, decorators: [{
|
|
3520
3024
|
type: Component,
|
|
3521
|
-
args: [{ selector: 'fx-ui-skeleton-table-loading',
|
|
3522
|
-
}], propDecorators: { columns: [{
|
|
3523
|
-
type: Input
|
|
3524
|
-
}], rows: [{
|
|
3525
|
-
type: Input
|
|
3526
|
-
}] } });
|
|
3025
|
+
args: [{ selector: 'fx-ui-skeleton-table-loading', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgStyle], template: "<div class=\"w-full animate-pulse space-y-normal\">\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns() + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns()); track col) {\n <div class=\"h-6 bg-bg-hover rounded\"></div>\n }\n </div>\n\n @for(row of [].constructor(rows()); track row) {\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns() + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns()); track col) {\n <div class=\"h-7 bg-bg-hover rounded\"></div>\n }\n </div>\n }\n</div>\n" }]
|
|
3026
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }] } });
|
|
3527
3027
|
|
|
3528
3028
|
class SliderComponent extends FxComponent {
|
|
3529
3029
|
ref;
|
|
3530
|
-
trackRef;
|
|
3531
|
-
thumbRef;
|
|
3532
|
-
min = 0;
|
|
3533
|
-
max = 100;
|
|
3534
|
-
step = 1;
|
|
3535
|
-
vertical = false;
|
|
3536
|
-
valueChange =
|
|
3030
|
+
trackRef = viewChild.required('track');
|
|
3031
|
+
thumbRef = viewChild.required('thumb');
|
|
3032
|
+
min = input(0, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
3033
|
+
max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
3034
|
+
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
|
|
3035
|
+
vertical = input(false, ...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
|
|
3036
|
+
valueChange = output();
|
|
3537
3037
|
dragging = false;
|
|
3538
3038
|
constructor(ref) {
|
|
3539
3039
|
super();
|
|
@@ -3548,15 +3048,15 @@ class SliderComponent extends FxComponent {
|
|
|
3548
3048
|
this.ref.markForCheck();
|
|
3549
3049
|
}
|
|
3550
3050
|
writeValue(value) {
|
|
3551
|
-
this.value = this._normalizeValue(value ?? this.min);
|
|
3051
|
+
this.value = this._normalizeValue(value ?? this.min());
|
|
3552
3052
|
this.ref.markForCheck();
|
|
3553
3053
|
}
|
|
3554
3054
|
_normalizeValue(v) {
|
|
3555
3055
|
if (!Number.isFinite(v))
|
|
3556
|
-
v = this.min;
|
|
3557
|
-
const clamped =
|
|
3558
|
-
const stepped = Math.round((clamped - this.min) / this.step) * this.step + this.min;
|
|
3559
|
-
const precision = Math.max(0, this._decimalPlaces(this.step));
|
|
3056
|
+
v = this.min();
|
|
3057
|
+
const clamped = Math.min(this.max(), Math.max(this.min(), v));
|
|
3058
|
+
const stepped = Math.round((clamped - this.min()) / this.step()) * this.step() + this.min();
|
|
3059
|
+
const precision = Math.max(0, this._decimalPlaces(this.step()));
|
|
3560
3060
|
return parseFloat(stepped.toFixed(precision));
|
|
3561
3061
|
}
|
|
3562
3062
|
_decimalPlaces(n) {
|
|
@@ -3595,12 +3095,12 @@ class SliderComponent extends FxComponent {
|
|
|
3595
3095
|
this._applyValue(newVal);
|
|
3596
3096
|
}
|
|
3597
3097
|
_coordToValue(clientX, clientY) {
|
|
3598
|
-
const rect = this.trackRef.nativeElement.getBoundingClientRect();
|
|
3599
|
-
let ratio = this.vertical
|
|
3098
|
+
const rect = this.trackRef().nativeElement.getBoundingClientRect();
|
|
3099
|
+
let ratio = this.vertical()
|
|
3600
3100
|
? 1 - (clientY - rect.top) / rect.height
|
|
3601
3101
|
: (clientX - rect.left) / rect.width;
|
|
3602
|
-
ratio =
|
|
3603
|
-
const raw = this.min + ratio * (this.max - this.min);
|
|
3102
|
+
ratio = Math.min(1, Math.max(0, ratio));
|
|
3103
|
+
const raw = this.min() + ratio * (this.max() - this.min());
|
|
3604
3104
|
return this._normalizeValue(raw);
|
|
3605
3105
|
}
|
|
3606
3106
|
onTrackClick(event) {
|
|
@@ -3614,20 +3114,20 @@ class SliderComponent extends FxComponent {
|
|
|
3614
3114
|
if (this.disabled)
|
|
3615
3115
|
return;
|
|
3616
3116
|
const key = ev.key;
|
|
3617
|
-
const largeStep = (this.max - this.min) / 10;
|
|
3117
|
+
const largeStep = (this.max() - this.min()) / 10;
|
|
3618
3118
|
let delta = 0;
|
|
3619
3119
|
if (key === 'ArrowLeft' || key === 'ArrowDown')
|
|
3620
|
-
delta = -this.step;
|
|
3120
|
+
delta = -this.step();
|
|
3621
3121
|
else if (key === 'ArrowRight' || key === 'ArrowUp')
|
|
3622
|
-
delta = this.step;
|
|
3122
|
+
delta = this.step();
|
|
3623
3123
|
else if (key === 'PageDown')
|
|
3624
3124
|
delta = -largeStep;
|
|
3625
3125
|
else if (key === 'PageUp')
|
|
3626
3126
|
delta = largeStep;
|
|
3627
3127
|
else if (key === 'Home')
|
|
3628
|
-
return this._applyValue(this.min);
|
|
3128
|
+
return this._applyValue(this.min());
|
|
3629
3129
|
else if (key === 'End')
|
|
3630
|
-
return this._applyValue(this.max);
|
|
3130
|
+
return this._applyValue(this.max());
|
|
3631
3131
|
if (delta !== 0) {
|
|
3632
3132
|
this._applyValue(this.value + delta);
|
|
3633
3133
|
ev.preventDefault();
|
|
@@ -3643,54 +3143,39 @@ class SliderComponent extends FxComponent {
|
|
|
3643
3143
|
}
|
|
3644
3144
|
}
|
|
3645
3145
|
get percent() {
|
|
3646
|
-
|
|
3146
|
+
const min = this.min();
|
|
3147
|
+
const max = this.max();
|
|
3148
|
+
if (max === min)
|
|
3647
3149
|
return 0;
|
|
3648
|
-
return ((this.value -
|
|
3150
|
+
return ((this.value - min) / (max - min)) * 100;
|
|
3649
3151
|
}
|
|
3650
3152
|
thumbStyle() {
|
|
3651
|
-
return this.vertical
|
|
3153
|
+
return this.vertical()
|
|
3652
3154
|
? { bottom: `${this.percent}%`, transform: 'translateY(50%)' }
|
|
3653
3155
|
: { left: `${this.percent}%`, transform: 'translateX(-50%)' };
|
|
3654
3156
|
}
|
|
3655
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3656
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3157
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SliderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3158
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SliderComponent, isStandalone: true, selector: "fx-ui-slider", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { listeners: { "keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "trackRef", first: true, predicate: ["track"], descendants: true, isSignal: true }, { propertyName: "thumbRef", first: true, predicate: ["thumb"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"w-full select-none\"\n [class.cursor-not-allowed]=\"disabled\"\n [class.opacity-60]=\"disabled\"\n role=\"group\"\n >\n <!-- Track click is a pointer shortcut; the thumb button below owns keyboard/focus. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n #track\n class=\"relative touch-none py-4\"\n (click)=\"onTrackClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-orientation]=\"vertical() ? 'vertical' : 'horizontal'\"\n >\n <div\n class=\"relative flex items-center\"\n [ngClass]=\"{ 'flex-col h-48': vertical() }\"\n >\n <div\n class=\"relative flex-1 rounded-full bg-gray-600 h-2\"\n [ngClass]=\"{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical() }\"\n >\n @if (!vertical()) {\n <div\n class=\"absolute left-0 top-0 h-full rounded-full bg-primary\"\n [style.width.%]=\"percent\"\n ></div>\n }\n\n @if (vertical()) {\n <div\n class=\"absolute bottom-0 left-0 w-full rounded-full bg-primary\"\n [style.height.%]=\"percent\"\n style=\"transform-origin: bottom;\"\n ></div>\n }\n\n <button\n #thumb\n type=\"button\"\n class=\"absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary\"\n [ngStyle]=\"thumbStyle()\"\n role=\"slider\"\n aria-label=\"Slider\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-disabled]=\"disabled\"\n tabindex=\"0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n [disabled]=\"disabled\"\n ></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3657
3159
|
}
|
|
3658
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SliderComponent, decorators: [{
|
|
3659
3161
|
type: Component,
|
|
3660
|
-
args: [{ selector: 'fx-ui-slider',
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
}]
|
|
3665
|
-
|
|
3666
|
-
args: ['thumb', { static: true }]
|
|
3667
|
-
}], min: [{
|
|
3668
|
-
type: Input
|
|
3669
|
-
}], max: [{
|
|
3670
|
-
type: Input
|
|
3671
|
-
}], step: [{
|
|
3672
|
-
type: Input
|
|
3673
|
-
}], vertical: [{
|
|
3674
|
-
type: Input
|
|
3675
|
-
}], valueChange: [{
|
|
3676
|
-
type: Output
|
|
3677
|
-
}], onKeydown: [{
|
|
3162
|
+
args: [{ selector: 'fx-ui-slider', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3163
|
+
NgClass,
|
|
3164
|
+
NgStyle,
|
|
3165
|
+
InputComponent,
|
|
3166
|
+
], template: "<div\n class=\"w-full select-none\"\n [class.cursor-not-allowed]=\"disabled\"\n [class.opacity-60]=\"disabled\"\n role=\"group\"\n >\n <!-- Track click is a pointer shortcut; the thumb button below owns keyboard/focus. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n #track\n class=\"relative touch-none py-4\"\n (click)=\"onTrackClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-orientation]=\"vertical() ? 'vertical' : 'horizontal'\"\n >\n <div\n class=\"relative flex items-center\"\n [ngClass]=\"{ 'flex-col h-48': vertical() }\"\n >\n <div\n class=\"relative flex-1 rounded-full bg-gray-600 h-2\"\n [ngClass]=\"{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical() }\"\n >\n @if (!vertical()) {\n <div\n class=\"absolute left-0 top-0 h-full rounded-full bg-primary\"\n [style.width.%]=\"percent\"\n ></div>\n }\n\n @if (vertical()) {\n <div\n class=\"absolute bottom-0 left-0 w-full rounded-full bg-primary\"\n [style.height.%]=\"percent\"\n style=\"transform-origin: bottom;\"\n ></div>\n }\n\n <button\n #thumb\n type=\"button\"\n class=\"absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary\"\n [ngStyle]=\"thumbStyle()\"\n role=\"slider\"\n aria-label=\"Slider\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-disabled]=\"disabled\"\n tabindex=\"0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n [disabled]=\"disabled\"\n ></button>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
3167
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { trackRef: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }], thumbRef: [{ type: i0.ViewChild, args: ['thumb', { isSignal: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], vertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "vertical", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], onKeydown: [{
|
|
3678
3168
|
type: HostListener,
|
|
3679
3169
|
args: ['keydown', ['$event']]
|
|
3680
3170
|
}] } });
|
|
3681
3171
|
|
|
3682
3172
|
class SwitchComponent extends FxComponent {
|
|
3683
|
-
|
|
3684
|
-
onSwitch = new EventEmitter();
|
|
3173
|
+
onSwitch = output();
|
|
3685
3174
|
/** Accessible name — the switch renders no visible text of its own. */
|
|
3686
|
-
ariaLabel = '';
|
|
3175
|
+
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
3687
3176
|
ngAfterViewInit() {
|
|
3688
3177
|
this.cdr.detectChanges();
|
|
3689
3178
|
}
|
|
3690
|
-
constructor(cdr) {
|
|
3691
|
-
super();
|
|
3692
|
-
this.cdr = cdr;
|
|
3693
|
-
}
|
|
3694
3179
|
writeValue(value) {
|
|
3695
3180
|
this.value = value ?? false;
|
|
3696
3181
|
}
|
|
@@ -3702,43 +3187,35 @@ class SwitchComponent extends FxComponent {
|
|
|
3702
3187
|
this.onChange(this.value);
|
|
3703
3188
|
this.onTouched();
|
|
3704
3189
|
}
|
|
3705
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3706
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3190
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SwitchComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3191
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SwitchComponent, isStandalone: true, selector: "fx-ui-switch", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSwitch: "onSwitch" }, usesInheritance: true, ngImport: i0, template: "<button\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"!!value\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [disabled]=\"disabled\"\n class=\"relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer disabled:cursor-not-allowed focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'bg-success': value && !disabled,\n 'bg-button-default': !value && !disabled,\n 'bg-bg-hover': disabled\n }\"\n (click)=\"toggle()\"\n>\n @if(value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute left-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">check</i>\n\n }\n @if(!value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute right-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">close</i>\n }\n <div\n class=\"absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300\"\n [ngClass]=\"{ 'translate-x-5': value }\"\n ></div>\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3707
3192
|
}
|
|
3708
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3193
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SwitchComponent, decorators: [{
|
|
3709
3194
|
type: Component,
|
|
3710
|
-
args: [{ selector: 'fx-ui-switch',
|
|
3711
|
-
}],
|
|
3712
|
-
type: Output
|
|
3713
|
-
}], ariaLabel: [{
|
|
3714
|
-
type: Input
|
|
3715
|
-
}] } });
|
|
3195
|
+
args: [{ selector: 'fx-ui-switch', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<button\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"!!value\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [disabled]=\"disabled\"\n class=\"relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer disabled:cursor-not-allowed focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'bg-success': value && !disabled,\n 'bg-button-default': !value && !disabled,\n 'bg-bg-hover': disabled\n }\"\n (click)=\"toggle()\"\n>\n @if(value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute left-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">check</i>\n\n }\n @if(!value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute right-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">close</i>\n }\n <div\n class=\"absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300\"\n [ngClass]=\"{ 'translate-x-5': value }\"\n ></div>\n</button>\n" }]
|
|
3196
|
+
}], propDecorators: { onSwitch: [{ type: i0.Output, args: ["onSwitch"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
3716
3197
|
|
|
3717
3198
|
class TabComponent {
|
|
3718
|
-
label;
|
|
3199
|
+
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
3719
3200
|
icon;
|
|
3720
|
-
content;
|
|
3721
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3722
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3201
|
+
content = viewChild.required(TemplateRef);
|
|
3202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3203
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.20", type: TabComponent, isStandalone: true, selector: "fx-ui-tab", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: false, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "content", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template><ng-content></ng-content></ng-template>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3723
3204
|
}
|
|
3724
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3205
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabComponent, decorators: [{
|
|
3725
3206
|
type: Component,
|
|
3726
|
-
args: [{ selector: 'fx-ui-tab',
|
|
3727
|
-
}], propDecorators: { label: [{
|
|
3207
|
+
args: [{ selector: 'fx-ui-tab', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template><ng-content></ng-content></ng-template>\n" }]
|
|
3208
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], icon: [{
|
|
3728
3209
|
type: Input
|
|
3729
|
-
}],
|
|
3730
|
-
type: Input
|
|
3731
|
-
}], content: [{
|
|
3732
|
-
type: ViewChild,
|
|
3733
|
-
args: [TemplateRef, { static: true }]
|
|
3734
|
-
}] } });
|
|
3210
|
+
}], content: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
|
|
3735
3211
|
|
|
3736
3212
|
class TabGroupComponent {
|
|
3737
3213
|
renderer;
|
|
3738
|
-
|
|
3214
|
+
cdr = inject(ChangeDetectorRef);
|
|
3215
|
+
tabs = contentChildren(TabComponent, ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
3739
3216
|
activeIndex = 0;
|
|
3740
|
-
tabListRef;
|
|
3741
|
-
underlineRef;
|
|
3217
|
+
tabListRef = viewChild.required('tabList');
|
|
3218
|
+
underlineRef = viewChild.required('underline');
|
|
3742
3219
|
canScrollLeft = false;
|
|
3743
3220
|
canScrollRight = false;
|
|
3744
3221
|
animateDelay = 50;
|
|
@@ -3752,6 +3229,7 @@ class TabGroupComponent {
|
|
|
3752
3229
|
this.updateScrollButtons();
|
|
3753
3230
|
this.updateUnderlinePosition();
|
|
3754
3231
|
this.scrollToActiveTab(false);
|
|
3232
|
+
this.cdr.markForCheck();
|
|
3755
3233
|
}, 0);
|
|
3756
3234
|
}
|
|
3757
3235
|
selectTab(index) {
|
|
@@ -3760,7 +3238,7 @@ class TabGroupComponent {
|
|
|
3760
3238
|
}
|
|
3761
3239
|
/** Roving tablist keyboard nav: arrows move AND activate (selection follows focus). */
|
|
3762
3240
|
onTabKeydown(event, index) {
|
|
3763
|
-
const count = this.tabs.length;
|
|
3241
|
+
const count = this.tabs().length;
|
|
3764
3242
|
if (!count)
|
|
3765
3243
|
return;
|
|
3766
3244
|
let next;
|
|
@@ -3782,12 +3260,12 @@ class TabGroupComponent {
|
|
|
3782
3260
|
}
|
|
3783
3261
|
event.preventDefault();
|
|
3784
3262
|
this.selectTab(next);
|
|
3785
|
-
const buttons = this.tabListRef.nativeElement.querySelectorAll('.tab-btn');
|
|
3263
|
+
const buttons = this.tabListRef().nativeElement.querySelectorAll('.tab-btn');
|
|
3786
3264
|
buttons[next]?.focus();
|
|
3787
3265
|
}
|
|
3788
3266
|
updateUnderlinePosition() {
|
|
3789
|
-
const tabListEl = this.tabListRef.nativeElement;
|
|
3790
|
-
const underlineEl = this.underlineRef.nativeElement;
|
|
3267
|
+
const tabListEl = this.tabListRef().nativeElement;
|
|
3268
|
+
const underlineEl = this.underlineRef().nativeElement;
|
|
3791
3269
|
const tabButtons = tabListEl.querySelectorAll('.tab-btn');
|
|
3792
3270
|
const activeTab = tabButtons[this.activeIndex];
|
|
3793
3271
|
if (!activeTab || !underlineEl)
|
|
@@ -3800,7 +3278,7 @@ class TabGroupComponent {
|
|
|
3800
3278
|
this.renderer.setStyle(underlineEl, 'transform', `translateX(${translateX}px)`);
|
|
3801
3279
|
}
|
|
3802
3280
|
scrollToActiveTab(updateUnderlineAfter = true) {
|
|
3803
|
-
const tabListEl = this.tabListRef.nativeElement;
|
|
3281
|
+
const tabListEl = this.tabListRef().nativeElement;
|
|
3804
3282
|
const tabButtons = tabListEl.querySelectorAll('.tab-btn');
|
|
3805
3283
|
const activeTab = tabButtons[this.activeIndex];
|
|
3806
3284
|
if (!activeTab)
|
|
@@ -3819,15 +3297,17 @@ class TabGroupComponent {
|
|
|
3819
3297
|
setTimeout(() => {
|
|
3820
3298
|
this.updateScrollButtons();
|
|
3821
3299
|
this.updateUnderlinePosition();
|
|
3300
|
+
this.cdr.markForCheck();
|
|
3822
3301
|
}, updateUnderlineAfter ? this.animateDelay : 0);
|
|
3823
3302
|
}
|
|
3824
3303
|
scroll(direction) {
|
|
3825
|
-
const tabListEl = this.tabListRef.nativeElement;
|
|
3304
|
+
const tabListEl = this.tabListRef().nativeElement;
|
|
3826
3305
|
const delta = direction === 'left' ? -this.scrollAmount : this.scrollAmount;
|
|
3827
3306
|
tabListEl.scrollBy({ left: delta, behavior: 'smooth' });
|
|
3828
3307
|
setTimeout(() => {
|
|
3829
3308
|
this.updateScrollButtons();
|
|
3830
3309
|
this.updateUnderlinePosition();
|
|
3310
|
+
this.cdr.markForCheck();
|
|
3831
3311
|
}, this.animateDelay);
|
|
3832
3312
|
}
|
|
3833
3313
|
onScroll() {
|
|
@@ -3835,7 +3315,7 @@ class TabGroupComponent {
|
|
|
3835
3315
|
this.updateUnderlinePosition();
|
|
3836
3316
|
}
|
|
3837
3317
|
updateScrollButtons() {
|
|
3838
|
-
const el = this.tabListRef.nativeElement;
|
|
3318
|
+
const el = this.tabListRef().nativeElement;
|
|
3839
3319
|
const scrollLeft = el.scrollLeft;
|
|
3840
3320
|
const maxScrollLeft = el.scrollWidth - el.clientWidth;
|
|
3841
3321
|
this.canScrollLeft = scrollLeft > 2;
|
|
@@ -3844,80 +3324,66 @@ class TabGroupComponent {
|
|
|
3844
3324
|
onResize() {
|
|
3845
3325
|
this.updateUnderlinePosition();
|
|
3846
3326
|
}
|
|
3847
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3848
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3327
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabGroupComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
3328
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TabGroupComponent, isStandalone: true, selector: "fx-ui-tab-group", inputs: { activeIndex: "activeIndex" }, host: { listeners: { "window:resize": "onResize()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent, isSignal: true }], viewQueries: [{ propertyName: "tabListRef", first: true, predicate: ["tabList"], descendants: true, isSignal: true }, { propertyName: "underlineRef", first: true, predicate: ["underline"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"relative\">\n <!-- Left scroll button -->\n <button\n class=\"left-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs left\"\n (click)=\"scroll('left')\"\n [style.opacity]=\"canScrollLeft ? 1 : 0\"\n [style.pointerEvents]=\"canScrollLeft ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollLeft ? null : -1\"\n [attr.aria-hidden]=\"!canScrollLeft\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <div\n #tabList\n role=\"tablist\"\n class=\"relative flex overflow-x-auto no-scrollbar scroll-smooth\"\n (scroll)=\"onScroll()\"\n >\n @for (tab of tabs(); track tab; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"i === activeIndex\"\n [tabindex]=\"i === activeIndex ? 0 : -1\"\n (click)=\"selectTab(i)\"\n (keydown)=\"onTabKeydown($event, i)\"\n class=\"tab-btn tab-bar-btn\"\n >\n <div class=\"flex flex-row items-center justify-center\">\n @if (tab.icon) {\n <fx-ui-hero-icon\n [icon]=\"tab.icon\"\n [size]=\"20\"\n class=\"flex mr-[2px]\"\n [ngClass]=\"{\n 'text-gradient-primary-start mb-small': i === activeIndex,\n 'text-text-placeholder': i !== activeIndex,\n }\"\n ></fx-ui-hero-icon>\n }\n <div\n [ngClass]=\"\n i === activeIndex ? 'txt-field-label text-gradient-primary-start' : 'txt-placeholder'\n \"\n >\n {{ tab.label() }}\n </div>\n </div>\n </button>\n }\n\n <span #underline class=\"underline\" style=\"width: 0; transform: translateX(0)\"></span>\n </div>\n\n <button\n class=\"right-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs right\"\n (click)=\"scroll('right')\"\n [style.opacity]=\"canScrollRight ? 1 : 0\"\n [style.pointerEvents]=\"canScrollRight ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollRight ? null : -1\"\n [attr.aria-hidden]=\"!canScrollRight\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n</div>\n\n<!-- Tab content -->\n<div class=\"transition-all duration-300 ease-in-out mt-4\">\n @for (tab of tabs(); track tab; let i = $index) {\n @if (i === activeIndex) {\n <div role=\"tabpanel\" class=\"animate-fadeIn\">\n <ng-container *ngTemplateOutlet=\"tab.content()\"></ng-container>\n </div>\n }\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .28s ease-in-out}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.underline{position:absolute;bottom:0;height:2px;background-color:rgb(var(--gradient-primary-start));transition:transform .25s cubic-bezier(.2,.9,.2,1),width .25s cubic-bezier(.2,.9,.2,1);will-change:transform,width;transform:translate(0);width:0;margin-left:32px;margin-right:32px}.left-scroll-button{position:absolute;top:0;left:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.right-scroll-button{position:absolute;top:0;right:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.tab-bar-btn{position:relative;padding-inline:1rem;padding-block:.5rem;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));white-space:nowrap;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3849
3329
|
}
|
|
3850
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3330
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabGroupComponent, decorators: [{
|
|
3851
3331
|
type: Component,
|
|
3852
|
-
args: [{ selector: 'fx-ui-tab-group',
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
type:
|
|
3860
|
-
|
|
3861
|
-
}], underlineRef: [{
|
|
3862
|
-
type: ViewChild,
|
|
3863
|
-
args: ['underline', { static: true }]
|
|
3864
|
-
}], onResize: [{
|
|
3332
|
+
args: [{ selector: 'fx-ui-tab-group', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3333
|
+
HeroIconComponent,
|
|
3334
|
+
NgClass,
|
|
3335
|
+
NgTemplateOutlet,
|
|
3336
|
+
InputComponent,
|
|
3337
|
+
], template: "<div class=\"relative\">\n <!-- Left scroll button -->\n <button\n class=\"left-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs left\"\n (click)=\"scroll('left')\"\n [style.opacity]=\"canScrollLeft ? 1 : 0\"\n [style.pointerEvents]=\"canScrollLeft ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollLeft ? null : -1\"\n [attr.aria-hidden]=\"!canScrollLeft\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <div\n #tabList\n role=\"tablist\"\n class=\"relative flex overflow-x-auto no-scrollbar scroll-smooth\"\n (scroll)=\"onScroll()\"\n >\n @for (tab of tabs(); track tab; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"i === activeIndex\"\n [tabindex]=\"i === activeIndex ? 0 : -1\"\n (click)=\"selectTab(i)\"\n (keydown)=\"onTabKeydown($event, i)\"\n class=\"tab-btn tab-bar-btn\"\n >\n <div class=\"flex flex-row items-center justify-center\">\n @if (tab.icon) {\n <fx-ui-hero-icon\n [icon]=\"tab.icon\"\n [size]=\"20\"\n class=\"flex mr-[2px]\"\n [ngClass]=\"{\n 'text-gradient-primary-start mb-small': i === activeIndex,\n 'text-text-placeholder': i !== activeIndex,\n }\"\n ></fx-ui-hero-icon>\n }\n <div\n [ngClass]=\"\n i === activeIndex ? 'txt-field-label text-gradient-primary-start' : 'txt-placeholder'\n \"\n >\n {{ tab.label() }}\n </div>\n </div>\n </button>\n }\n\n <span #underline class=\"underline\" style=\"width: 0; transform: translateX(0)\"></span>\n </div>\n\n <button\n class=\"right-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs right\"\n (click)=\"scroll('right')\"\n [style.opacity]=\"canScrollRight ? 1 : 0\"\n [style.pointerEvents]=\"canScrollRight ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollRight ? null : -1\"\n [attr.aria-hidden]=\"!canScrollRight\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n</div>\n\n<!-- Tab content -->\n<div class=\"transition-all duration-300 ease-in-out mt-4\">\n @for (tab of tabs(); track tab; let i = $index) {\n @if (i === activeIndex) {\n <div role=\"tabpanel\" class=\"animate-fadeIn\">\n <ng-container *ngTemplateOutlet=\"tab.content()\"></ng-container>\n </div>\n }\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .28s ease-in-out}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.underline{position:absolute;bottom:0;height:2px;background-color:rgb(var(--gradient-primary-start));transition:transform .25s cubic-bezier(.2,.9,.2,1),width .25s cubic-bezier(.2,.9,.2,1);will-change:transform,width;transform:translate(0);width:0;margin-left:32px;margin-right:32px}.left-scroll-button{position:absolute;top:0;left:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.right-scroll-button{position:absolute;top:0;right:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.tab-bar-btn{position:relative;padding-inline:1rem;padding-block:.5rem;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));white-space:nowrap;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3338
|
+
}], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TabComponent), { isSignal: true }] }], activeIndex: [{
|
|
3339
|
+
type: Input
|
|
3340
|
+
}], tabListRef: [{ type: i0.ViewChild, args: ['tabList', { isSignal: true }] }], underlineRef: [{ type: i0.ViewChild, args: ['underline', { isSignal: true }] }], onResize: [{
|
|
3865
3341
|
type: HostListener,
|
|
3866
3342
|
args: ['window:resize']
|
|
3867
3343
|
}] } });
|
|
3868
3344
|
|
|
3869
3345
|
class TableCell {
|
|
3870
|
-
loading;
|
|
3871
|
-
skeletonClass = 'h-4 w-full';
|
|
3872
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3873
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3346
|
+
loading = input.required(...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
3347
|
+
skeletonClass = input('h-4 w-full', ...(ngDevMode ? [{ debugName: "skeletonClass" }] : /* istanbul ignore next */ []));
|
|
3348
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TableCell, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3349
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TableCell, isStandalone: true, selector: "fx-ui-table-cell", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: true, transformFunction: null }, skeletonClass: { classPropertyName: "skeletonClass", publicName: "skeletonClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (!loading()) {\n <div animate.enter=\"fade-in-animation\" class=\"inline-block my-normal\">\n <ng-content />\n </div>\n} @else {\n <div animate.enter=\"fade-in-animation\" class=\"skeleton-load my-semi\" [class]=\"skeletonClass()\"></div>\n}\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3874
3350
|
}
|
|
3875
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TableCell, decorators: [{
|
|
3876
3352
|
type: Component,
|
|
3877
|
-
args: [{ selector: 'fx-ui-table-cell',
|
|
3878
|
-
}], propDecorators: { loading: [{
|
|
3879
|
-
type: Input,
|
|
3880
|
-
args: [{ required: true }]
|
|
3881
|
-
}], skeletonClass: [{
|
|
3882
|
-
type: Input
|
|
3883
|
-
}] } });
|
|
3353
|
+
args: [{ selector: 'fx-ui-table-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!loading()) {\n <div animate.enter=\"fade-in-animation\" class=\"inline-block my-normal\">\n <ng-content />\n </div>\n} @else {\n <div animate.enter=\"fade-in-animation\" class=\"skeleton-load my-semi\" [class]=\"skeletonClass()\"></div>\n}\n" }]
|
|
3354
|
+
}], propDecorators: { loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: true }] }], skeletonClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonClass", required: false }] }] } });
|
|
3884
3355
|
|
|
3885
3356
|
class TagComponent {
|
|
3886
|
-
label;
|
|
3887
|
-
type = 'default';
|
|
3888
|
-
rounded = true;
|
|
3357
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
|
|
3358
|
+
type = input('default', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
3359
|
+
rounded = input(true, ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
|
|
3889
3360
|
icon;
|
|
3890
|
-
solid = false;
|
|
3361
|
+
solid = input(false, ...(ngDevMode ? [{ debugName: "solid" }] : /* istanbul ignore next */ []));
|
|
3362
|
+
/* EventEmitter (not output()) on purpose: the template branches on
|
|
3363
|
+
* `clicked.observed` to only expose button semantics when someone listens —
|
|
3364
|
+
* OutputEmitterRef has no equivalent. */
|
|
3891
3365
|
clicked = new EventEmitter();
|
|
3892
3366
|
onClick() {
|
|
3893
3367
|
this.clicked.emit();
|
|
3894
3368
|
}
|
|
3895
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3896
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3369
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3370
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TagComponent, isStandalone: true, selector: "fx-ui-tag", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: false, isRequired: false, transformFunction: null }, solid: { classPropertyName: "solid", publicName: "solid", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<!-- Interactive semantics only when a (clicked) listener is attached. -->\n<div\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"$event.preventDefault(); onClick()\"\n [attr.role]=\"clicked.observed ? 'button' : null\"\n [attr.tabindex]=\"clicked.observed ? 0 : null\"\n [class]=\"\n `flex flex-row gap-small ${rounded() ? 'tag-round' : 'tag-square'} tag-${type()}${solid() ? '-solid' : ''}${clicked.observed ? ' cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50' : ''}`\n \"\n>\n @if (icon) {\n <fx-ui-hero-icon\n [class]=\"`flex txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-white' : ''}`\"\n [icon]=\"icon\"\n [size]=\"18\"\n ></fx-ui-hero-icon>\n }\n\n <div [class]=\"`txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-white font-medium' : ''}`\">\n {{ label() }}\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3897
3371
|
}
|
|
3898
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3372
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TagComponent, decorators: [{
|
|
3899
3373
|
type: Component,
|
|
3900
|
-
args: [{ selector: 'fx-ui-tag',
|
|
3901
|
-
}], propDecorators: { label: [{
|
|
3902
|
-
type: Input
|
|
3903
|
-
}], type: [{
|
|
3904
|
-
type: Input
|
|
3905
|
-
}], rounded: [{
|
|
3906
|
-
type: Input
|
|
3907
|
-
}], icon: [{
|
|
3908
|
-
type: Input
|
|
3909
|
-
}], solid: [{
|
|
3374
|
+
args: [{ selector: 'fx-ui-tag', changeDetection: ChangeDetectionStrategy.OnPush, imports: [HeroIconComponent], template: "<!-- Interactive semantics only when a (clicked) listener is attached. -->\n<div\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"$event.preventDefault(); onClick()\"\n [attr.role]=\"clicked.observed ? 'button' : null\"\n [attr.tabindex]=\"clicked.observed ? 0 : null\"\n [class]=\"\n `flex flex-row gap-small ${rounded() ? 'tag-round' : 'tag-square'} tag-${type()}${solid() ? '-solid' : ''}${clicked.observed ? ' cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50' : ''}`\n \"\n>\n @if (icon) {\n <fx-ui-hero-icon\n [class]=\"`flex txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-white' : ''}`\"\n [icon]=\"icon\"\n [size]=\"18\"\n ></fx-ui-hero-icon>\n }\n\n <div [class]=\"`txt-tag-${type()} ${solid() && type() !== 'default' ? 'text-white font-medium' : ''}`\">\n {{ label() }}\n </div>\n</div>\n" }]
|
|
3375
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], icon: [{
|
|
3910
3376
|
type: Input
|
|
3911
|
-
}], clicked: [{
|
|
3377
|
+
}], solid: [{ type: i0.Input, args: [{ isSignal: true, alias: "solid", required: false }] }], clicked: [{
|
|
3912
3378
|
type: Output
|
|
3913
3379
|
}] } });
|
|
3914
3380
|
|
|
3915
3381
|
class TreeDiagram {
|
|
3916
3382
|
zone;
|
|
3917
3383
|
cdr;
|
|
3918
|
-
data;
|
|
3919
|
-
container;
|
|
3920
|
-
root;
|
|
3384
|
+
data = input.required(...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
3385
|
+
container = viewChild.required('container');
|
|
3386
|
+
root = viewChild.required('root');
|
|
3921
3387
|
children;
|
|
3922
3388
|
lines = [];
|
|
3923
3389
|
svgWidth = 0;
|
|
@@ -3936,7 +3402,7 @@ class TreeDiagram {
|
|
|
3936
3402
|
return;
|
|
3937
3403
|
this.scheduleDraw();
|
|
3938
3404
|
});
|
|
3939
|
-
this.resizeObserver.observe(this.container.nativeElement);
|
|
3405
|
+
this.resizeObserver.observe(this.container().nativeElement);
|
|
3940
3406
|
setTimeout(() => this.scheduleDraw(), 50);
|
|
3941
3407
|
setTimeout(() => this.scheduleDraw(), 150);
|
|
3942
3408
|
});
|
|
@@ -3955,13 +3421,14 @@ class TreeDiagram {
|
|
|
3955
3421
|
});
|
|
3956
3422
|
}
|
|
3957
3423
|
drawLines() {
|
|
3958
|
-
|
|
3424
|
+
const root = this.root();
|
|
3425
|
+
if (!root || !this.children.length)
|
|
3959
3426
|
return;
|
|
3960
|
-
const containerEl = this.container.nativeElement;
|
|
3427
|
+
const containerEl = this.container().nativeElement;
|
|
3961
3428
|
const rect = containerEl.getBoundingClientRect();
|
|
3962
3429
|
if (rect.width === 0 || rect.height === 0)
|
|
3963
3430
|
return;
|
|
3964
|
-
const rootRect =
|
|
3431
|
+
const rootRect = root.nativeElement.getBoundingClientRect();
|
|
3965
3432
|
const rootX = rootRect.left + rootRect.width / 2 - rect.left;
|
|
3966
3433
|
const rootBottomY = rootRect.bottom - rect.top;
|
|
3967
3434
|
const childRects = this.children.map(c => c.nativeElement.getBoundingClientRect());
|
|
@@ -3996,34 +3463,26 @@ class TreeDiagram {
|
|
|
3996
3463
|
});
|
|
3997
3464
|
this.cdr.detectChanges();
|
|
3998
3465
|
}
|
|
3999
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4000
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3466
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeDiagram, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3467
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TreeDiagram, isStandalone: true, selector: "fx-ui-tree-diagram", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "root", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "children", predicate: ["child"], descendants: true }], ngImport: i0, template: "<div class=\"relative p-8\" #container>\n\n <!-- ROOT -->\n <div\n #root\n class=\"mx-auto w-fit bg-blue-600 text-white px-7 py-3 rounded-md font-semibold text-center\"\n >\n {{ data().label }}\n </div>\n\n <!-- CHILDREN -->\n <div class=\"mt-16 flex justify-center gap-16\">\n @for (child of data().children; track child) {\n <div\n #child\n class=\"w-48 bg-rose-600 text-white px-4 py-4 rounded-lg text-center\"\n >\n <div class=\"font-semibold text-lg\">{{ child.label }}</div>\n <div class=\"mt-1 text-sm opacity-90\">{{ child.status }}</div>\n </div>\n }\n </div>\n\n <!-- SVG CONNECTORS -->\n <svg\n class=\"absolute inset-0 pointer-events-none\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n >\n @for (line of lines; track line) {\n <line\n [attr.x1]=\"line.x1\"\n [attr.y1]=\"line.y1\"\n [attr.x2]=\"line.x2\"\n [attr.y2]=\"line.y2\"\n stroke=\"#1f2937\"\n stroke-width=\"2\"\n />\n }\n </svg>\n\n</div>\n", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4001
3468
|
}
|
|
4002
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3469
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeDiagram, decorators: [{
|
|
4003
3470
|
type: Component,
|
|
4004
|
-
args: [{ selector: 'fx-ui-tree-diagram',
|
|
4005
|
-
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { data: [{
|
|
4006
|
-
type: Input
|
|
4007
|
-
}], container: [{
|
|
4008
|
-
type: ViewChild,
|
|
4009
|
-
args: ['container']
|
|
4010
|
-
}], root: [{
|
|
4011
|
-
type: ViewChild,
|
|
4012
|
-
args: ['root']
|
|
4013
|
-
}], children: [{
|
|
3471
|
+
args: [{ selector: 'fx-ui-tree-diagram', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative p-8\" #container>\n\n <!-- ROOT -->\n <div\n #root\n class=\"mx-auto w-fit bg-blue-600 text-white px-7 py-3 rounded-md font-semibold text-center\"\n >\n {{ data().label }}\n </div>\n\n <!-- CHILDREN -->\n <div class=\"mt-16 flex justify-center gap-16\">\n @for (child of data().children; track child) {\n <div\n #child\n class=\"w-48 bg-rose-600 text-white px-4 py-4 rounded-lg text-center\"\n >\n <div class=\"font-semibold text-lg\">{{ child.label }}</div>\n <div class=\"mt-1 text-sm opacity-90\">{{ child.status }}</div>\n </div>\n }\n </div>\n\n <!-- SVG CONNECTORS -->\n <svg\n class=\"absolute inset-0 pointer-events-none\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n >\n @for (line of lines; track line) {\n <line\n [attr.x1]=\"line.x1\"\n [attr.y1]=\"line.y1\"\n [attr.x2]=\"line.x2\"\n [attr.y2]=\"line.y2\"\n stroke=\"#1f2937\"\n stroke-width=\"2\"\n />\n }\n </svg>\n\n</div>\n" }]
|
|
3472
|
+
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], container: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }], root: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], children: [{
|
|
4014
3473
|
type: ViewChildren,
|
|
4015
3474
|
args: ['child']
|
|
4016
3475
|
}] } });
|
|
4017
3476
|
|
|
4018
3477
|
class KanbanBoardComponent {
|
|
4019
|
-
columns = [];
|
|
3478
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
4020
3479
|
itemTemplate;
|
|
4021
|
-
columnChanged =
|
|
3480
|
+
columnChanged = output();
|
|
4022
3481
|
/**
|
|
4023
3482
|
* Get all column IDs for connecting drop lists
|
|
4024
3483
|
*/
|
|
4025
3484
|
getColumnIds() {
|
|
4026
|
-
return this.columns.map((col) => col.id);
|
|
3485
|
+
return this.columns().map((col) => col.id);
|
|
4027
3486
|
}
|
|
4028
3487
|
/**
|
|
4029
3488
|
* Handle drop event when item is moved
|
|
@@ -4049,28 +3508,30 @@ class KanbanBoardComponent {
|
|
|
4049
3508
|
currentIndex: event.currentIndex,
|
|
4050
3509
|
});
|
|
4051
3510
|
}
|
|
4052
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4053
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: KanbanBoardComponent, isStandalone: false, selector: "fx-ui-kanban-board", inputs: { columns: "columns", itemTemplate: "itemTemplate" }, outputs: { columnChanged: "columnChanged" }, ngImport: i0, template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns; track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;.kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:calc(var(--spacing, .25rem) * 4);padding:calc(var(--spacing, .25rem) * 4)}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;background-color:var(--color-gray-50, oklch(98.5% .002 247.839));flex-shrink:0}@media (prefers-color-scheme: dark){.kanban-column{background-color:var(--color-gray-800, oklch(27.8% .033 256.848))}}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding:calc(var(--spacing, .25rem) * 4)}@media (prefers-color-scheme: dark){.kanban-column-header{border-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-column-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-gray-900, oklch(21% .034 264.665))}@media (prefers-color-scheme: dark){.kanban-column-title{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-column-count{border-radius:calc(infinity * 1px);background-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-gray-700, oklch(37.3% .034 259.733))}@media (prefers-color-scheme: dark){.kanban-column-count{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}@media (prefers-color-scheme: dark){.kanban-column-count{color:var(--color-gray-300, oklch(87.2% .01 258.338))}}.kanban-column-content{flex:1;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 4);min-height:200px}:where(.kanban-column-content>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing, .25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing, .25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}.kanban-item{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));background-color:var(--color-white, #fff);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s;cursor:move}@media (prefers-color-scheme: dark){.kanban-item{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}@media (prefers-color-scheme: dark){.kanban-item{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.kanban-item-default{padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-900, oklch(21% .034 264.665))}@media (prefers-color-scheme: dark){.kanban-item-default{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-item-placeholder{border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-400, oklch(70.7% .022 261.325));background-color:var(--color-gray-200, oklch(92.8% .006 264.531));opacity:50%;min-height:60px}@media (prefers-color-scheme: dark){.kanban-item-placeholder{border-color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media (prefers-color-scheme: dark){.kanban-item-placeholder{background-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.kanban-column-empty{display:flex;height:calc(var(--spacing, .25rem) * 32);align-items:center;justify-content:center;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-gray-400, oklch(70.7% .022 261.325));border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-300, oklch(87.2% .01 258.338))}@media (prefers-color-scheme: dark){.kanban-column-empty{color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media (prefers-color-scheme: dark){.kanban-column-empty{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.cdk-drag-preview{border-radius:.5rem;opacity:80%;--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-space-y-reverse: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$3.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }] });
|
|
3511
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KanbanBoardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3512
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: KanbanBoardComponent, isStandalone: true, selector: "fx-ui-kanban-board", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { columnChanged: "columnChanged" }, ngImport: i0, template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns(); track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;.kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:calc(var(--spacing, .25rem) * 4);padding:calc(var(--spacing, .25rem) * 4)}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;background-color:var(--color-gray-50, oklch(98.5% .002 247.839));flex-shrink:0}@media(prefers-color-scheme:dark){.kanban-column{background-color:var(--color-gray-800, oklch(27.8% .033 256.848))}}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding:calc(var(--spacing, .25rem) * 4)}@media(prefers-color-scheme:dark){.kanban-column-header{border-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-column-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-column-title{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-column-count{border-radius:calc(infinity * 1px);background-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-gray-700, oklch(37.3% .034 259.733))}@media(prefers-color-scheme:dark){.kanban-column-count{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}@media(prefers-color-scheme:dark){.kanban-column-count{color:var(--color-gray-300, oklch(87.2% .01 258.338))}}.kanban-column-content{flex:1;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 4);min-height:200px}:where(.kanban-column-content>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing, .25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing, .25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}.kanban-item{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));background-color:var(--color-white, #fff);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s;cursor:move}@media(prefers-color-scheme:dark){.kanban-item{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}@media(prefers-color-scheme:dark){.kanban-item{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.kanban-item-default{padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-item-default{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-item-placeholder{border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-400, oklch(70.7% .022 261.325));background-color:var(--color-gray-200, oklch(92.8% .006 264.531));opacity:50%;min-height:60px}@media(prefers-color-scheme:dark){.kanban-item-placeholder{border-color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-item-placeholder{background-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.kanban-column-empty{display:flex;height:calc(var(--spacing, .25rem) * 32);align-items:center;justify-content:center;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-gray-400, oklch(70.7% .022 261.325));border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-300, oklch(87.2% .01 258.338))}@media(prefers-color-scheme:dark){.kanban-column-empty{color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-column-empty{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.cdk-drag-preview{border-radius:.5rem;opacity:80%;--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-space-y-reverse: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4054
3513
|
}
|
|
4055
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3514
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KanbanBoardComponent, decorators: [{
|
|
4056
3515
|
type: Component,
|
|
4057
|
-
args: [{ selector: 'fx-ui-kanban-board',
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
3516
|
+
args: [{ selector: 'fx-ui-kanban-board', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3517
|
+
CdkDropList,
|
|
3518
|
+
CdkDrag,
|
|
3519
|
+
CdkDragPlaceholder,
|
|
3520
|
+
NgTemplateOutlet,
|
|
3521
|
+
], template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns(); track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;.kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:calc(var(--spacing, .25rem) * 4);padding:calc(var(--spacing, .25rem) * 4)}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;background-color:var(--color-gray-50, oklch(98.5% .002 247.839));flex-shrink:0}@media(prefers-color-scheme:dark){.kanban-column{background-color:var(--color-gray-800, oklch(27.8% .033 256.848))}}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding:calc(var(--spacing, .25rem) * 4)}@media(prefers-color-scheme:dark){.kanban-column-header{border-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-column-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-column-title{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-column-count{border-radius:calc(infinity * 1px);background-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-gray-700, oklch(37.3% .034 259.733))}@media(prefers-color-scheme:dark){.kanban-column-count{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}@media(prefers-color-scheme:dark){.kanban-column-count{color:var(--color-gray-300, oklch(87.2% .01 258.338))}}.kanban-column-content{flex:1;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 4);min-height:200px}:where(.kanban-column-content>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing, .25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing, .25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}.kanban-item{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));background-color:var(--color-white, #fff);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s;cursor:move}@media(prefers-color-scheme:dark){.kanban-item{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}@media(prefers-color-scheme:dark){.kanban-item{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.kanban-item-default{padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-item-default{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-item-placeholder{border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-400, oklch(70.7% .022 261.325));background-color:var(--color-gray-200, oklch(92.8% .006 264.531));opacity:50%;min-height:60px}@media(prefers-color-scheme:dark){.kanban-item-placeholder{border-color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-item-placeholder{background-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.kanban-column-empty{display:flex;height:calc(var(--spacing, .25rem) * 32);align-items:center;justify-content:center;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-gray-400, oklch(70.7% .022 261.325));border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-300, oklch(87.2% .01 258.338))}@media(prefers-color-scheme:dark){.kanban-column-empty{color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-column-empty{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.cdk-drag-preview{border-radius:.5rem;opacity:80%;--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-space-y-reverse: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3522
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], itemTemplate: [{
|
|
3523
|
+
type: Input
|
|
3524
|
+
}], columnChanged: [{ type: i0.Output, args: ["columnChanged"] }] } });
|
|
4065
3525
|
|
|
4066
3526
|
class DrawerComponent {
|
|
4067
3527
|
router;
|
|
4068
|
-
|
|
3528
|
+
cdr = inject(ChangeDetectorRef);
|
|
3529
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
4069
3530
|
isExpanded = true;
|
|
4070
3531
|
logo;
|
|
4071
3532
|
version;
|
|
4072
|
-
toggleExpanded =
|
|
4073
|
-
itemClicked =
|
|
3533
|
+
toggleExpanded = output();
|
|
3534
|
+
itemClicked = output();
|
|
4074
3535
|
expandedItems = new Set();
|
|
4075
3536
|
currentRoute = '';
|
|
4076
3537
|
destroy$ = new Subject();
|
|
@@ -4086,6 +3547,7 @@ class DrawerComponent {
|
|
|
4086
3547
|
.subscribe((event) => {
|
|
4087
3548
|
this.currentRoute = event.urlAfterRedirects || event.url;
|
|
4088
3549
|
this.autoExpandActiveParents();
|
|
3550
|
+
this.cdr.markForCheck();
|
|
4089
3551
|
});
|
|
4090
3552
|
// Auto-expand parents of active route on init
|
|
4091
3553
|
this.autoExpandActiveParents();
|
|
@@ -4157,7 +3619,7 @@ class DrawerComponent {
|
|
|
4157
3619
|
}
|
|
4158
3620
|
return false;
|
|
4159
3621
|
};
|
|
4160
|
-
expandParents(this.items);
|
|
3622
|
+
expandParents(this.items());
|
|
4161
3623
|
}
|
|
4162
3624
|
getAccordionState(itemId) {
|
|
4163
3625
|
return this.isAccordionExpanded(itemId) ? 'expanded' : 'collapsed';
|
|
@@ -4165,8 +3627,8 @@ class DrawerComponent {
|
|
|
4165
3627
|
getDrawerState() {
|
|
4166
3628
|
return this.isExpanded ? 'expanded' : 'collapsed';
|
|
4167
3629
|
}
|
|
4168
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4169
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DrawerComponent, isStandalone: false, selector: "fx-ui-drawer", inputs: { items: "items", isExpanded: "isExpanded", logo: "logo", version: "version" }, outputs: { toggleExpanded: "toggleExpanded", itemClicked: "itemClicked" }, ngImport: i0, template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n alt=\"Home\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n\n <!-- Version -->\n <div *ngIf=\"version\" class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n <span *ngIf=\"isExpanded\">{{ version }}</span>\n <span *ngIf=\"!isExpanded\" class=\"drawer-version-dot\"></span>\n </div>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n [attr.aria-label]=\"isExpanded ? 'Collapse navigation' : 'Expand navigation'\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:rgb(var(--border-default))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;background-color:rgb(var(--bg-primary));padding-inline:calc(var(--spacing, .25rem) * 2);transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{background-color:rgb(var(--bg-primary-hover));--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-nav{flex:1;overflow-x:hidden;overflow-y:auto;padding-block:calc(var(--spacing, .25rem) * 2)}.drawer-nav::-webkit-scrollbar{width:calc(var(--spacing, .25rem) * 1.5)}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;background-color:rgb(var(--border-default))}.drawer-nav::-webkit-scrollbar-thumb:hover{background-color:rgb(var(--text-placeholder))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:var(--spacing, .25rem);display:flex;min-height:calc(var(--spacing, .25rem) * 8);width:100%;cursor:pointer;align-items:center;border-radius:.25rem;--tw-border-style: none;border-style:none;background-color:transparent;padding-inline:1rem;padding-block:calc(var(--spacing, .25rem) * 2);color:rgb(var(--text-primary));text-decoration-line:none;transition:all .2s ease;-webkit-tap-highlight-color:transparent;--tw-outline-style: none;outline-style:none}.drawer-item:hover{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:rgb(var(--bg-primary-hover));color:rgb(var(--text-primary))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-white, #fff)}.drawer-item.active .item-icon{color:var(--color-white, #fff)}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.item-content{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3);overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1;overflow:hidden;text-align:left;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);text-overflow:ellipsis;white-space:nowrap}.chevron-icon{margin-left:auto;flex-shrink:0;color:rgb(var(--text-primary));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;align-items:center;justify-content:center;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgb(var(--border-default));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);font-size:11px;color:rgb(var(--text-placeholder));-webkit-user-select:none;user-select:none;font-family:Roboto,monospace}.drawer-version-dot{display:block;height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);background-color:rgb(var(--text-placeholder))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-scale-x{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-y{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-z{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i57.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], animations: [
|
|
3630
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DrawerComponent, deps: [{ token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
3631
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: DrawerComponent, isStandalone: true, selector: "fx-ui-drawer", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, isExpanded: { classPropertyName: "isExpanded", publicName: "isExpanded", isSignal: false, isRequired: false, transformFunction: null }, logo: { classPropertyName: "logo", publicName: "logo", isSignal: false, isRequired: false, transformFunction: null }, version: { classPropertyName: "version", publicName: "version", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { toggleExpanded: "toggleExpanded", itemClicked: "itemClicked" }, ngImport: i0, template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n alt=\"Home\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n @for (item of items(); track item) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n }\n </nav>\n\n <!-- Version -->\n @if (version) {\n <div class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n @if (isExpanded) {\n <span>{{ version }}</span>\n }\n @if (!isExpanded) {\n <span class=\"drawer-version-dot\"></span>\n }\n </div>\n }\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n [attr.aria-label]=\"isExpanded ? 'Collapse navigation' : 'Expand navigation'\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n @if (item.route && !item.children) {\n <a\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n </div>\n </a>\n }\n\n @if (!item.route || item.children) {\n <button\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n @if (isExpanded && item.children && item.children.length > 0) {\n <fx-ui-hero-icon\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n }\n </div>\n </button>\n }\n\n <!-- Accordion Children -->\n @if (item.children && item.children.length > 0) {\n <div\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n @for (child of item.children; track child) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:rgb(var(--border-default))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;background-color:rgb(var(--bg-primary));padding-inline:calc(var(--spacing, .25rem) * 2);transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{background-color:rgb(var(--bg-primary-hover));--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-nav{flex:1;overflow-x:hidden;overflow-y:auto;padding-block:calc(var(--spacing, .25rem) * 2)}.drawer-nav::-webkit-scrollbar{width:calc(var(--spacing, .25rem) * 1.5)}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;background-color:rgb(var(--border-default))}.drawer-nav::-webkit-scrollbar-thumb:hover{background-color:rgb(var(--text-placeholder))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:var(--spacing, .25rem);display:flex;min-height:calc(var(--spacing, .25rem) * 8);width:100%;cursor:pointer;align-items:center;border-radius:.25rem;--tw-border-style: none;border-style:none;background-color:transparent;padding-inline:1rem;padding-block:calc(var(--spacing, .25rem) * 2);color:rgb(var(--text-primary));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:rgb(var(--bg-primary-hover));color:rgb(var(--text-primary))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-white, #fff)}.drawer-item.active .item-icon{color:var(--color-white, #fff)}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-item{-webkit-tap-highlight-color:transparent;--tw-outline-style: none;outline-style:none}.item-content{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3);overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1;overflow:hidden;text-align:left;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);text-overflow:ellipsis;white-space:nowrap}.chevron-icon{margin-left:auto;flex-shrink:0;color:rgb(var(--text-primary));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;align-items:center;justify-content:center;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgb(var(--border-default));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);font-size:11px;color:rgb(var(--text-placeholder));-webkit-user-select:none;user-select:none;font-family:Roboto,monospace}.drawer-version-dot{display:block;height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);background-color:rgb(var(--text-placeholder))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-scale-x{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-y{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-z{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], animations: [
|
|
4170
3632
|
trigger('drawerExpand', [
|
|
4171
3633
|
state('collapsed', style({ width: '70px' })),
|
|
4172
3634
|
state('expanded', style({ width: '260px' })),
|
|
@@ -4177,11 +3639,11 @@ class DrawerComponent {
|
|
|
4177
3639
|
state('expanded', style({ height: '*', overflow: 'visible', opacity: 1 })),
|
|
4178
3640
|
transition('collapsed <=> expanded', animate('300ms cubic-bezier(0.4, 0, 0.2, 1)')),
|
|
4179
3641
|
]),
|
|
4180
|
-
] });
|
|
3642
|
+
], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4181
3643
|
}
|
|
4182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3644
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DrawerComponent, decorators: [{
|
|
4183
3645
|
type: Component,
|
|
4184
|
-
args: [{ selector: 'fx-ui-drawer',
|
|
3646
|
+
args: [{ selector: 'fx-ui-drawer', animations: [
|
|
4185
3647
|
trigger('drawerExpand', [
|
|
4186
3648
|
state('collapsed', style({ width: '70px' })),
|
|
4187
3649
|
state('expanded', style({ width: '260px' })),
|
|
@@ -4192,64 +3654,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4192
3654
|
state('expanded', style({ height: '*', overflow: 'visible', opacity: 1 })),
|
|
4193
3655
|
transition('collapsed <=> expanded', animate('300ms cubic-bezier(0.4, 0, 0.2, 1)')),
|
|
4194
3656
|
]),
|
|
4195
|
-
], template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n alt=\"Home\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n\n <!-- Version -->\n <div *ngIf=\"version\" class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n <span *ngIf=\"isExpanded\">{{ version }}</span>\n <span *ngIf=\"!isExpanded\" class=\"drawer-version-dot\"></span>\n </div>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n [attr.aria-label]=\"isExpanded ? 'Collapse navigation' : 'Expand navigation'\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:rgb(var(--border-default))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;background-color:rgb(var(--bg-primary));padding-inline:calc(var(--spacing, .25rem) * 2);transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{background-color:rgb(var(--bg-primary-hover));--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-nav{flex:1;overflow-x:hidden;overflow-y:auto;padding-block:calc(var(--spacing, .25rem) * 2)}.drawer-nav::-webkit-scrollbar{width:calc(var(--spacing, .25rem) * 1.5)}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;background-color:rgb(var(--border-default))}.drawer-nav::-webkit-scrollbar-thumb:hover{background-color:rgb(var(--text-placeholder))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:var(--spacing, .25rem);display:flex;min-height:calc(var(--spacing, .25rem) * 8);width:100%;cursor:pointer;align-items:center;border-radius:.25rem;--tw-border-style: none;border-style:none;background-color:transparent;padding-inline:1rem;padding-block:calc(var(--spacing, .25rem) * 2);color:rgb(var(--text-primary));text-decoration-line:none;transition:all .2s ease;-webkit-tap-highlight-color:transparent;--tw-outline-style: none;outline-style:none}.drawer-item:hover{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:rgb(var(--bg-primary-hover));color:rgb(var(--text-primary))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-white, #fff)}.drawer-item.active .item-icon{color:var(--color-white, #fff)}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.item-content{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3);overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1;overflow:hidden;text-align:left;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);text-overflow:ellipsis;white-space:nowrap}.chevron-icon{margin-left:auto;flex-shrink:0;color:rgb(var(--text-primary));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;align-items:center;justify-content:center;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgb(var(--border-default));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);font-size:11px;color:rgb(var(--text-placeholder));-webkit-user-select:none;user-select:none;font-family:Roboto,monospace}.drawer-version-dot{display:block;height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);background-color:rgb(var(--text-placeholder))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-scale-x{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-y{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-z{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
3657
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3658
|
+
NgClass,
|
|
3659
|
+
NgTemplateOutlet,
|
|
3660
|
+
MatTooltip,
|
|
3661
|
+
HeroIconComponent,
|
|
3662
|
+
RouterLink,
|
|
3663
|
+
], template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n alt=\"Home\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n @for (item of items(); track item) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n }\n </nav>\n\n <!-- Version -->\n @if (version) {\n <div class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n @if (isExpanded) {\n <span>{{ version }}</span>\n }\n @if (!isExpanded) {\n <span class=\"drawer-version-dot\"></span>\n }\n </div>\n }\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n [attr.aria-label]=\"isExpanded ? 'Collapse navigation' : 'Expand navigation'\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n @if (item.route && !item.children) {\n <a\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n </div>\n </a>\n }\n\n @if (!item.route || item.children) {\n <button\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n @if (isExpanded && item.children && item.children.length > 0) {\n <fx-ui-hero-icon\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n }\n </div>\n </button>\n }\n\n <!-- Accordion Children -->\n @if (item.children && item.children.length > 0) {\n <div\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n @for (child of item.children; track child) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:rgb(var(--border-default))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;background-color:rgb(var(--bg-primary));padding-inline:calc(var(--spacing, .25rem) * 2);transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{background-color:rgb(var(--bg-primary-hover));--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-nav{flex:1;overflow-x:hidden;overflow-y:auto;padding-block:calc(var(--spacing, .25rem) * 2)}.drawer-nav::-webkit-scrollbar{width:calc(var(--spacing, .25rem) * 1.5)}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;background-color:rgb(var(--border-default))}.drawer-nav::-webkit-scrollbar-thumb:hover{background-color:rgb(var(--text-placeholder))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:var(--spacing, .25rem);display:flex;min-height:calc(var(--spacing, .25rem) * 8);width:100%;cursor:pointer;align-items:center;border-radius:.25rem;--tw-border-style: none;border-style:none;background-color:transparent;padding-inline:1rem;padding-block:calc(var(--spacing, .25rem) * 2);color:rgb(var(--text-primary));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:rgb(var(--bg-primary-hover));color:rgb(var(--text-primary))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-white, #fff)}.drawer-item.active .item-icon{color:var(--color-white, #fff)}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-item{-webkit-tap-highlight-color:transparent;--tw-outline-style: none;outline-style:none}.item-content{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3);overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1;overflow:hidden;text-align:left;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);text-overflow:ellipsis;white-space:nowrap}.chevron-icon{margin-left:auto;flex-shrink:0;color:rgb(var(--text-primary));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;align-items:center;justify-content:center;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgb(var(--border-default));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);font-size:11px;color:rgb(var(--text-placeholder));-webkit-user-select:none;user-select:none;font-family:Roboto,monospace}.drawer-version-dot{display:block;height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);background-color:rgb(var(--text-placeholder))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-scale-x{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-y{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-z{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3664
|
+
}], ctorParameters: () => [{ type: i2$1.Router }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], isExpanded: [{
|
|
4199
3665
|
type: Input
|
|
4200
3666
|
}], logo: [{
|
|
4201
3667
|
type: Input
|
|
4202
3668
|
}], version: [{
|
|
4203
3669
|
type: Input
|
|
4204
|
-
}], toggleExpanded: [{
|
|
4205
|
-
type: Output
|
|
4206
|
-
}], itemClicked: [{
|
|
4207
|
-
type: Output
|
|
4208
|
-
}] } });
|
|
3670
|
+
}], toggleExpanded: [{ type: i0.Output, args: ["toggleExpanded"] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }] } });
|
|
4209
3671
|
|
|
4210
3672
|
/** Row-card skeleton placeholder for master-detail list panes. */
|
|
4211
3673
|
class SkeletonListComponent {
|
|
4212
|
-
rows = 5;
|
|
3674
|
+
rows = input(5, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
4213
3675
|
range(n) {
|
|
4214
3676
|
return Array.from({ length: Number(n) || 0 }, (_, i) => i);
|
|
4215
3677
|
}
|
|
4216
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4217
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3678
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3679
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SkeletonListComponent, isStandalone: true, selector: "fx-ui-skeleton-list", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-normal animate-pulse\">\n @for (r of range(rows()); track r) {\n <div class=\"rounded-lg border border-border-default p-semi\">\n <div class=\"flex items-center gap-normal mb-small\">\n <div class=\"w-8 h-8 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"h-4 flex-1 rounded bg-bg-hover\"></div>\n <div class=\"h-5 w-12 rounded-full bg-bg-hover shrink-0\"></div>\n </div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n }\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4218
3680
|
}
|
|
4219
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3681
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonListComponent, decorators: [{
|
|
4220
3682
|
type: Component,
|
|
4221
|
-
args: [{ selector: 'fx-ui-skeleton-list',
|
|
4222
|
-
}], propDecorators: { rows: [{
|
|
4223
|
-
type: Input
|
|
4224
|
-
}] } });
|
|
3683
|
+
args: [{ selector: 'fx-ui-skeleton-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-normal animate-pulse\">\n @for (r of range(rows()); track r) {\n <div class=\"rounded-lg border border-border-default p-semi\">\n <div class=\"flex items-center gap-normal mb-small\">\n <div class=\"w-8 h-8 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"h-4 flex-1 rounded bg-bg-hover\"></div>\n <div class=\"h-5 w-12 rounded-full bg-bg-hover shrink-0\"></div>\n </div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n }\n</div>\n" }]
|
|
3684
|
+
}], propDecorators: { rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }] } });
|
|
4225
3685
|
|
|
4226
3686
|
/** Card-shaped skeleton placeholder for detail panels. */
|
|
4227
3687
|
class SkeletonDetailComponent {
|
|
4228
3688
|
/** Number of content cards rendered below the header card. */
|
|
4229
|
-
cards = 3;
|
|
3689
|
+
cards = input(3, ...(ngDevMode ? [{ debugName: "cards" }] : /* istanbul ignore next */ []));
|
|
4230
3690
|
/** Rows per content card. */
|
|
4231
|
-
rows = 4;
|
|
3691
|
+
rows = input(4, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
4232
3692
|
range(n) {
|
|
4233
3693
|
return Array.from({ length: Number(n) || 0 }, (_, i) => i);
|
|
4234
3694
|
}
|
|
4235
3695
|
rowWidth(i) {
|
|
4236
3696
|
return [90, 70, 80, 60][i % 4];
|
|
4237
3697
|
}
|
|
4238
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4239
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3698
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3699
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SkeletonDetailComponent, isStandalone: true, selector: "fx-ui-skeleton-detail", inputs: { cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-xl animate-pulse\">\n <div class=\"card-common\">\n <div class=\"flex items-start gap-normal\">\n <div class=\"w-10 h-10 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"flex-1 min-w-0 flex flex-col gap-normal\">\n <div class=\"h-5 w-1/2 rounded bg-bg-hover\"></div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n </div>\n </div>\n\n @for (c of range(cards()); track c) {\n <div class=\"card-common flex flex-col gap-large\">\n <div class=\"h-4 w-1/3 rounded bg-bg-hover\"></div>\n <div class=\"flex flex-col gap-normal\">\n @for (r of range(rows()); track r) {\n <div class=\"h-3 rounded bg-bg-hover\" [style.width.%]=\"rowWidth(r)\"></div>\n }\n </div>\n </div>\n }\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4240
3700
|
}
|
|
4241
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3701
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonDetailComponent, decorators: [{
|
|
4242
3702
|
type: Component,
|
|
4243
|
-
args: [{ selector: 'fx-ui-skeleton-detail',
|
|
4244
|
-
}], propDecorators: { cards: [{
|
|
4245
|
-
type: Input
|
|
4246
|
-
}], rows: [{
|
|
4247
|
-
type: Input
|
|
4248
|
-
}] } });
|
|
3703
|
+
args: [{ selector: 'fx-ui-skeleton-detail', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-xl animate-pulse\">\n <div class=\"card-common\">\n <div class=\"flex items-start gap-normal\">\n <div class=\"w-10 h-10 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"flex-1 min-w-0 flex flex-col gap-normal\">\n <div class=\"h-5 w-1/2 rounded bg-bg-hover\"></div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n </div>\n </div>\n\n @for (c of range(cards()); track c) {\n <div class=\"card-common flex flex-col gap-large\">\n <div class=\"h-4 w-1/3 rounded bg-bg-hover\"></div>\n <div class=\"flex flex-col gap-normal\">\n @for (r of range(rows()); track r) {\n <div class=\"h-3 rounded bg-bg-hover\" [style.width.%]=\"rowWidth(r)\"></div>\n }\n </div>\n </div>\n }\n</div>\n" }]
|
|
3704
|
+
}], propDecorators: { cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }] } });
|
|
4249
3705
|
|
|
4250
3706
|
/** KPI tile row: big number + tinted icon box + caption, in a responsive grid. */
|
|
4251
3707
|
class StatCardsComponent {
|
|
4252
|
-
cards = [];
|
|
3708
|
+
cards = input([], ...(ngDevMode ? [{ debugName: "cards" }] : /* istanbul ignore next */ []));
|
|
4253
3709
|
/** Grid columns; defaults to one column per card. */
|
|
4254
3710
|
cols;
|
|
4255
3711
|
get gridColumns() {
|
|
@@ -4265,38 +3721,36 @@ class StatCardsComponent {
|
|
|
4265
3721
|
boxClass(card) {
|
|
4266
3722
|
return card.tone ? toneBadge(card.tone) : 'bg-bg-hover text-text-secondary';
|
|
4267
3723
|
}
|
|
4268
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4269
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3724
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: StatCardsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3725
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: StatCardsComponent, isStandalone: true, selector: "fx-ui-stat-cards", inputs: { cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: false, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"grid gap-normal\" [ngStyle]=\"{ 'grid-template-columns': gridColumns }\">\n @for (card of cards(); track card.label) {\n <div class=\"card-common flex items-center gap-normal\">\n @if (card.icon) {\n <div\n class=\"w-10 h-10 rounded-lg flex items-center justify-center shrink-0\"\n [ngClass]=\"boxClass(card)\"\n >\n <fx-ui-hero-icon [icon]=\"card.icon\" [size]=\"20\"></fx-ui-hero-icon>\n </div>\n }\n <div class=\"flex flex-col min-w-0\">\n <span class=\"txt-heading-04\" [ngClass]=\"numClass(card)\">{{ card.value }}</span>\n <span class=\"txt-utility-caption text-text-secondary truncate\">{{ card.label }}</span>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4270
3726
|
}
|
|
4271
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: StatCardsComponent, decorators: [{
|
|
4272
3728
|
type: Component,
|
|
4273
|
-
args: [{ selector: 'fx-ui-stat-cards',
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
3729
|
+
args: [{ selector: 'fx-ui-stat-cards', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3730
|
+
NgStyle,
|
|
3731
|
+
NgClass,
|
|
3732
|
+
HeroIconComponent,
|
|
3733
|
+
], template: "<div class=\"grid gap-normal\" [ngStyle]=\"{ 'grid-template-columns': gridColumns }\">\n @for (card of cards(); track card.label) {\n <div class=\"card-common flex items-center gap-normal\">\n @if (card.icon) {\n <div\n class=\"w-10 h-10 rounded-lg flex items-center justify-center shrink-0\"\n [ngClass]=\"boxClass(card)\"\n >\n <fx-ui-hero-icon [icon]=\"card.icon\" [size]=\"20\"></fx-ui-hero-icon>\n </div>\n }\n <div class=\"flex flex-col min-w-0\">\n <span class=\"txt-heading-04\" [ngClass]=\"numClass(card)\">{{ card.value }}</span>\n <span class=\"txt-utility-caption text-text-secondary truncate\">{{ card.label }}</span>\n </div>\n </div>\n }\n</div>\n" }]
|
|
3734
|
+
}], propDecorators: { cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: false }] }], cols: [{
|
|
4277
3735
|
type: Input
|
|
4278
3736
|
}] } });
|
|
4279
3737
|
|
|
4280
3738
|
/** Centered "no data" block. The message is caller-translated (no i18n in lib). */
|
|
4281
3739
|
class EmptyStateComponent {
|
|
4282
|
-
message = 'No data';
|
|
3740
|
+
message = input('No data', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
4283
3741
|
/** Optional icon (hero-icon name). */
|
|
4284
3742
|
icon;
|
|
4285
3743
|
/** Min height of the block, CSS length. */
|
|
4286
|
-
height = '120px';
|
|
4287
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4288
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3744
|
+
height = input('120px', ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
3745
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3746
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: EmptyStateComponent, isStandalone: true, selector: "fx-ui-empty-state", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: false, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"flex flex-col items-center justify-center gap-small w-full\"\n [style.minHeight]=\"height()\"\n>\n @if (icon) {\n <fx-ui-hero-icon class=\"text-text-placeholder\" [icon]=\"icon\" [size]=\"24\"></fx-ui-hero-icon>\n }\n <div class=\"txt-default text-text-placeholder\">{{ message() }}</div>\n</div>\n", dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4289
3747
|
}
|
|
4290
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3748
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: EmptyStateComponent, decorators: [{
|
|
4291
3749
|
type: Component,
|
|
4292
|
-
args: [{ selector: 'fx-ui-empty-state',
|
|
4293
|
-
}], propDecorators: { message: [{
|
|
4294
|
-
type: Input
|
|
4295
|
-
}], icon: [{
|
|
4296
|
-
type: Input
|
|
4297
|
-
}], height: [{
|
|
3750
|
+
args: [{ selector: 'fx-ui-empty-state', changeDetection: ChangeDetectionStrategy.OnPush, imports: [HeroIconComponent], template: "<div\n class=\"flex flex-col items-center justify-center gap-small w-full\"\n [style.minHeight]=\"height()\"\n>\n @if (icon) {\n <fx-ui-hero-icon class=\"text-text-placeholder\" [icon]=\"icon\" [size]=\"24\"></fx-ui-hero-icon>\n }\n <div class=\"txt-default text-text-placeholder\">{{ message() }}</div>\n</div>\n" }]
|
|
3751
|
+
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], icon: [{
|
|
4298
3752
|
type: Input
|
|
4299
|
-
}] } });
|
|
3753
|
+
}], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
|
|
4300
3754
|
|
|
4301
3755
|
/**
|
|
4302
3756
|
* Tone-tinted filter chip row. Replaces the per-tab chipClass() copies —
|
|
@@ -4305,8 +3759,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4305
3759
|
*/
|
|
4306
3760
|
class FilterChipsComponent {
|
|
4307
3761
|
options = [];
|
|
3762
|
+
/* Accepts undefined so screens can bind [value]="filters.x" where the
|
|
3763
|
+
* filter bag keys are optional; '' and undefined both mean "All". */
|
|
4308
3764
|
value = '';
|
|
4309
|
-
valueChange =
|
|
3765
|
+
valueChange = output();
|
|
4310
3766
|
/** Per-value tone overrides (e.g. { Safe: 'information', Protected: 'discovery' as any }). */
|
|
4311
3767
|
toneOverrides = {};
|
|
4312
3768
|
select(option) {
|
|
@@ -4314,7 +3770,7 @@ class FilterChipsComponent {
|
|
|
4314
3770
|
this.valueChange.emit(option.value);
|
|
4315
3771
|
}
|
|
4316
3772
|
chipClass(option) {
|
|
4317
|
-
const active = this.value === option.value;
|
|
3773
|
+
const active = (this.value ?? '') === option.value;
|
|
4318
3774
|
if (!option.value) {
|
|
4319
3775
|
return active
|
|
4320
3776
|
? 'bg-text-primary text-text-focus'
|
|
@@ -4328,19 +3784,17 @@ class FilterChipsComponent {
|
|
|
4328
3784
|
}
|
|
4329
3785
|
return active ? `${toneBg(tone)} text-text-focus` : `${toneBadge(tone)} hover:opacity-50`;
|
|
4330
3786
|
}
|
|
4331
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4332
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3787
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3788
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: FilterChipsComponent, isStandalone: true, selector: "fx-ui-filter-chips", inputs: { options: "options", value: "value", toneOverrides: "toneOverrides" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"flex flex-wrap items-center gap-small\">\n @for (option of options; track option.value) {\n <button\n type=\"button\"\n class=\"px-3 py-1 rounded-full txt-utility-caption font-medium transition-colors cursor-pointer\"\n [ngClass]=\"chipClass(option)\"\n (click)=\"select(option)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4333
3789
|
}
|
|
4334
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3790
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FilterChipsComponent, decorators: [{
|
|
4335
3791
|
type: Component,
|
|
4336
|
-
args: [{ selector: 'fx-ui-filter-chips',
|
|
3792
|
+
args: [{ selector: 'fx-ui-filter-chips', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<div class=\"flex flex-wrap items-center gap-small\">\n @for (option of options; track option.value) {\n <button\n type=\"button\"\n class=\"px-3 py-1 rounded-full txt-utility-caption font-medium transition-colors cursor-pointer\"\n [ngClass]=\"chipClass(option)\"\n (click)=\"select(option)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n" }]
|
|
4337
3793
|
}], propDecorators: { options: [{
|
|
4338
3794
|
type: Input
|
|
4339
3795
|
}], value: [{
|
|
4340
3796
|
type: Input
|
|
4341
|
-
}], valueChange: [{
|
|
4342
|
-
type: Output
|
|
4343
|
-
}], toneOverrides: [{
|
|
3797
|
+
}], valueChange: [{ type: i0.Output, args: ["valueChange"] }], toneOverrides: [{
|
|
4344
3798
|
type: Input
|
|
4345
3799
|
}] } });
|
|
4346
3800
|
|
|
@@ -4348,7 +3802,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4348
3802
|
class MeterComponent {
|
|
4349
3803
|
value = 0;
|
|
4350
3804
|
max = 10;
|
|
4351
|
-
tone = null;
|
|
3805
|
+
tone = input(null, ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
4352
3806
|
/** Caller-translated texts; omitted → bar only. */
|
|
4353
3807
|
label;
|
|
4354
3808
|
caption;
|
|
@@ -4358,21 +3812,19 @@ class MeterComponent {
|
|
|
4358
3812
|
return Math.min(100, Math.max(0, pct));
|
|
4359
3813
|
}
|
|
4360
3814
|
get fillClass() {
|
|
4361
|
-
return toneBg(this.tone);
|
|
3815
|
+
return toneBg(this.tone());
|
|
4362
3816
|
}
|
|
4363
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4364
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3817
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MeterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3818
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: MeterComponent, isStandalone: true, selector: "fx-ui-meter", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: false, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-small w-full\">\n @if (label || caption) {\n <div class=\"flex items-center justify-between gap-normal\">\n @if (label) {\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n }\n @if (caption) {\n <span class=\"txt-utility-caption text-text-secondary\">{{ caption }}</span>\n }\n </div>\n }\n <div\n class=\"h-2 rounded-full bg-bg-hover overflow-hidden\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-label]=\"label || null\"\n >\n <div class=\"h-full rounded-full\" [ngClass]=\"fillClass\" [style.width.%]=\"percent\"></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4365
3819
|
}
|
|
4366
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3820
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MeterComponent, decorators: [{
|
|
4367
3821
|
type: Component,
|
|
4368
|
-
args: [{ selector: 'fx-ui-meter',
|
|
3822
|
+
args: [{ selector: 'fx-ui-meter', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<div class=\"flex flex-col gap-small w-full\">\n @if (label || caption) {\n <div class=\"flex items-center justify-between gap-normal\">\n @if (label) {\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n }\n @if (caption) {\n <span class=\"txt-utility-caption text-text-secondary\">{{ caption }}</span>\n }\n </div>\n }\n <div\n class=\"h-2 rounded-full bg-bg-hover overflow-hidden\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-label]=\"label || null\"\n >\n <div class=\"h-full rounded-full\" [ngClass]=\"fillClass\" [style.width.%]=\"percent\"></div>\n </div>\n</div>\n" }]
|
|
4369
3823
|
}], propDecorators: { value: [{
|
|
4370
3824
|
type: Input
|
|
4371
3825
|
}], max: [{
|
|
4372
3826
|
type: Input
|
|
4373
|
-
}], tone: [{
|
|
4374
|
-
type: Input
|
|
4375
|
-
}], label: [{
|
|
3827
|
+
}], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], label: [{
|
|
4376
3828
|
type: Input
|
|
4377
3829
|
}], caption: [{
|
|
4378
3830
|
type: Input
|
|
@@ -4381,26 +3833,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4381
3833
|
/** Detail-panel section: card with an icon + heading header and projected body. */
|
|
4382
3834
|
class SectionCardComponent {
|
|
4383
3835
|
/** Caller-translated heading. */
|
|
4384
|
-
title = '';
|
|
3836
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
4385
3837
|
/** hero-icon name; omitted → text-only header. */
|
|
4386
3838
|
icon;
|
|
4387
|
-
iconTone = null;
|
|
3839
|
+
iconTone = input(null, ...(ngDevMode ? [{ debugName: "iconTone" }] : /* istanbul ignore next */ []));
|
|
4388
3840
|
get iconClass() {
|
|
4389
|
-
|
|
3841
|
+
const iconTone = this.iconTone();
|
|
3842
|
+
return iconTone ? toneText(iconTone) : 'text-text-secondary';
|
|
4390
3843
|
}
|
|
4391
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4392
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3844
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SectionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3845
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SectionCardComponent, isStandalone: true, selector: "fx-ui-section-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: false, isRequired: false, transformFunction: null }, iconTone: { classPropertyName: "iconTone", publicName: "iconTone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"card-common\">\n <div class=\"flex items-center gap-normal mb-large\">\n @if (icon) {\n <fx-ui-hero-icon [ngClass]=\"iconClass\" [icon]=\"icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span class=\"txt-heading-06\">{{ title() }}</span>\n </div>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4393
3846
|
}
|
|
4394
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3847
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SectionCardComponent, decorators: [{
|
|
4395
3848
|
type: Component,
|
|
4396
|
-
args: [{ selector: 'fx-ui-section-card',
|
|
4397
|
-
}], propDecorators: { title: [{
|
|
4398
|
-
type: Input
|
|
4399
|
-
}], icon: [{
|
|
3849
|
+
args: [{ selector: 'fx-ui-section-card', changeDetection: ChangeDetectionStrategy.OnPush, imports: [HeroIconComponent, NgClass], template: "<div class=\"card-common\">\n <div class=\"flex items-center gap-normal mb-large\">\n @if (icon) {\n <fx-ui-hero-icon [ngClass]=\"iconClass\" [icon]=\"icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span class=\"txt-heading-06\">{{ title() }}</span>\n </div>\n <ng-content></ng-content>\n</div>\n" }]
|
|
3850
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], icon: [{
|
|
4400
3851
|
type: Input
|
|
4401
|
-
}], iconTone: [{
|
|
4402
|
-
type: Input
|
|
4403
|
-
}] } });
|
|
3852
|
+
}], iconTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconTone", required: false }] }] } });
|
|
4404
3853
|
|
|
4405
3854
|
/**
|
|
4406
3855
|
* Label-over-value field for detail panels. The label uses txt-field-label
|
|
@@ -4409,17 +3858,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4409
3858
|
*/
|
|
4410
3859
|
class InfoFieldComponent {
|
|
4411
3860
|
/** Caller-translated label. */
|
|
4412
|
-
label = '';
|
|
3861
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
4413
3862
|
value;
|
|
4414
3863
|
/** Colours the value; null/undefined renders the primary text colour. */
|
|
4415
3864
|
tone = null;
|
|
4416
3865
|
/** Monospace value (hashes, paths). */
|
|
4417
3866
|
mono = false;
|
|
4418
3867
|
/** Placeholder when value is empty. */
|
|
4419
|
-
placeholder = '---';
|
|
3868
|
+
placeholder = input('---', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
4420
3869
|
get displayValue() {
|
|
4421
3870
|
if (this.value === null || this.value === undefined || this.value === '') {
|
|
4422
|
-
return this.placeholder;
|
|
3871
|
+
return this.placeholder();
|
|
4423
3872
|
}
|
|
4424
3873
|
return String(this.value);
|
|
4425
3874
|
}
|
|
@@ -4427,23 +3876,19 @@ class InfoFieldComponent {
|
|
|
4427
3876
|
const toneClass = this.tone ? toneText(this.tone) : 'text-text-primary';
|
|
4428
3877
|
return this.mono ? `${toneClass} font-mono break-all` : toneClass;
|
|
4429
3878
|
}
|
|
4430
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4431
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3879
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InfoFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3880
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.20", type: InfoFieldComponent, isStandalone: true, selector: "fx-ui-info-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: false, isRequired: false, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-small min-w-0\">\n <span class=\"txt-field-label !mb-0\">{{ label() }}</span>\n <span class=\"txt-default\" [ngClass]=\"valueClass\">{{ displayValue }}</span>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4432
3881
|
}
|
|
4433
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3882
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InfoFieldComponent, decorators: [{
|
|
4434
3883
|
type: Component,
|
|
4435
|
-
args: [{ selector: 'fx-ui-info-field',
|
|
4436
|
-
}], propDecorators: { label: [{
|
|
4437
|
-
type: Input
|
|
4438
|
-
}], value: [{
|
|
3884
|
+
args: [{ selector: 'fx-ui-info-field', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<div class=\"flex flex-col gap-small min-w-0\">\n <span class=\"txt-field-label !mb-0\">{{ label() }}</span>\n <span class=\"txt-default\" [ngClass]=\"valueClass\">{{ displayValue }}</span>\n</div>\n" }]
|
|
3885
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{
|
|
4439
3886
|
type: Input
|
|
4440
3887
|
}], tone: [{
|
|
4441
3888
|
type: Input
|
|
4442
3889
|
}], mono: [{
|
|
4443
3890
|
type: Input
|
|
4444
|
-
}], placeholder: [{
|
|
4445
|
-
type: Input
|
|
4446
|
-
}] } });
|
|
3891
|
+
}], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
|
|
4447
3892
|
|
|
4448
3893
|
/**
|
|
4449
3894
|
* Compact total/critical/high/medium(/low) badge cluster used in table cells.
|
|
@@ -4456,7 +3901,7 @@ class SeverityBadgesComponent {
|
|
|
4456
3901
|
showZero = true;
|
|
4457
3902
|
/** Append the severity letter to counts ("3C", "5H", "2M") per the report design. */
|
|
4458
3903
|
suffixed = false;
|
|
4459
|
-
badgeClick =
|
|
3904
|
+
badgeClick = output();
|
|
4460
3905
|
static TONES = {
|
|
4461
3906
|
total: null,
|
|
4462
3907
|
critical: 'critical',
|
|
@@ -4477,21 +3922,19 @@ class SeverityBadgesComponent {
|
|
|
4477
3922
|
badgeClass(badge) {
|
|
4478
3923
|
return badge.tone ? toneBadge(badge.tone) : 'bg-bg-hover text-text-primary';
|
|
4479
3924
|
}
|
|
4480
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4481
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3925
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SeverityBadgesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3926
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SeverityBadgesComponent, isStandalone: true, selector: "fx-ui-severity-badges", inputs: { stats: "stats", showZero: "showZero", suffixed: "suffixed" }, outputs: { badgeClick: "badgeClick" }, ngImport: i0, template: "<div class=\"flex items-center gap-small\">\n @for (badge of badges; track badge.key) {\n <button\n type=\"button\"\n class=\"px-2 py-0.5 rounded-full txt-utility-caption font-medium cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"badgeClass(badge)\"\n [attr.aria-label]=\"badge.key + ': ' + badge.label\"\n (click)=\"badgeClick.emit(badge.key)\"\n >{{ badge.label }}</button>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4482
3927
|
}
|
|
4483
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3928
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SeverityBadgesComponent, decorators: [{
|
|
4484
3929
|
type: Component,
|
|
4485
|
-
args: [{ selector: 'fx-ui-severity-badges',
|
|
3930
|
+
args: [{ selector: 'fx-ui-severity-badges', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<div class=\"flex items-center gap-small\">\n @for (badge of badges; track badge.key) {\n <button\n type=\"button\"\n class=\"px-2 py-0.5 rounded-full txt-utility-caption font-medium cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"badgeClass(badge)\"\n [attr.aria-label]=\"badge.key + ': ' + badge.label\"\n (click)=\"badgeClick.emit(badge.key)\"\n >{{ badge.label }}</button>\n }\n</div>\n" }]
|
|
4486
3931
|
}], propDecorators: { stats: [{
|
|
4487
3932
|
type: Input
|
|
4488
3933
|
}], showZero: [{
|
|
4489
3934
|
type: Input
|
|
4490
3935
|
}], suffixed: [{
|
|
4491
3936
|
type: Input
|
|
4492
|
-
}], badgeClick: [{
|
|
4493
|
-
type: Output
|
|
4494
|
-
}] } });
|
|
3937
|
+
}], badgeClick: [{ type: i0.Output, args: ["badgeClick"] }] } });
|
|
4495
3938
|
|
|
4496
3939
|
let nextUid = 0;
|
|
4497
3940
|
/**
|
|
@@ -4512,23 +3955,23 @@ let nextUid = 0;
|
|
|
4512
3955
|
class MasterDetailComponent {
|
|
4513
3956
|
table;
|
|
4514
3957
|
/** Fixed list-pane width on lg+ viewports (stacked full-width below). */
|
|
4515
|
-
listWidth = '420px';
|
|
4516
|
-
maxListHeight = '640px';
|
|
4517
|
-
pageSizeOptions = [5, 10, 20, 50];
|
|
3958
|
+
listWidth = input('420px', ...(ngDevMode ? [{ debugName: "listWidth" }] : /* istanbul ignore next */ []));
|
|
3959
|
+
maxListHeight = input('640px', ...(ngDevMode ? [{ debugName: "maxListHeight" }] : /* istanbul ignore next */ []));
|
|
3960
|
+
pageSizeOptions = input([5, 10, 20, 50], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
4518
3961
|
/** Labels come in via inputs — the lib carries no i18n. */
|
|
4519
|
-
emptyMessage = 'No data';
|
|
4520
|
-
listLabel = '';
|
|
4521
|
-
skeletonCards = 3;
|
|
4522
|
-
rowTemplate;
|
|
4523
|
-
detailTemplate;
|
|
4524
|
-
paginator;
|
|
3962
|
+
emptyMessage = input('No data', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
3963
|
+
listLabel = input('', ...(ngDevMode ? [{ debugName: "listLabel" }] : /* istanbul ignore next */ []));
|
|
3964
|
+
skeletonCards = input(3, ...(ngDevMode ? [{ debugName: "skeletonCards" }] : /* istanbul ignore next */ []));
|
|
3965
|
+
rowTemplate = contentChild.required('row');
|
|
3966
|
+
detailTemplate = contentChild.required('detail');
|
|
3967
|
+
paginator = viewChild.required(MatPaginator);
|
|
4525
3968
|
uid = `fx-md-${nextUid++}`;
|
|
4526
3969
|
ngAfterViewInit() {
|
|
4527
3970
|
// The paginator lives in this view, not the host page's, so the host's
|
|
4528
3971
|
// @ViewChild(MatPaginator) never finds it. Hand it to the table so
|
|
4529
3972
|
// refresh() keeps resetting pageIndex.
|
|
4530
3973
|
if (this.table) {
|
|
4531
|
-
this.table.paginator = this.paginator;
|
|
3974
|
+
this.table.paginator = this.paginator();
|
|
4532
3975
|
}
|
|
4533
3976
|
}
|
|
4534
3977
|
isSelected(row) {
|
|
@@ -4568,36 +4011,60 @@ class MasterDetailComponent {
|
|
|
4568
4011
|
el?.focus();
|
|
4569
4012
|
el?.scrollIntoView({ block: 'nearest' });
|
|
4570
4013
|
}
|
|
4571
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4572
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
4014
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MasterDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4015
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: MasterDetailComponent, isStandalone: true, selector: "fx-ui-master-detail", inputs: { table: { classPropertyName: "table", publicName: "table", isSignal: false, isRequired: false, transformFunction: null }, listWidth: { classPropertyName: "listWidth", publicName: "listWidth", isSignal: true, isRequired: false, transformFunction: null }, maxListHeight: { classPropertyName: "maxListHeight", publicName: "maxListHeight", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: true, isRequired: false, transformFunction: null }, skeletonCards: { classPropertyName: "skeletonCards", publicName: "skeletonCards", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "rowTemplate", first: true, predicate: ["row"], descendants: true, isSignal: true }, { propertyName: "detailTemplate", first: true, predicate: ["detail"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col lg:flex-row items-start gap-xl\" [style.--fx-md-list-width]=\"listWidth()\">\n <!-- Master: list pane -->\n <div class=\"fx-md-list card-common\">\n <ng-content select=\"[mdHeader]\"></ng-content>\n <ng-content select=\"[mdFilters]\"></ng-content>\n <div\n class=\"flex flex-col gap-normal overflow-auto pr-xs\"\n [style.maxHeight]=\"maxListHeight()\"\n role=\"listbox\"\n [attr.aria-label]=\"listLabel() || null\"\n >\n @if (table.loading) {\n <fx-ui-skeleton-list [rows]=\"table.pageSize\"></fx-ui-skeleton-list>\n } @else {\n @for (row of table.dataSource.data; track table.idOf(row); let i = $index) {\n <button\n type=\"button\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [attr.aria-selected]=\"isSelected(row)\"\n [tabindex]=\"isSelected(row) ? 0 : -1\"\n (click)=\"table.selectItem(row)\"\n (keydown)=\"onKeydown($event, i)\"\n class=\"text-left rounded-lg border p-semi transition-colors\"\n [ngClass]=\"\n isSelected(row)\n ? 'border-gradient-primary-start bg-gradient-primary-start/5'\n : 'border-border-default hover:border-border-interactive bg-bg-primary'\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: row, selected: isSelected(row) }\"\n ></ng-container>\n </button>\n }\n @if (!table.dataSource.data.length) {\n <fx-ui-empty-state [message]=\"emptyMessage()\"></fx-ui-empty-state>\n }\n }\n </div>\n <!-- No (page) binding: ngAfterViewInit hands this paginator to the table,\n whose own BaseTable subscription (running after this child's hook)\n wires page events \u2014 a binding here would double-fetch every change. -->\n <mat-paginator\n class=\"mt-normal\"\n [length]=\"table.total\"\n [pageSize]=\"table.pageSize\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n ></mat-paginator>\n </div>\n\n <!-- Detail pane -->\n <div class=\"w-full lg:flex-1 min-w-0\">\n @if (table.selected) {\n @if (table.detailBusy) {\n <fx-ui-skeleton-detail [cards]=\"skeletonCards()\"></fx-ui-skeleton-detail>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"detailTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: table.detail, selected: table.selected }\"\n ></ng-container>\n }\n } @else {\n <div class=\"card-common flex items-center justify-center h-[300px]\">\n <fx-ui-empty-state [message]=\"emptyMessage()\"></fx-ui-empty-state>\n </div>\n }\n </div>\n</div>\n", styles: [".fx-md-list{width:100%}@media(min-width:1080px){.fx-md-list{width:var(--fx-md-list-width, 420px);flex-shrink:0}}\n"], dependencies: [{ kind: "component", type: SkeletonListComponent, selector: "fx-ui-skeleton-list", inputs: ["rows"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EmptyStateComponent, selector: "fx-ui-empty-state", inputs: ["message", "icon", "height"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: SkeletonDetailComponent, selector: "fx-ui-skeleton-detail", inputs: ["cards", "rows"] }] });
|
|
4573
4016
|
}
|
|
4574
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
4017
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MasterDetailComponent, decorators: [{
|
|
4575
4018
|
type: Component,
|
|
4576
|
-
args: [{ selector: 'fx-ui-master-detail',
|
|
4019
|
+
args: [{ selector: 'fx-ui-master-detail', imports: [
|
|
4020
|
+
SkeletonListComponent,
|
|
4021
|
+
NgClass,
|
|
4022
|
+
NgTemplateOutlet,
|
|
4023
|
+
EmptyStateComponent,
|
|
4024
|
+
MatPaginator,
|
|
4025
|
+
SkeletonDetailComponent,
|
|
4026
|
+
], template: "<div class=\"flex flex-col lg:flex-row items-start gap-xl\" [style.--fx-md-list-width]=\"listWidth()\">\n <!-- Master: list pane -->\n <div class=\"fx-md-list card-common\">\n <ng-content select=\"[mdHeader]\"></ng-content>\n <ng-content select=\"[mdFilters]\"></ng-content>\n <div\n class=\"flex flex-col gap-normal overflow-auto pr-xs\"\n [style.maxHeight]=\"maxListHeight()\"\n role=\"listbox\"\n [attr.aria-label]=\"listLabel() || null\"\n >\n @if (table.loading) {\n <fx-ui-skeleton-list [rows]=\"table.pageSize\"></fx-ui-skeleton-list>\n } @else {\n @for (row of table.dataSource.data; track table.idOf(row); let i = $index) {\n <button\n type=\"button\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [attr.aria-selected]=\"isSelected(row)\"\n [tabindex]=\"isSelected(row) ? 0 : -1\"\n (click)=\"table.selectItem(row)\"\n (keydown)=\"onKeydown($event, i)\"\n class=\"text-left rounded-lg border p-semi transition-colors\"\n [ngClass]=\"\n isSelected(row)\n ? 'border-gradient-primary-start bg-gradient-primary-start/5'\n : 'border-border-default hover:border-border-interactive bg-bg-primary'\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: row, selected: isSelected(row) }\"\n ></ng-container>\n </button>\n }\n @if (!table.dataSource.data.length) {\n <fx-ui-empty-state [message]=\"emptyMessage()\"></fx-ui-empty-state>\n }\n }\n </div>\n <!-- No (page) binding: ngAfterViewInit hands this paginator to the table,\n whose own BaseTable subscription (running after this child's hook)\n wires page events \u2014 a binding here would double-fetch every change. -->\n <mat-paginator\n class=\"mt-normal\"\n [length]=\"table.total\"\n [pageSize]=\"table.pageSize\"\n [pageSizeOptions]=\"pageSizeOptions()\"\n ></mat-paginator>\n </div>\n\n <!-- Detail pane -->\n <div class=\"w-full lg:flex-1 min-w-0\">\n @if (table.selected) {\n @if (table.detailBusy) {\n <fx-ui-skeleton-detail [cards]=\"skeletonCards()\"></fx-ui-skeleton-detail>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"detailTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: table.detail, selected: table.selected }\"\n ></ng-container>\n }\n } @else {\n <div class=\"card-common flex items-center justify-center h-[300px]\">\n <fx-ui-empty-state [message]=\"emptyMessage()\"></fx-ui-empty-state>\n </div>\n }\n </div>\n</div>\n", styles: [".fx-md-list{width:100%}@media(min-width:1080px){.fx-md-list{width:var(--fx-md-list-width, 420px);flex-shrink:0}}\n"] }]
|
|
4577
4027
|
}], propDecorators: { table: [{
|
|
4578
4028
|
type: Input
|
|
4579
|
-
}], listWidth: [{
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4029
|
+
}], listWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "listWidth", required: false }] }], maxListHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxListHeight", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], listLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "listLabel", required: false }] }], skeletonCards: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonCards", required: false }] }], rowTemplate: [{ type: i0.ContentChild, args: ['row', { isSignal: true }] }], detailTemplate: [{ type: i0.ContentChild, args: ['detail', { isSignal: true }] }], paginator: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatPaginator), { isSignal: true }] }] } });
|
|
4030
|
+
|
|
4031
|
+
/**
|
|
4032
|
+
* Row-action dropdown wrapper over mat-menu (behavior-layer rule, Playbook
|
|
4033
|
+
* §5.1 — apps never import @angular/material directly). Project the trigger
|
|
4034
|
+
* content; items render from [items] and come back through (select).
|
|
4035
|
+
*
|
|
4036
|
+
* <fx-ui-menu [items]="actions" (select)="onAction($event)">
|
|
4037
|
+
* <fx-ui-hero-icon icon="ellipsis-vertical" [size]="20" />
|
|
4038
|
+
* </fx-ui-menu>
|
|
4039
|
+
*/
|
|
4040
|
+
class MenuComponent {
|
|
4041
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
4042
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
4043
|
+
/** Accessible name for the trigger button. */
|
|
4044
|
+
ariaLabel = input('Open menu', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
4045
|
+
select = output();
|
|
4046
|
+
toneClass(item) {
|
|
4047
|
+
switch (item.tone) {
|
|
4048
|
+
case 'critical':
|
|
4049
|
+
case 'danger':
|
|
4050
|
+
return 'text-danger';
|
|
4051
|
+
case 'warning':
|
|
4052
|
+
return 'text-warning';
|
|
4053
|
+
case 'success':
|
|
4054
|
+
return 'text-success';
|
|
4055
|
+
case 'information':
|
|
4056
|
+
return 'text-information';
|
|
4057
|
+
default:
|
|
4058
|
+
return 'text-text-primary';
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4061
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4062
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: MenuComponent, isStandalone: true, selector: "fx-ui-menu", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"inline-flex items-center justify-center rounded-lg p-1 hover:bg-bg-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n [matMenuTriggerFor]=\"menu\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n <ng-content></ng-content>\n</button>\n\n<mat-menu #menu=\"matMenu\">\n @for (item of items(); track item.label) {\n <button\n mat-menu-item\n type=\"button\"\n [disabled]=\"item.disabled\"\n (click)=\"select.emit(item)\"\n >\n <span class=\"flex items-center gap-normal\" [class]=\"toneClass(item)\">\n @if (item.icon) {\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span>{{ item.label }}</span>\n </span>\n </button>\n }\n</mat-menu>\n", dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4063
|
+
}
|
|
4064
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MenuComponent, decorators: [{
|
|
4065
|
+
type: Component,
|
|
4066
|
+
args: [{ selector: 'fx-ui-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatMenuModule, HeroIconComponent], template: "<button\n type=\"button\"\n class=\"inline-flex items-center justify-center rounded-lg p-1 hover:bg-bg-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n [matMenuTriggerFor]=\"menu\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n>\n <ng-content></ng-content>\n</button>\n\n<mat-menu #menu=\"matMenu\">\n @for (item of items(); track item.label) {\n <button\n mat-menu-item\n type=\"button\"\n [disabled]=\"item.disabled\"\n (click)=\"select.emit(item)\"\n >\n <span class=\"flex items-center gap-normal\" [class]=\"toneClass(item)\">\n @if (item.icon) {\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span>{{ item.label }}</span>\n </span>\n </button>\n }\n</mat-menu>\n" }]
|
|
4067
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], select: [{ type: i0.Output, args: ["select"] }] } });
|
|
4601
4068
|
|
|
4602
4069
|
const FX_COMPONENTS = [
|
|
4603
4070
|
InputComponent,
|
|
@@ -4616,12 +4083,9 @@ const FX_COMPONENTS = [
|
|
|
4616
4083
|
ToastComponent,
|
|
4617
4084
|
ToastContainerComponent,
|
|
4618
4085
|
TagComponent,
|
|
4619
|
-
ChartComponent,
|
|
4620
4086
|
SliderComponent,
|
|
4621
4087
|
SwitchComponent,
|
|
4622
|
-
RichTextAreaComponent,
|
|
4623
4088
|
SkeletonTableLoadingComponent,
|
|
4624
|
-
FlowConnection,
|
|
4625
4089
|
CircleProgressBar,
|
|
4626
4090
|
TreeDiagram,
|
|
4627
4091
|
TableCell,
|
|
@@ -4637,134 +4101,61 @@ const FX_COMPONENTS = [
|
|
|
4637
4101
|
InfoFieldComponent,
|
|
4638
4102
|
SeverityBadgesComponent,
|
|
4639
4103
|
MasterDetailComponent,
|
|
4104
|
+
MenuComponent,
|
|
4640
4105
|
];
|
|
4641
4106
|
|
|
4642
|
-
class ConfirmationDialogComponent {
|
|
4643
|
-
ref;
|
|
4644
|
-
bindings;
|
|
4645
|
-
loading = false;
|
|
4646
|
-
title = '';
|
|
4647
|
-
message = '';
|
|
4648
|
-
cancelLabel = 'Cancel';
|
|
4649
|
-
confirmLabel = 'Submit';
|
|
4650
|
-
constructor(ref, bindings) {
|
|
4651
|
-
this.ref = ref;
|
|
4652
|
-
this.bindings = bindings;
|
|
4653
|
-
this.title = _.get(bindings, 'title');
|
|
4654
|
-
this.message = _.get(bindings, 'message');
|
|
4655
|
-
this.cancelLabel = _.get(bindings, 'cancelLabel');
|
|
4656
|
-
this.confirmLabel = _.get(bindings, 'confirmLabel');
|
|
4657
|
-
}
|
|
4658
|
-
async accept() {
|
|
4659
|
-
this.loading = true;
|
|
4660
|
-
if (_.get(this.bindings, 'callback')) {
|
|
4661
|
-
await this.bindings.callback();
|
|
4662
|
-
this.loading = false;
|
|
4663
|
-
}
|
|
4664
|
-
this.ref.close(true);
|
|
4665
|
-
}
|
|
4666
|
-
cancel() {
|
|
4667
|
-
this.ref.close(false);
|
|
4668
|
-
}
|
|
4669
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ConfirmationDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
4670
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: ConfirmationDialogComponent, isStandalone: false, selector: "fx-ui-confirmation-dialog", ngImport: i0, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 mat-dialog-title class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: ButtonComponent, selector: "fx-ui-button", inputs: ["label", "disabled", "buttonVariant", "icon", "class", "loading", "type", "ariaLabel"], outputs: ["clicked"] }] });
|
|
4671
|
-
}
|
|
4672
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
|
|
4673
|
-
type: Component,
|
|
4674
|
-
args: [{ selector: 'fx-ui-confirmation-dialog', standalone: false, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 mat-dialog-title class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n" }]
|
|
4675
|
-
}], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
|
|
4676
|
-
type: Inject,
|
|
4677
|
-
args: [MAT_DIALOG_DATA]
|
|
4678
|
-
}] }] });
|
|
4679
|
-
|
|
4680
4107
|
const DIALOGS_COMPONENT = [
|
|
4681
4108
|
ConfirmationDialogComponent
|
|
4682
4109
|
];
|
|
4683
4110
|
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4111
|
+
/**
|
|
4112
|
+
* Compatibility barrel over the (now standalone) core components.
|
|
4113
|
+
*
|
|
4114
|
+
* Deliberately NOT re-exported anymore: Angular Material —
|
|
4115
|
+
* Material is a behavior layer that stays an
|
|
4116
|
+
* implementation detail of this lib (Playbook §5.1); each standalone
|
|
4117
|
+
* component imports what it needs itself. Apps consume fx-ui-* only.
|
|
4118
|
+
*
|
|
4119
|
+
* Heavy components live in secondary entry points and are not part of this
|
|
4120
|
+
* barrel: @foxeltech/angular-ui/chart, /flow, /rich-text.
|
|
4121
|
+
*/
|
|
4693
4122
|
class UiModule {
|
|
4694
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
4695
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
4696
|
-
FormsModule,
|
|
4123
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
4124
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: UiModule, imports: [FormsModule,
|
|
4697
4125
|
ReactiveFormsModule,
|
|
4698
4126
|
RouterModule,
|
|
4699
|
-
OwlDateTimeModule,
|
|
4700
|
-
OwlNativeDateTimeModule,
|
|
4701
|
-
OwlMomentDateTimeModule,
|
|
4702
4127
|
HasPermissionDirective,
|
|
4703
|
-
TrimOnBlurDirective,
|
|
4704
|
-
NgHeroiconsModule, i39.VflowComponent, i39.HandleComponent, i39.ResizableComponent, i39.SelectableDirective, i39.MiniMapComponent, i39.NodeToolbarComponent, i39.CustomTemplateEdgeComponent, i39.DragHandleDirective, i39.ConnectionControllerDirective, i39.NodeHtmlTemplateDirective, i39.NodeSvgTemplateDirective, i39.GroupNodeTemplateDirective, i39.EdgeLabelHtmlTemplateDirective, i39.EdgeTemplateDirective, i39.ConnectionTemplateDirective, i39.HandleTemplateDirective, i1$5.NgxEchartsModule, i3.MatSelectModule, i42.MatRadioModule, i43.MatButtonModule, i44.MatIconModule, i45.MatPaginatorModule, i46.MatTableModule, i47.MatSnackBarModule, i1$2.MatDialogModule, i49.MatCheckboxModule, i50.MatCardModule, i51.MatDatepickerModule, i52.MatTimepickerModule, i53.MatBadgeModule, i54.MatExpansionModule, i55.MatFormFieldModule, i56.MatMenuModule, i57.MatTooltipModule, i2$3.DragDropModule], exports: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, RichTextAreaComponent, SkeletonTableLoadingComponent, FlowConnection, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, MasterDetailComponent, ConfirmationDialogComponent,
|
|
4705
|
-
// Module
|
|
4706
|
-
FormsModule,
|
|
4128
|
+
TrimOnBlurDirective, InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, SliderComponent, SwitchComponent, SkeletonTableLoadingComponent, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, MasterDetailComponent, MenuComponent, ConfirmationDialogComponent], exports: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, SliderComponent, SwitchComponent, SkeletonTableLoadingComponent, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, MasterDetailComponent, MenuComponent, ConfirmationDialogComponent, FormsModule,
|
|
4707
4129
|
ReactiveFormsModule,
|
|
4708
4130
|
RouterModule,
|
|
4709
|
-
OwlDateTimeModule,
|
|
4710
|
-
OwlNativeDateTimeModule,
|
|
4711
4131
|
HasPermissionDirective,
|
|
4712
|
-
|
|
4713
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
4714
|
-
importProvidersFrom(NgHeroiconsModule.forRoot()),
|
|
4715
|
-
{ provide: OWL_DATE_TIME_FORMATS, useValue: MY_MOMENT_FORMATS },
|
|
4716
|
-
], imports: [CommonModule,
|
|
4717
|
-
FormsModule,
|
|
4132
|
+
TrimOnBlurDirective] });
|
|
4133
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiModule, imports: [FormsModule,
|
|
4718
4134
|
ReactiveFormsModule,
|
|
4719
|
-
RouterModule,
|
|
4720
|
-
OwlDateTimeModule,
|
|
4721
|
-
OwlNativeDateTimeModule,
|
|
4722
|
-
OwlMomentDateTimeModule,
|
|
4723
|
-
NgHeroiconsModule, i39.VflowComponent, i39.HandleComponent, i39.ResizableComponent, i39.MiniMapComponent, i39.NodeToolbarComponent, i39.CustomTemplateEdgeComponent, NgxEchartsModule.forRoot({ echarts: () => import('echarts') }), MATERIAL_MODULE,
|
|
4724
|
-
// Module
|
|
4725
|
-
FormsModule,
|
|
4135
|
+
RouterModule, SelectComponent, DatetimePicker, MasterDetailComponent, MenuComponent, FormsModule,
|
|
4726
4136
|
ReactiveFormsModule,
|
|
4727
|
-
RouterModule
|
|
4728
|
-
OwlDateTimeModule,
|
|
4729
|
-
OwlNativeDateTimeModule,
|
|
4730
|
-
NgHeroiconsModule, i3.MatSelectModule, i42.MatRadioModule, i43.MatButtonModule, i44.MatIconModule, i45.MatPaginatorModule, i46.MatTableModule, i47.MatSnackBarModule, i1$2.MatDialogModule, i49.MatCheckboxModule, i50.MatCardModule, i51.MatDatepickerModule, i52.MatTimepickerModule, i53.MatBadgeModule, i54.MatExpansionModule, i55.MatFormFieldModule, i56.MatMenuModule, i57.MatTooltipModule, i2$3.DragDropModule] });
|
|
4137
|
+
RouterModule] });
|
|
4731
4138
|
}
|
|
4732
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
4139
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiModule, decorators: [{
|
|
4733
4140
|
type: NgModule,
|
|
4734
4141
|
args: [{
|
|
4735
|
-
declarations: [...FX_COMPONENTS, ...DIALOGS_COMPONENT],
|
|
4736
4142
|
imports: [
|
|
4737
|
-
CommonModule,
|
|
4738
4143
|
FormsModule,
|
|
4739
4144
|
ReactiveFormsModule,
|
|
4740
4145
|
RouterModule,
|
|
4741
|
-
OwlDateTimeModule,
|
|
4742
|
-
OwlNativeDateTimeModule,
|
|
4743
|
-
OwlMomentDateTimeModule,
|
|
4744
4146
|
HasPermissionDirective,
|
|
4745
4147
|
TrimOnBlurDirective,
|
|
4746
|
-
|
|
4747
|
-
...
|
|
4748
|
-
NgxEchartsModule.forRoot({ echarts: () => import('echarts') }),
|
|
4749
|
-
...MATERIAL_MODULE,
|
|
4148
|
+
...FX_COMPONENTS,
|
|
4149
|
+
...DIALOGS_COMPONENT,
|
|
4750
4150
|
],
|
|
4751
4151
|
exports: [
|
|
4752
|
-
// Component
|
|
4753
4152
|
...FX_COMPONENTS,
|
|
4754
4153
|
...DIALOGS_COMPONENT,
|
|
4755
|
-
// Module
|
|
4756
4154
|
FormsModule,
|
|
4757
4155
|
ReactiveFormsModule,
|
|
4758
4156
|
RouterModule,
|
|
4759
|
-
OwlDateTimeModule,
|
|
4760
|
-
OwlNativeDateTimeModule,
|
|
4761
4157
|
HasPermissionDirective,
|
|
4762
|
-
|
|
4763
|
-
...MATERIAL_MODULE,
|
|
4764
|
-
],
|
|
4765
|
-
providers: [
|
|
4766
|
-
importProvidersFrom(NgHeroiconsModule.forRoot()),
|
|
4767
|
-
{ provide: OWL_DATE_TIME_FORMATS, useValue: MY_MOMENT_FORMATS },
|
|
4158
|
+
TrimOnBlurDirective,
|
|
4768
4159
|
],
|
|
4769
4160
|
}]
|
|
4770
4161
|
}] });
|
|
@@ -4777,5 +4168,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4777
4168
|
* Generated bundle index. Do not edit.
|
|
4778
4169
|
*/
|
|
4779
4170
|
|
|
4780
|
-
export { AuthInterceptor, AuthStateService, BaseComponent, BaseDialogComponent, BaseMasterDetailComponent, BaseResolver, BaseTableComponent, BreadcrumbService, ButtonComponent,
|
|
4171
|
+
export { AuthInterceptor, AuthStateService, BaseComponent, BaseDialogComponent, BaseMasterDetailComponent, BaseResolver, BaseTableComponent, BreadcrumbService, ButtonComponent, CheckboxComponent, CircleProgressBar, ConfirmationDialogComponent, DatetimePicker, DndUploadComponent, DrawerComponent, EmptyStateComponent, FX_ICON_SPRITE_URL, FilterChipsComponent, FxComponent, FxDialogService, FxLoadingService, FxStorageService, FxToastrService, FxUtils, FxValidators, HasPermissionDirective, HeroIconComponent, HttpLoaderFactory, HttpWrapper, InfoFieldComponent, InputComponent, KanbanBoardComponent, LoadingPanel, MasterDetailComponent, MenuComponent, MeterComponent, NotificationService, PermissionGuard, PermissionService, RadioButtonComponent, RadioButtonToggleComponent, RealtimeTableSync, SearchBarComponent, SectionCardComponent, SelectComponent, SeverityBadgesComponent, SkeletonDetailComponent, SkeletonListComponent, SkeletonTableLoadingComponent, SliderComponent, StatCardsComponent, SwitchComponent, TabComponent, TabGroupComponent, TableCell, TagComponent, ThemeService, ToastComponent, ToastContainerComponent, TranslationModule, TranslationService, TreeDiagram, TrimOnBlurDirective, UiModule, countTone, createApi, fxListResolver, scoreTone, severityTone, toneBadge, toneBg, toneColor, toneText };
|
|
4781
4172
|
//# sourceMappingURL=foxeltech-angular-ui.mjs.map
|