ngx-dev-toolbar 3.0.3 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/components/icons/edit-icon.component.d.ts +6 -0
- package/components/icons/icon.models.d.ts +1 -1
- package/components/select/select.component.d.ts +3 -1
- package/components/step-view/step-view.component.d.ts +14 -0
- package/components/step-view/step-view.directive.d.ts +9 -0
- package/fesm2022/ngx-dev-toolbar.mjs +1292 -270
- package/fesm2022/ngx-dev-toolbar.mjs.map +1 -1
- package/index.d.ts +8 -62
- package/package.json +1 -1
- package/tools/feature-flags-tool/feature-flags-tool.component.d.ts +1 -0
- package/tools/presets-tool/presets-internal.service.d.ts +13 -1
- package/tools/presets-tool/presets-tool.component.d.ts +48 -11
- package/tools/presets-tool/presets.models.d.ts +12 -0
- package/tools/presets-tool/presets.service.d.ts +21 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal, computed, Injectable, inject, ChangeDetectionStrategy, Component, input, model, ElementRef, output, viewChild, contentChild, effect, DestroyRef, ViewEncapsulation, EnvironmentInjector, createComponent } from '@angular/core';
|
|
2
|
+
import { InjectionToken, signal, computed, Injectable, inject, ChangeDetectionStrategy, Component, input, model, ElementRef, output, viewChild, contentChild, effect, DestroyRef, ViewEncapsulation, EnvironmentInjector, createComponent, TemplateRef, Directive, contentChildren } from '@angular/core';
|
|
3
3
|
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { BehaviorSubject, combineLatest, map, firstValueFrom, fromEvent } from 'rxjs';
|
|
5
|
-
import { trigger, state,
|
|
6
|
-
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
5
|
+
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
6
|
+
import { CommonModule, DOCUMENT, NgTemplateOutlet } from '@angular/common';
|
|
7
7
|
import { filter, throttleTime } from 'rxjs/operators';
|
|
8
8
|
import * as i1 from '@angular/forms';
|
|
9
9
|
import { FormsModule } from '@angular/forms';
|
|
@@ -1615,6 +1615,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
1615
1615
|
}]
|
|
1616
1616
|
}] });
|
|
1617
1617
|
|
|
1618
|
+
class EditIconComponent {
|
|
1619
|
+
constructor() {
|
|
1620
|
+
this.fill = input('#FFFF');
|
|
1621
|
+
}
|
|
1622
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: EditIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1623
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.7", type: EditIconComponent, isStandalone: true, selector: "ngt-edit-icon", inputs: { fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1624
|
+
<svg
|
|
1625
|
+
[attr.fill]="fill()"
|
|
1626
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1627
|
+
width="24"
|
|
1628
|
+
height="24"
|
|
1629
|
+
viewBox="0 0 256 256"
|
|
1630
|
+
>
|
|
1631
|
+
<path
|
|
1632
|
+
d="M221.66,90.34,192,120,136,64l29.66-29.66a8,8,0,0,1,11.31,0L221.66,79A8,8,0,0,1,221.66,90.34Z"
|
|
1633
|
+
opacity="0.2"
|
|
1634
|
+
></path>
|
|
1635
|
+
<path
|
|
1636
|
+
d="M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z"
|
|
1637
|
+
></path>
|
|
1638
|
+
</svg>
|
|
1639
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1640
|
+
}
|
|
1641
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: EditIconComponent, decorators: [{
|
|
1642
|
+
type: Component,
|
|
1643
|
+
args: [{
|
|
1644
|
+
selector: 'ngt-edit-icon',
|
|
1645
|
+
standalone: true,
|
|
1646
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1647
|
+
template: `
|
|
1648
|
+
<svg
|
|
1649
|
+
[attr.fill]="fill()"
|
|
1650
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1651
|
+
width="24"
|
|
1652
|
+
height="24"
|
|
1653
|
+
viewBox="0 0 256 256"
|
|
1654
|
+
>
|
|
1655
|
+
<path
|
|
1656
|
+
d="M221.66,90.34,192,120,136,64l29.66-29.66a8,8,0,0,1,11.31,0L221.66,79A8,8,0,0,1,221.66,90.34Z"
|
|
1657
|
+
opacity="0.2"
|
|
1658
|
+
></path>
|
|
1659
|
+
<path
|
|
1660
|
+
d="M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z"
|
|
1661
|
+
></path>
|
|
1662
|
+
</svg>
|
|
1663
|
+
`,
|
|
1664
|
+
}]
|
|
1665
|
+
}] });
|
|
1666
|
+
|
|
1618
1667
|
class ExportIconComponent {
|
|
1619
1668
|
constructor() {
|
|
1620
1669
|
this.fill = input('#FFFF');
|
|
@@ -2604,6 +2653,8 @@ class ToolbarIconComponent {
|
|
|
2604
2653
|
<ngt-database-icon [fill]="fill()" />
|
|
2605
2654
|
} @case ('docs') {
|
|
2606
2655
|
<ngt-docs-icon [fill]="fill()" />
|
|
2656
|
+
} @case ('edit') {
|
|
2657
|
+
<ngt-edit-icon [fill]="fill()" />
|
|
2607
2658
|
} @case ('export') {
|
|
2608
2659
|
<ngt-export-icon [fill]="fill()" />
|
|
2609
2660
|
} @case ('filter') {
|
|
@@ -2649,7 +2700,7 @@ class ToolbarIconComponent {
|
|
|
2649
2700
|
} @case ('trash') {
|
|
2650
2701
|
<ngt-trash-icon [fill]="fill()" />
|
|
2651
2702
|
} }
|
|
2652
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AngularIconComponent, selector: "ngt-angular-icon" }, { kind: "component", type: BoltIconComponent, selector: "ngt-bolt-icon", inputs: ["fill"] }, { kind: "component", type: BugIconComponent, selector: "ngt-bug-icon", inputs: ["fill"] }, { kind: "component", type: CodeIconComponent, selector: "ngt-code-icon", inputs: ["fill"] }, { kind: "component", type: DatabaseIconComponent, selector: "ngt-database-icon", inputs: ["fill"] }, { kind: "component", type: DocsIconComponent, selector: "ngt-docs-icon", inputs: ["fill"] }, { kind: "component", type: DiscordIconComponent, selector: "ngt-discord-icon", inputs: ["fill"] }, { kind: "component", type: ExportIconComponent, selector: "ngt-export-icon", inputs: ["fill"] }, { kind: "component", type: FilterIconComponent, selector: "ngt-filter-icon", inputs: ["fill"] }, { kind: "component", type: GaugeIconComponent, selector: "ngt-gauge-icon", inputs: ["fill"] }, { kind: "component", type: GearIconComponent, selector: "ngt-gear-icon", inputs: ["fill"] }, { kind: "component", type: GitBranchIconComponent, selector: "ngt-git-branch-icon", inputs: ["fill"] }, { kind: "component", type: ImportIconComponent, selector: "ngt-import-icon", inputs: ["fill"] }, { kind: "component", type: LayoutIconComponent, selector: "ngt-layout-icon", inputs: ["fill"] }, { kind: "component", type: LightbulbIconComponent, selector: "ngt-lightbulb-icon", inputs: ["fill"] }, { kind: "component", type: LightingIconComponent, selector: "ngt-lighting-icon", inputs: ["fill"] }, { kind: "component", type: LockIconComponent, selector: "ngt-lock-icon", inputs: ["fill"] }, { kind: "component", type: NetworkIconComponent, selector: "ngt-network-icon", inputs: ["fill"] }, { kind: "component", type: PuzzleIconComponent, selector: "ngt-puzzle-icon", inputs: ["fill"] }, { kind: "component", type: RefreshIconComponent, selector: "ngt-refresh-icon", inputs: ["fill"] }, { kind: "component", type: StarIconComponent, selector: "ngt-star-icon", inputs: ["fill"] }, { kind: "component", type: TerminalIconComponent, selector: "ngt-terminal-icon", inputs: ["fill"] }, { kind: "component", type: ToggleLeftIconComponent, selector: "ngt-toggle-left-icon", inputs: ["fill"] }, { kind: "component", type: UsersIconComponent, selector: "ngt-users-icon", inputs: ["fill"] }, { kind: "component", type: SunIconComponent, selector: "ngt-sun-icon", inputs: ["fill"] }, { kind: "component", type: MoonIconComponent, selector: "ngt-moon-icon", inputs: ["fill"] }, { kind: "component", type: TranslateIconComponent, selector: "ngt-translate-icon", inputs: ["fill"] }, { kind: "component", type: TrashIconComponent, selector: "ngt-trash-icon", inputs: ["fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2703
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AngularIconComponent, selector: "ngt-angular-icon" }, { kind: "component", type: BoltIconComponent, selector: "ngt-bolt-icon", inputs: ["fill"] }, { kind: "component", type: BugIconComponent, selector: "ngt-bug-icon", inputs: ["fill"] }, { kind: "component", type: CodeIconComponent, selector: "ngt-code-icon", inputs: ["fill"] }, { kind: "component", type: DatabaseIconComponent, selector: "ngt-database-icon", inputs: ["fill"] }, { kind: "component", type: DocsIconComponent, selector: "ngt-docs-icon", inputs: ["fill"] }, { kind: "component", type: DiscordIconComponent, selector: "ngt-discord-icon", inputs: ["fill"] }, { kind: "component", type: EditIconComponent, selector: "ngt-edit-icon", inputs: ["fill"] }, { kind: "component", type: ExportIconComponent, selector: "ngt-export-icon", inputs: ["fill"] }, { kind: "component", type: FilterIconComponent, selector: "ngt-filter-icon", inputs: ["fill"] }, { kind: "component", type: GaugeIconComponent, selector: "ngt-gauge-icon", inputs: ["fill"] }, { kind: "component", type: GearIconComponent, selector: "ngt-gear-icon", inputs: ["fill"] }, { kind: "component", type: GitBranchIconComponent, selector: "ngt-git-branch-icon", inputs: ["fill"] }, { kind: "component", type: ImportIconComponent, selector: "ngt-import-icon", inputs: ["fill"] }, { kind: "component", type: LayoutIconComponent, selector: "ngt-layout-icon", inputs: ["fill"] }, { kind: "component", type: LightbulbIconComponent, selector: "ngt-lightbulb-icon", inputs: ["fill"] }, { kind: "component", type: LightingIconComponent, selector: "ngt-lighting-icon", inputs: ["fill"] }, { kind: "component", type: LockIconComponent, selector: "ngt-lock-icon", inputs: ["fill"] }, { kind: "component", type: NetworkIconComponent, selector: "ngt-network-icon", inputs: ["fill"] }, { kind: "component", type: PuzzleIconComponent, selector: "ngt-puzzle-icon", inputs: ["fill"] }, { kind: "component", type: RefreshIconComponent, selector: "ngt-refresh-icon", inputs: ["fill"] }, { kind: "component", type: StarIconComponent, selector: "ngt-star-icon", inputs: ["fill"] }, { kind: "component", type: TerminalIconComponent, selector: "ngt-terminal-icon", inputs: ["fill"] }, { kind: "component", type: ToggleLeftIconComponent, selector: "ngt-toggle-left-icon", inputs: ["fill"] }, { kind: "component", type: UsersIconComponent, selector: "ngt-users-icon", inputs: ["fill"] }, { kind: "component", type: SunIconComponent, selector: "ngt-sun-icon", inputs: ["fill"] }, { kind: "component", type: MoonIconComponent, selector: "ngt-moon-icon", inputs: ["fill"] }, { kind: "component", type: TranslateIconComponent, selector: "ngt-translate-icon", inputs: ["fill"] }, { kind: "component", type: TrashIconComponent, selector: "ngt-trash-icon", inputs: ["fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2653
2704
|
}
|
|
2654
2705
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarIconComponent, decorators: [{
|
|
2655
2706
|
type: Component,
|
|
@@ -2664,6 +2715,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2664
2715
|
DatabaseIconComponent,
|
|
2665
2716
|
DocsIconComponent,
|
|
2666
2717
|
DiscordIconComponent,
|
|
2718
|
+
EditIconComponent,
|
|
2667
2719
|
ExportIconComponent,
|
|
2668
2720
|
FilterIconComponent,
|
|
2669
2721
|
GaugeIconComponent,
|
|
@@ -2700,6 +2752,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
2700
2752
|
<ngt-database-icon [fill]="fill()" />
|
|
2701
2753
|
} @case ('docs') {
|
|
2702
2754
|
<ngt-docs-icon [fill]="fill()" />
|
|
2755
|
+
} @case ('edit') {
|
|
2756
|
+
<ngt-edit-icon [fill]="fill()" />
|
|
2703
2757
|
} @case ('export') {
|
|
2704
2758
|
<ngt-export-icon [fill]="fill()" />
|
|
2705
2759
|
} @case ('filter') {
|
|
@@ -2991,14 +3045,19 @@ class ToolbarSelectComponent {
|
|
|
2991
3045
|
this.ariaLabel = input('');
|
|
2992
3046
|
this.label = input('');
|
|
2993
3047
|
this.size = input('medium');
|
|
3048
|
+
this.placeholder = input('Select an option');
|
|
2994
3049
|
this.theme = computed(() => this.devToolbarStateService.theme());
|
|
2995
3050
|
this.selectMenuId = `select-menu-${Math.random()
|
|
2996
3051
|
.toString(36)
|
|
2997
3052
|
.slice(2, 11)}`;
|
|
2998
3053
|
this.isOpen = signal(false);
|
|
3054
|
+
this.isPlaceholder = computed(() => {
|
|
3055
|
+
const options = this.options();
|
|
3056
|
+
return !!options?.length && !options.some((opt) => opt.value === this.value());
|
|
3057
|
+
});
|
|
2999
3058
|
this.selectedLabel = computed(() => {
|
|
3000
3059
|
const selected = this.options()?.find((opt) => opt.value === this.value());
|
|
3001
|
-
return selected?.label ??
|
|
3060
|
+
return selected?.label ?? this.placeholder();
|
|
3002
3061
|
});
|
|
3003
3062
|
this.positions = [
|
|
3004
3063
|
{
|
|
@@ -3028,11 +3087,12 @@ class ToolbarSelectComponent {
|
|
|
3028
3087
|
this.close();
|
|
3029
3088
|
}
|
|
3030
3089
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3031
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarSelectComponent, isStandalone: true, selector: "ngt-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
|
|
3090
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarSelectComponent, isStandalone: true, selector: "ngt-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
|
|
3032
3091
|
<div
|
|
3033
3092
|
class="ngt-select"
|
|
3034
3093
|
[class.small]="size() === 'small'"
|
|
3035
3094
|
[class.open]="isOpen()"
|
|
3095
|
+
[class.placeholder]="isPlaceholder()"
|
|
3036
3096
|
[attr.aria-label]="ariaLabel()"
|
|
3037
3097
|
[attr.aria-expanded]="isOpen()"
|
|
3038
3098
|
[attr.aria-controls]="selectMenuId"
|
|
@@ -3065,20 +3125,20 @@ class ToolbarSelectComponent {
|
|
|
3065
3125
|
[attr.data-theme]="theme()"
|
|
3066
3126
|
>
|
|
3067
3127
|
@for (option of options(); track option.value) {
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3128
|
+
<button
|
|
3129
|
+
class="select-menu-item"
|
|
3130
|
+
[class.selected]="option.value === value()"
|
|
3131
|
+
[attr.aria-selected]="option.value === value()"
|
|
3132
|
+
cdkMenuItem
|
|
3133
|
+
type="button"
|
|
3134
|
+
(click)="selectOption(option)"
|
|
3135
|
+
>
|
|
3136
|
+
{{ option.label }}
|
|
3137
|
+
</button>
|
|
3078
3138
|
}
|
|
3079
3139
|
</div>
|
|
3080
3140
|
</ng-template>
|
|
3081
|
-
`, isInline: true, styles: [":host{--ngt-border-radius-small: 4px;--ngt-border-radius-medium: 8px;--ngt-border-radius-large: 12px;--ngt-transition-default: all .2s ease-out;--ngt-transition-smooth: all .2s ease-in-out;--ngt-bg-primary: rgb(255, 255, 255);--ngt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ngt-text-primary: rgb(17, 24, 39);--ngt-text-secondary: rgb(55, 65, 81);--ngt-text-muted: rgb(107, 114, 128);--ngt-border-primary: #e5e7eb;--ngt-border-subtle: rgba(17, 24, 39, .1);--ngt-hover-bg: rgba(17, 24, 39, .05);--ngt-hover-danger: rgb(239, 68, 68);--ngt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ngt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ngt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ngt-spacing-xs: 4px;--ngt-spacing-sm: 6px;--ngt-spacing-md: 12px;--ngt-spacing-lg: 16px;--ngt-window-padding: 16px;--ngt-font-size-xxs: .65rem;--ngt-font-size-xs: .75rem;--ngt-font-size-sm: .875rem;--ngt-font-size-md: 1rem;--ngt-font-size-lg: 1.25rem;--ngt-font-size-xl: 2rem;--ngt-background-secondary: var(--ngt-bg-primary);--ngt-background-hover: var(--ngt-hover-bg);--ngt-primary: #df30d4;--ngt-primary-rgb: 223, 48, 212;--ngt-text-on-primary: rgb(255, 255, 255);--ngt-border-color: var(--ngt-border-primary);--ngt-note-background: rgb(219, 234, 254);--ngt-note-border: rgba(37, 99, 235, .2);--ngt-warning-background: rgb(254, 249, 195);--ngt-warning-border: rgba(202, 138, 4, .2);--ngt-error-background: rgb(254, 226, 226);--ngt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ngt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border:1px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-small);background-color:var(--ngt-bg-primary);color:var(--ngt-text-primary);font-size:var(--ngt-font-size-sm);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngt-transition-default);outline:none;min-height:36px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ngt-select:hover{background-color:var(--ngt-hover-bg);border-color:var(--ngt-primary);box-shadow:0 1px 3px #0000001a}.ngt-select:focus-visible{outline:none;border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.small{padding:var(--ngt-spacing-xs) var(--ngt-spacing-sm);font-size:var(--ngt-font-size-sm);height:24px}.ngt-select.open{border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.open .select__arrow{transform:rotate(180deg)}.ngt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:var(--ngt-spacing-sm);min-width:0;display:flex;align-items:center}.ngt-select__arrow{width:16px;height:16px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ngt-select-menu{display:inline-flex;flex-direction:column;min-width:180px;background-color:var(--ngt-bg-primary);padding:var(--ngt-spacing-sm) 0;border:2px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-large);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ngt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ngt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ngt-select-menu::-webkit-scrollbar-track{background:transparent}.ngt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ngt-border-primary);border-radius:4px;border:2px solid var(--ngt-bg-primary)}.ngt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ngt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ngt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md) var(--ngt-spacing-sm) var(--ngt-spacing-lg);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ngt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.5;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ngt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ngt-primary);background-color:rgba(var(--ngt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ngt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:8px;width:3px;height:calc(100% - 16px);background-color:var(--ngt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f}.select-menu-item:first-child{margin-top:var(--ngt-spacing-xs)}.select-menu-item:last-child{margin-bottom:var(--ngt-spacing-xs)}.select-overlay{backdrop-filter:blur(8px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: CdkMenuModule }, { kind: "directive", type: i2.CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }, { kind: "directive", type: i2.CdkMenuItem, selector: "[cdkMenuItem]", inputs: ["cdkMenuItemDisabled", "cdkMenuitemTypeaheadLabel"], outputs: ["cdkMenuItemTriggered"], exportAs: ["cdkMenuItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3141
|
+
`, isInline: true, styles: [":host{--ngt-border-radius-small: 4px;--ngt-border-radius-medium: 8px;--ngt-border-radius-large: 12px;--ngt-transition-default: all .2s ease-out;--ngt-transition-smooth: all .2s ease-in-out;--ngt-bg-primary: rgb(255, 255, 255);--ngt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ngt-text-primary: rgb(17, 24, 39);--ngt-text-secondary: rgb(55, 65, 81);--ngt-text-muted: rgb(107, 114, 128);--ngt-border-primary: #e5e7eb;--ngt-border-subtle: rgba(17, 24, 39, .1);--ngt-hover-bg: rgba(17, 24, 39, .05);--ngt-hover-danger: rgb(239, 68, 68);--ngt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ngt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ngt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ngt-spacing-xs: 4px;--ngt-spacing-sm: 6px;--ngt-spacing-md: 12px;--ngt-spacing-lg: 16px;--ngt-window-padding: 16px;--ngt-font-size-xxs: .65rem;--ngt-font-size-xs: .75rem;--ngt-font-size-sm: .875rem;--ngt-font-size-md: 1rem;--ngt-font-size-lg: 1.25rem;--ngt-font-size-xl: 2rem;--ngt-background-secondary: var(--ngt-bg-primary);--ngt-background-hover: var(--ngt-hover-bg);--ngt-primary: #df30d4;--ngt-primary-rgb: 223, 48, 212;--ngt-text-on-primary: rgb(255, 255, 255);--ngt-border-color: var(--ngt-border-primary);--ngt-note-background: rgb(219, 234, 254);--ngt-note-border: rgba(37, 99, 235, .2);--ngt-warning-background: rgb(254, 249, 195);--ngt-warning-border: rgba(202, 138, 4, .2);--ngt-error-background: rgb(254, 226, 226);--ngt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ngt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border:1px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-small);background-color:var(--ngt-bg-primary);color:var(--ngt-text-primary);font-size:var(--ngt-font-size-sm);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngt-transition-default);outline:none;min-height:36px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ngt-select:hover{background-color:var(--ngt-hover-bg);border-color:var(--ngt-primary);box-shadow:0 1px 3px #0000001a}.ngt-select:focus-visible{outline:none;border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.small{padding:var(--ngt-spacing-xs) var(--ngt-spacing-sm);font-size:var(--ngt-font-size-sm);height:24px}.ngt-select.open{border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.open .select__arrow{transform:rotate(180deg)}.ngt-select.placeholder{color:var(--ngt-text-muted)}.ngt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:var(--ngt-spacing-sm);min-width:0;display:flex;align-items:center}.ngt-select__arrow{width:16px;height:16px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ngt-select-menu{display:inline-flex;flex-direction:column;min-width:180px;background-color:var(--ngt-bg-primary);padding:var(--ngt-spacing-sm) 0;border:2px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-large);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ngt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ngt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ngt-select-menu::-webkit-scrollbar-track{background:transparent}.ngt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ngt-border-primary);border-radius:4px;border:2px solid var(--ngt-bg-primary)}.ngt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ngt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ngt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md) var(--ngt-spacing-sm) var(--ngt-spacing-lg);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ngt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.5;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ngt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ngt-primary);background-color:rgba(var(--ngt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ngt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:8px;width:3px;height:calc(100% - 16px);background-color:var(--ngt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f}.select-menu-item:first-child{margin-top:var(--ngt-spacing-xs)}.select-menu-item:last-child{margin-bottom:var(--ngt-spacing-xs)}.select-overlay{backdrop-filter:blur(8px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: CdkMenuModule }, { kind: "directive", type: i2.CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }, { kind: "directive", type: i2.CdkMenuItem, selector: "[cdkMenuItem]", inputs: ["cdkMenuItemDisabled", "cdkMenuitemTypeaheadLabel"], outputs: ["cdkMenuItemTriggered"], exportAs: ["cdkMenuItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3082
3142
|
}
|
|
3083
3143
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarSelectComponent, decorators: [{
|
|
3084
3144
|
type: Component,
|
|
@@ -3087,6 +3147,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
3087
3147
|
class="ngt-select"
|
|
3088
3148
|
[class.small]="size() === 'small'"
|
|
3089
3149
|
[class.open]="isOpen()"
|
|
3150
|
+
[class.placeholder]="isPlaceholder()"
|
|
3090
3151
|
[attr.aria-label]="ariaLabel()"
|
|
3091
3152
|
[attr.aria-expanded]="isOpen()"
|
|
3092
3153
|
[attr.aria-controls]="selectMenuId"
|
|
@@ -3119,20 +3180,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
3119
3180
|
[attr.data-theme]="theme()"
|
|
3120
3181
|
>
|
|
3121
3182
|
@for (option of options(); track option.value) {
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3183
|
+
<button
|
|
3184
|
+
class="select-menu-item"
|
|
3185
|
+
[class.selected]="option.value === value()"
|
|
3186
|
+
[attr.aria-selected]="option.value === value()"
|
|
3187
|
+
cdkMenuItem
|
|
3188
|
+
type="button"
|
|
3189
|
+
(click)="selectOption(option)"
|
|
3190
|
+
>
|
|
3191
|
+
{{ option.label }}
|
|
3192
|
+
</button>
|
|
3132
3193
|
}
|
|
3133
3194
|
</div>
|
|
3134
3195
|
</ng-template>
|
|
3135
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ngt-border-radius-small: 4px;--ngt-border-radius-medium: 8px;--ngt-border-radius-large: 12px;--ngt-transition-default: all .2s ease-out;--ngt-transition-smooth: all .2s ease-in-out;--ngt-bg-primary: rgb(255, 255, 255);--ngt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ngt-text-primary: rgb(17, 24, 39);--ngt-text-secondary: rgb(55, 65, 81);--ngt-text-muted: rgb(107, 114, 128);--ngt-border-primary: #e5e7eb;--ngt-border-subtle: rgba(17, 24, 39, .1);--ngt-hover-bg: rgba(17, 24, 39, .05);--ngt-hover-danger: rgb(239, 68, 68);--ngt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ngt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ngt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ngt-spacing-xs: 4px;--ngt-spacing-sm: 6px;--ngt-spacing-md: 12px;--ngt-spacing-lg: 16px;--ngt-window-padding: 16px;--ngt-font-size-xxs: .65rem;--ngt-font-size-xs: .75rem;--ngt-font-size-sm: .875rem;--ngt-font-size-md: 1rem;--ngt-font-size-lg: 1.25rem;--ngt-font-size-xl: 2rem;--ngt-background-secondary: var(--ngt-bg-primary);--ngt-background-hover: var(--ngt-hover-bg);--ngt-primary: #df30d4;--ngt-primary-rgb: 223, 48, 212;--ngt-text-on-primary: rgb(255, 255, 255);--ngt-border-color: var(--ngt-border-primary);--ngt-note-background: rgb(219, 234, 254);--ngt-note-border: rgba(37, 99, 235, .2);--ngt-warning-background: rgb(254, 249, 195);--ngt-warning-border: rgba(202, 138, 4, .2);--ngt-error-background: rgb(254, 226, 226);--ngt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ngt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border:1px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-small);background-color:var(--ngt-bg-primary);color:var(--ngt-text-primary);font-size:var(--ngt-font-size-sm);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngt-transition-default);outline:none;min-height:36px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ngt-select:hover{background-color:var(--ngt-hover-bg);border-color:var(--ngt-primary);box-shadow:0 1px 3px #0000001a}.ngt-select:focus-visible{outline:none;border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.small{padding:var(--ngt-spacing-xs) var(--ngt-spacing-sm);font-size:var(--ngt-font-size-sm);height:24px}.ngt-select.open{border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.open .select__arrow{transform:rotate(180deg)}.ngt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:var(--ngt-spacing-sm);min-width:0;display:flex;align-items:center}.ngt-select__arrow{width:16px;height:16px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ngt-select-menu{display:inline-flex;flex-direction:column;min-width:180px;background-color:var(--ngt-bg-primary);padding:var(--ngt-spacing-sm) 0;border:2px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-large);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ngt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ngt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ngt-select-menu::-webkit-scrollbar-track{background:transparent}.ngt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ngt-border-primary);border-radius:4px;border:2px solid var(--ngt-bg-primary)}.ngt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ngt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ngt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md) var(--ngt-spacing-sm) var(--ngt-spacing-lg);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ngt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.5;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ngt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ngt-primary);background-color:rgba(var(--ngt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ngt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:8px;width:3px;height:calc(100% - 16px);background-color:var(--ngt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f}.select-menu-item:first-child{margin-top:var(--ngt-spacing-xs)}.select-menu-item:last-child{margin-bottom:var(--ngt-spacing-xs)}.select-overlay{backdrop-filter:blur(8px)}\n"] }]
|
|
3196
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--ngt-border-radius-small: 4px;--ngt-border-radius-medium: 8px;--ngt-border-radius-large: 12px;--ngt-transition-default: all .2s ease-out;--ngt-transition-smooth: all .2s ease-in-out;--ngt-bg-primary: rgb(255, 255, 255);--ngt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ngt-text-primary: rgb(17, 24, 39);--ngt-text-secondary: rgb(55, 65, 81);--ngt-text-muted: rgb(107, 114, 128);--ngt-border-primary: #e5e7eb;--ngt-border-subtle: rgba(17, 24, 39, .1);--ngt-hover-bg: rgba(17, 24, 39, .05);--ngt-hover-danger: rgb(239, 68, 68);--ngt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ngt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ngt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ngt-spacing-xs: 4px;--ngt-spacing-sm: 6px;--ngt-spacing-md: 12px;--ngt-spacing-lg: 16px;--ngt-window-padding: 16px;--ngt-font-size-xxs: .65rem;--ngt-font-size-xs: .75rem;--ngt-font-size-sm: .875rem;--ngt-font-size-md: 1rem;--ngt-font-size-lg: 1.25rem;--ngt-font-size-xl: 2rem;--ngt-background-secondary: var(--ngt-bg-primary);--ngt-background-hover: var(--ngt-hover-bg);--ngt-primary: #df30d4;--ngt-primary-rgb: 223, 48, 212;--ngt-text-on-primary: rgb(255, 255, 255);--ngt-border-color: var(--ngt-border-primary);--ngt-note-background: rgb(219, 234, 254);--ngt-note-border: rgba(37, 99, 235, .2);--ngt-warning-background: rgb(254, 249, 195);--ngt-warning-border: rgba(202, 138, 4, .2);--ngt-error-background: rgb(254, 226, 226);--ngt-error-border: rgba(220, 38, 38, .2);display:inline-block;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\"}.ngt-select{position:relative;width:100%;min-width:120px;display:flex;align-items:center;justify-content:space-between;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border:1px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-small);background-color:var(--ngt-bg-primary);color:var(--ngt-text-primary);font-size:var(--ngt-font-size-sm);cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--ngt-transition-default);outline:none;min-height:36px;box-sizing:border-box;box-shadow:0 1px 2px #0000000d}.ngt-select:hover{background-color:var(--ngt-hover-bg);border-color:var(--ngt-primary);box-shadow:0 1px 3px #0000001a}.ngt-select:focus-visible{outline:none;border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.small{padding:var(--ngt-spacing-xs) var(--ngt-spacing-sm);font-size:var(--ngt-font-size-sm);height:24px}.ngt-select.open{border-color:var(--ngt-primary);box-shadow:0 0 0 2px rgba(var(--ngt-primary-rgb),.2),0 1px 3px #0000001a}.ngt-select.open .select__arrow{transform:rotate(180deg)}.ngt-select.placeholder{color:var(--ngt-text-muted)}.ngt-select__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;margin-right:var(--ngt-spacing-sm);min-width:0;display:flex;align-items:center}.ngt-select__arrow{width:16px;height:16px;flex-shrink:0;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:center;background-size:contain;transition:transform .2s ease;opacity:.9}.ngt-select-menu{display:inline-flex;flex-direction:column;min-width:180px;background-color:var(--ngt-bg-primary);padding:var(--ngt-spacing-sm) 0;border:2px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-large);box-shadow:0 4px 12px #00000026,0 2px 4px #0000001a;color:var(--ngt-text-primary);max-height:min(400px,70vh);overflow-y:auto;backdrop-filter:blur(8px);z-index:1000}.ngt-select-menu::-webkit-scrollbar{width:8px;height:8px}.ngt-select-menu::-webkit-scrollbar-track{background:transparent}.ngt-select-menu::-webkit-scrollbar-thumb{background-color:var(--ngt-border-primary);border-radius:4px;border:2px solid var(--ngt-bg-primary)}.ngt-select-menu::-webkit-scrollbar-thumb:hover{background-color:var(--ngt-text-secondary)}.select-menu-item{background-color:transparent;cursor:pointer;border:none;color:var(--ngt-text-primary);-webkit-user-select:none;user-select:none;min-width:64px;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md) var(--ngt-spacing-sm) var(--ngt-spacing-lg);display:flex;align-items:center;flex-direction:row;flex:1;font-size:var(--ngt-font-size-xs);font-family:inherit;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-weight:400;line-height:1.5;transition:background-color .15s ease}.select-menu-item:hover{background-color:#0000000f}.select-menu-item:active{background-color:rgba(var(--ngt-primary-rgb),.15)}.select-menu-item.selected{color:var(--ngt-primary);background-color:rgba(var(--ngt-primary-rgb),.08);font-weight:400}.select-menu-item.selected:hover{background-color:rgba(var(--ngt-primary-rgb),.12)}.select-menu-item.selected:before{content:\"\";position:absolute;left:0;top:8px;width:3px;height:calc(100% - 16px);background-color:var(--ngt-primary);border-radius:2px}.select-menu-item:focus-visible{outline:none;background-color:#0000000f}.select-menu-item:first-child{margin-top:var(--ngt-spacing-xs)}.select-menu-item:last-child{margin-bottom:var(--ngt-spacing-xs)}.select-overlay{backdrop-filter:blur(8px)}\n"] }]
|
|
3136
3197
|
}] });
|
|
3137
3198
|
|
|
3138
3199
|
class ToolbarToolButtonComponent {
|
|
@@ -3762,7 +3823,7 @@ class ToolbarAppFeaturesToolComponent {
|
|
|
3762
3823
|
</ngt-list>
|
|
3763
3824
|
</div>
|
|
3764
3825
|
</ngt-toolbar-tool>
|
|
3765
|
-
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);ngt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;gap:var(--ngt-spacing-md);.filter-icon{width:18px;height:18px;flex-shrink:0;opacity:.6}ngt-select{flex:0 0 auto;min-width:180px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }, { kind: "component", type: ToolbarListComponent, selector: "ngt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ngt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3826
|
+
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);ngt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;gap:var(--ngt-spacing-md);.filter-icon{width:18px;height:18px;flex-shrink:0;opacity:.6}ngt-select{flex:0 0 auto;min-width:180px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }, { kind: "component", type: ToolbarListComponent, selector: "ngt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ngt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3766
3827
|
}
|
|
3767
3828
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarAppFeaturesToolComponent, decorators: [{
|
|
3768
3829
|
type: Component,
|
|
@@ -3943,6 +4004,9 @@ class ToolbarFeatureFlagsToolComponent {
|
|
|
3943
4004
|
return '';
|
|
3944
4005
|
return flag.isEnabled ? 'on' : 'off';
|
|
3945
4006
|
}
|
|
4007
|
+
getFlagPlaceholder(flag) {
|
|
4008
|
+
return flag.isEnabled ? 'On' : 'Off';
|
|
4009
|
+
}
|
|
3946
4010
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarFeatureFlagsToolComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3947
4011
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarFeatureFlagsToolComponent, isStandalone: true, selector: "ngt-feature-flags-tool", ngImport: i0, template: `
|
|
3948
4012
|
<ngt-toolbar-tool
|
|
@@ -3976,26 +4040,27 @@ class ToolbarFeatureFlagsToolComponent {
|
|
|
3976
4040
|
noResultsMessage="No flags found matching your filter"
|
|
3977
4041
|
>
|
|
3978
4042
|
@for (flag of filteredFlags(); track flag.id) {
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
4043
|
+
<ngt-list-item
|
|
4044
|
+
[title]="flag.name"
|
|
4045
|
+
[description]="flag.description"
|
|
4046
|
+
[isForced]="flag.isForced"
|
|
4047
|
+
[currentValue]="flag.isEnabled"
|
|
4048
|
+
[originalValue]="flag.originalValue"
|
|
4049
|
+
>
|
|
4050
|
+
<ngt-select
|
|
4051
|
+
[value]="getFlagValue(flag)"
|
|
4052
|
+
[options]="flagValueOptions"
|
|
4053
|
+
[placeholder]="getFlagPlaceholder(flag)"
|
|
4054
|
+
[ariaLabel]="'Set value for ' + flag.name"
|
|
4055
|
+
(valueChange)="onFlagChange(flag.id, $event ?? '')"
|
|
4056
|
+
size="small"
|
|
4057
|
+
/>
|
|
4058
|
+
</ngt-list-item>
|
|
3994
4059
|
}
|
|
3995
4060
|
</ngt-list>
|
|
3996
4061
|
</div>
|
|
3997
4062
|
</ngt-toolbar-tool>
|
|
3998
|
-
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);ngt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;gap:var(--ngt-spacing-md);.filter-icon{width:18px;height:18px;flex-shrink:0;opacity:.6}ngt-select{flex:0 0 auto;min-width:180px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }, { kind: "component", type: ToolbarListComponent, selector: "ngt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ngt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4063
|
+
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);ngt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;gap:var(--ngt-spacing-md);.filter-icon{width:18px;height:18px;flex-shrink:0;opacity:.6}ngt-select{flex:0 0 auto;min-width:180px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }, { kind: "component", type: ToolbarListComponent, selector: "ngt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ngt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3999
4064
|
}
|
|
4000
4065
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarFeatureFlagsToolComponent, decorators: [{
|
|
4001
4066
|
type: Component,
|
|
@@ -4039,21 +4104,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
4039
4104
|
noResultsMessage="No flags found matching your filter"
|
|
4040
4105
|
>
|
|
4041
4106
|
@for (flag of filteredFlags(); track flag.id) {
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4107
|
+
<ngt-list-item
|
|
4108
|
+
[title]="flag.name"
|
|
4109
|
+
[description]="flag.description"
|
|
4110
|
+
[isForced]="flag.isForced"
|
|
4111
|
+
[currentValue]="flag.isEnabled"
|
|
4112
|
+
[originalValue]="flag.originalValue"
|
|
4113
|
+
>
|
|
4114
|
+
<ngt-select
|
|
4115
|
+
[value]="getFlagValue(flag)"
|
|
4116
|
+
[options]="flagValueOptions"
|
|
4117
|
+
[placeholder]="getFlagPlaceholder(flag)"
|
|
4118
|
+
[ariaLabel]="'Set value for ' + flag.name"
|
|
4119
|
+
(valueChange)="onFlagChange(flag.id, $event ?? '')"
|
|
4120
|
+
size="small"
|
|
4121
|
+
/>
|
|
4122
|
+
</ngt-list-item>
|
|
4057
4123
|
}
|
|
4058
4124
|
</ngt-list>
|
|
4059
4125
|
</div>
|
|
@@ -4496,7 +4562,7 @@ class ToolbarLanguageToolComponent {
|
|
|
4496
4562
|
/>
|
|
4497
4563
|
</div>
|
|
4498
4564
|
</ngt-toolbar-tool>
|
|
4499
|
-
`, isInline: true, styles: [":host{--ngt-border-radius-small: 4px;--ngt-border-radius-medium: 8px;--ngt-border-radius-large: 12px;--ngt-transition-default: all .2s ease-out;--ngt-transition-smooth: all .2s ease-in-out;--ngt-bg-primary: rgb(255, 255, 255);--ngt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ngt-text-primary: rgb(17, 24, 39);--ngt-text-secondary: rgb(55, 65, 81);--ngt-text-muted: rgb(107, 114, 128);--ngt-border-primary: #e5e7eb;--ngt-border-subtle: rgba(17, 24, 39, .1);--ngt-hover-bg: rgba(17, 24, 39, .05);--ngt-hover-danger: rgb(239, 68, 68);--ngt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ngt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ngt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ngt-spacing-xs: 4px;--ngt-spacing-sm: 6px;--ngt-spacing-md: 12px;--ngt-spacing-lg: 16px;--ngt-window-padding: 16px;--ngt-font-size-xxs: .65rem;--ngt-font-size-xs: .75rem;--ngt-font-size-sm: .875rem;--ngt-font-size-md: 1rem;--ngt-font-size-lg: 1.25rem;--ngt-font-size-xl: 2rem;--ngt-background-secondary: var(--ngt-bg-primary);--ngt-background-hover: var(--ngt-hover-bg);--ngt-primary: #df30d4;--ngt-primary-rgb: 223, 48, 212;--ngt-text-on-primary: rgb(255, 255, 255);--ngt-border-color: var(--ngt-border-primary);--ngt-note-background: rgb(219, 234, 254);--ngt-note-border: rgba(37, 99, 235, .2);--ngt-warning-background: rgb(254, 249, 195);--ngt-warning-border: rgba(202, 138, 4, .2);--ngt-error-background: rgb(254, 226, 226);--ngt-error-border: rgba(220, 38, 38, .2)}.language-select{display:flex;flex-direction:row;gap:.5rem;align-items:center;justify-content:space-between}\n"], dependencies: [{ kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size"], outputs: ["valueChange"] }] }); }
|
|
4565
|
+
`, isInline: true, styles: [":host{--ngt-border-radius-small: 4px;--ngt-border-radius-medium: 8px;--ngt-border-radius-large: 12px;--ngt-transition-default: all .2s ease-out;--ngt-transition-smooth: all .2s ease-in-out;--ngt-bg-primary: rgb(255, 255, 255);--ngt-bg-gradient: linear-gradient(180deg, rgb(243, 244, 246) 0%, rgba(243, 244, 246, .88) 100%);--ngt-text-primary: rgb(17, 24, 39);--ngt-text-secondary: rgb(55, 65, 81);--ngt-text-muted: rgb(107, 114, 128);--ngt-border-primary: #e5e7eb;--ngt-border-subtle: rgba(17, 24, 39, .1);--ngt-hover-bg: rgba(17, 24, 39, .05);--ngt-hover-danger: rgb(239, 68, 68);--ngt-shadow-toolbar: 0 2px 8px rgba(156, 163, 175, .2);--ngt-shadow-tooltip: 0 0 0 1px rgba(17, 24, 39, .05), 0 4px 8px rgba(107, 114, 128, .15), 0 2px 4px rgba(107, 114, 128, .1);--ngt-shadow-window: 0px 0px 0px 0px rgba(156, 163, 175, .1), 0px 1px 2px 0px rgba(156, 163, 175, .12), 0px 4px 4px 0px rgba(156, 163, 175, .1), 0px 10px 6px 0px rgba(156, 163, 175, .08), 0px 17px 7px 0px rgba(156, 163, 175, .05), 0px 26px 7px 0px rgba(156, 163, 175, .02);--ngt-spacing-xs: 4px;--ngt-spacing-sm: 6px;--ngt-spacing-md: 12px;--ngt-spacing-lg: 16px;--ngt-window-padding: 16px;--ngt-font-size-xxs: .65rem;--ngt-font-size-xs: .75rem;--ngt-font-size-sm: .875rem;--ngt-font-size-md: 1rem;--ngt-font-size-lg: 1.25rem;--ngt-font-size-xl: 2rem;--ngt-background-secondary: var(--ngt-bg-primary);--ngt-background-hover: var(--ngt-hover-bg);--ngt-primary: #df30d4;--ngt-primary-rgb: 223, 48, 212;--ngt-text-on-primary: rgb(255, 255, 255);--ngt-border-color: var(--ngt-border-primary);--ngt-note-background: rgb(219, 234, 254);--ngt-note-border: rgba(37, 99, 235, .2);--ngt-warning-background: rgb(254, 249, 195);--ngt-warning-border: rgba(202, 138, 4, .2);--ngt-error-background: rgb(254, 226, 226);--ngt-error-border: rgba(220, 38, 38, .2)}.language-select{display:flex;flex-direction:row;gap:.5rem;align-items:center;justify-content:space-between}\n"], dependencies: [{ kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }] }); }
|
|
4500
4566
|
}
|
|
4501
4567
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarLanguageToolComponent, decorators: [{
|
|
4502
4568
|
type: Component,
|
|
@@ -4685,7 +4751,7 @@ class ToolbarPermissionsToolComponent {
|
|
|
4685
4751
|
</ngt-list>
|
|
4686
4752
|
</div>
|
|
4687
4753
|
</ngt-toolbar-tool>
|
|
4688
|
-
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);ngt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;gap:var(--ngt-spacing-md);.filter-icon{width:18px;height:18px;flex-shrink:0;opacity:.6}ngt-select{flex:0 0 auto;min-width:180px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }, { kind: "component", type: ToolbarListComponent, selector: "ngt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ngt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4754
|
+
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);ngt-input{flex:1}.filter-wrapper{flex:0 0 auto;display:flex;align-items:center;gap:var(--ngt-spacing-md);.filter-icon{width:18px;height:18px;flex-shrink:0;opacity:.6}ngt-select{flex:0 0 auto;min-width:180px}}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarSelectComponent, selector: "ngt-select", inputs: ["value", "options", "ariaLabel", "label", "size", "placeholder"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }, { kind: "component", type: ToolbarListComponent, selector: "ngt-list", inputs: ["hasItems", "hasResults", "emptyMessage", "emptyHint", "noResultsMessage"] }, { kind: "component", type: ToolbarListItemComponent, selector: "ngt-list-item", inputs: ["title", "description", "isForced", "currentValue", "originalValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4689
4755
|
}
|
|
4690
4756
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarPermissionsToolComponent, decorators: [{
|
|
4691
4757
|
type: Component,
|
|
@@ -4849,6 +4915,52 @@ class ToolbarInternalPresetsService {
|
|
|
4849
4915
|
getPresetById(presetId) {
|
|
4850
4916
|
return this.presetsSubject.value.find((p) => p.id === presetId);
|
|
4851
4917
|
}
|
|
4918
|
+
/**
|
|
4919
|
+
* Toggle favorite status for a preset
|
|
4920
|
+
*/
|
|
4921
|
+
toggleFavorite(presetId) {
|
|
4922
|
+
const presets = this.presetsSubject.value.map((p) => p.id === presetId ? { ...p, isFavorite: !p.isFavorite } : p);
|
|
4923
|
+
this.presetsSubject.next(presets);
|
|
4924
|
+
this.storageService.set(this.STORAGE_KEY, presets);
|
|
4925
|
+
}
|
|
4926
|
+
/**
|
|
4927
|
+
* Apply a preset with partial options (only selected categories)
|
|
4928
|
+
*/
|
|
4929
|
+
async partialApplyPreset(presetId, options) {
|
|
4930
|
+
const preset = this.presetsSubject.value.find((p) => p.id === presetId);
|
|
4931
|
+
if (!preset)
|
|
4932
|
+
return;
|
|
4933
|
+
if (options.applyFeatureFlags) {
|
|
4934
|
+
this.featureFlagsService.applyPresetFlags(preset.config.featureFlags);
|
|
4935
|
+
}
|
|
4936
|
+
if (options.applyLanguage) {
|
|
4937
|
+
await this.languageService.applyPresetLanguage(preset.config.language);
|
|
4938
|
+
}
|
|
4939
|
+
if (options.applyPermissions) {
|
|
4940
|
+
this.permissionsService.applyPresetPermissions(preset.config.permissions);
|
|
4941
|
+
}
|
|
4942
|
+
if (options.applyAppFeatures) {
|
|
4943
|
+
this.appFeaturesService.applyForcedState(preset.config.appFeatures);
|
|
4944
|
+
}
|
|
4945
|
+
}
|
|
4946
|
+
/**
|
|
4947
|
+
* Update only the metadata (name, description) of a preset without changing config
|
|
4948
|
+
*/
|
|
4949
|
+
updatePresetMetadata(presetId, name, description) {
|
|
4950
|
+
const presets = this.presetsSubject.value.map((preset) => {
|
|
4951
|
+
if (preset.id === presetId) {
|
|
4952
|
+
return {
|
|
4953
|
+
...preset,
|
|
4954
|
+
name,
|
|
4955
|
+
description,
|
|
4956
|
+
updatedAt: new Date().toISOString(),
|
|
4957
|
+
};
|
|
4958
|
+
}
|
|
4959
|
+
return preset;
|
|
4960
|
+
});
|
|
4961
|
+
this.presetsSubject.next(presets);
|
|
4962
|
+
this.storageService.set(this.STORAGE_KEY, presets);
|
|
4963
|
+
}
|
|
4852
4964
|
/**
|
|
4853
4965
|
* Capture current configuration from all tools
|
|
4854
4966
|
*/
|
|
@@ -4927,27 +5039,80 @@ class ToolbarPresetsToolComponent {
|
|
|
4927
5039
|
this.appFeaturesService = inject(ToolbarInternalAppFeaturesService);
|
|
4928
5040
|
this.languageService = inject(ToolbarInternalLanguageService);
|
|
4929
5041
|
this.state = inject(ToolbarStateService);
|
|
4930
|
-
//
|
|
5042
|
+
// View state signals
|
|
4931
5043
|
this.viewMode = signal('list');
|
|
4932
5044
|
this.searchQuery = signal('');
|
|
5045
|
+
// Create form signals
|
|
4933
5046
|
this.presetName = signal('');
|
|
4934
5047
|
this.presetDescription = signal('');
|
|
4935
5048
|
this.includeFeatureFlags = signal(true);
|
|
4936
5049
|
this.includePermissions = signal(true);
|
|
4937
5050
|
this.includeAppFeatures = signal(true);
|
|
4938
5051
|
this.includeLanguage = signal(true);
|
|
4939
|
-
// Track selected individual items
|
|
4940
5052
|
this.selectedFlagIds = signal(new Set());
|
|
4941
5053
|
this.selectedPermissionIds = signal(new Set());
|
|
4942
5054
|
this.selectedFeatureIds = signal(new Set());
|
|
5055
|
+
// Edit mode signals
|
|
5056
|
+
this.editingPresetId = signal(null);
|
|
5057
|
+
this.editName = signal('');
|
|
5058
|
+
this.editDescription = signal('');
|
|
5059
|
+
// Import mode signals
|
|
5060
|
+
this.importJson = signal('');
|
|
5061
|
+
this.importError = signal(null);
|
|
5062
|
+
this.isDragOver = signal(false);
|
|
5063
|
+
// Apply mode signals
|
|
5064
|
+
this.applyingPresetId = signal(null);
|
|
5065
|
+
this.applyFeatureFlags = signal(true);
|
|
5066
|
+
this.applyPermissions = signal(true);
|
|
5067
|
+
this.applyAppFeatures = signal(true);
|
|
5068
|
+
this.applyLanguage = signal(true);
|
|
5069
|
+
// Delete confirmation signals
|
|
5070
|
+
this.deletePresetId = signal(null);
|
|
5071
|
+
// Toast signals
|
|
5072
|
+
this.toastMessage = signal(null);
|
|
5073
|
+
this.toastType = signal('success');
|
|
5074
|
+
// Validation signals
|
|
5075
|
+
this.nameError = signal(null);
|
|
5076
|
+
// Auto-dismiss toast effect
|
|
5077
|
+
this.toastTimeout = null;
|
|
5078
|
+
// Computed values
|
|
4943
5079
|
this.presets = this.presetsService.presets;
|
|
4944
5080
|
this.filteredPresets = computed(() => {
|
|
4945
5081
|
const query = this.searchQuery().toLowerCase();
|
|
4946
5082
|
return this.presets().filter((preset) => preset.name.toLowerCase().includes(query) ||
|
|
4947
5083
|
preset.description?.toLowerCase().includes(query));
|
|
4948
5084
|
});
|
|
5085
|
+
this.sortedPresets = computed(() => {
|
|
5086
|
+
const presets = this.filteredPresets();
|
|
5087
|
+
return [...presets].sort((a, b) => {
|
|
5088
|
+
if (a.isFavorite && !b.isFavorite)
|
|
5089
|
+
return -1;
|
|
5090
|
+
if (!a.isFavorite && b.isFavorite)
|
|
5091
|
+
return 1;
|
|
5092
|
+
return 0;
|
|
5093
|
+
});
|
|
5094
|
+
});
|
|
4949
5095
|
this.hasNoPresets = computed(() => this.presets().length === 0);
|
|
4950
5096
|
this.hasNoFilteredPresets = computed(() => this.filteredPresets().length === 0);
|
|
5097
|
+
this.editingPreset = computed(() => {
|
|
5098
|
+
const id = this.editingPresetId();
|
|
5099
|
+
if (!id)
|
|
5100
|
+
return null;
|
|
5101
|
+
return this.presets().find((p) => p.id === id) || null;
|
|
5102
|
+
});
|
|
5103
|
+
this.applyingPreset = computed(() => {
|
|
5104
|
+
const id = this.applyingPresetId();
|
|
5105
|
+
if (!id)
|
|
5106
|
+
return null;
|
|
5107
|
+
return this.presets().find((p) => p.id === id) || null;
|
|
5108
|
+
});
|
|
5109
|
+
this.deletePresetName = computed(() => {
|
|
5110
|
+
const id = this.deletePresetId();
|
|
5111
|
+
if (!id)
|
|
5112
|
+
return '';
|
|
5113
|
+
const preset = this.presets().find((p) => p.id === id);
|
|
5114
|
+
return preset?.name || '';
|
|
5115
|
+
});
|
|
4951
5116
|
// Tool availability (based on config)
|
|
4952
5117
|
this.isFeatureFlagsEnabled = computed(() => this.state.config().showFeatureFlagsTool ?? true);
|
|
4953
5118
|
this.isPermissionsEnabled = computed(() => this.state.config().showPermissionsTool ?? true);
|
|
@@ -4972,15 +5137,38 @@ class ToolbarPresetsToolComponent {
|
|
|
4972
5137
|
id: 'ngt-presets',
|
|
4973
5138
|
isBeta: true,
|
|
4974
5139
|
};
|
|
5140
|
+
effect(() => {
|
|
5141
|
+
const message = this.toastMessage();
|
|
5142
|
+
if (message) {
|
|
5143
|
+
if (this.toastTimeout) {
|
|
5144
|
+
clearTimeout(this.toastTimeout);
|
|
5145
|
+
}
|
|
5146
|
+
this.toastTimeout = setTimeout(() => {
|
|
5147
|
+
this.toastMessage.set(null);
|
|
5148
|
+
}, 3000);
|
|
5149
|
+
}
|
|
5150
|
+
});
|
|
4975
5151
|
}
|
|
4976
|
-
//
|
|
5152
|
+
// Toast helper
|
|
5153
|
+
showToast(message, type = 'success') {
|
|
5154
|
+
this.toastMessage.set(message);
|
|
5155
|
+
this.toastType.set(type);
|
|
5156
|
+
}
|
|
5157
|
+
// View mode switching
|
|
4977
5158
|
onSearchChange(query) {
|
|
4978
5159
|
this.searchQuery.set(query);
|
|
4979
5160
|
}
|
|
5161
|
+
onSwitchToListMode() {
|
|
5162
|
+
this.viewMode.set('list');
|
|
5163
|
+
this.nameError.set(null);
|
|
5164
|
+
this.importError.set(null);
|
|
5165
|
+
this.deletePresetId.set(null);
|
|
5166
|
+
}
|
|
4980
5167
|
onSwitchToCreateMode() {
|
|
4981
5168
|
this.viewMode.set('create');
|
|
4982
5169
|
this.presetName.set('');
|
|
4983
5170
|
this.presetDescription.set('');
|
|
5171
|
+
this.nameError.set(null);
|
|
4984
5172
|
// Reset checkboxes - only enable categories that have forced items
|
|
4985
5173
|
this.includeFeatureFlags.set(this.getCurrentFlagsCount() > 0);
|
|
4986
5174
|
this.includePermissions.set(this.getCurrentPermissionsCount() > 0);
|
|
@@ -4992,14 +5180,33 @@ class ToolbarPresetsToolComponent {
|
|
|
4992
5180
|
this.selectedPermissionIds.set(new Set(this.forcedPermissions().map((p) => p.id)));
|
|
4993
5181
|
this.selectedFeatureIds.set(new Set(this.forcedAppFeatures().map((f) => f.id)));
|
|
4994
5182
|
}
|
|
4995
|
-
|
|
4996
|
-
this.viewMode.set('
|
|
5183
|
+
onSwitchToImportMode() {
|
|
5184
|
+
this.viewMode.set('import');
|
|
5185
|
+
this.importJson.set('');
|
|
5186
|
+
this.importError.set(null);
|
|
5187
|
+
this.isDragOver.set(false);
|
|
5188
|
+
}
|
|
5189
|
+
// Create preset
|
|
5190
|
+
onPresetNameChange(value) {
|
|
5191
|
+
this.presetName.set(value);
|
|
5192
|
+
if (value.trim()) {
|
|
5193
|
+
this.nameError.set(null);
|
|
5194
|
+
}
|
|
4997
5195
|
}
|
|
4998
5196
|
onSavePreset(event) {
|
|
4999
5197
|
event.preventDefault();
|
|
5000
|
-
|
|
5198
|
+
const name = this.presetName().trim();
|
|
5199
|
+
if (!name) {
|
|
5200
|
+
this.nameError.set('Name is required');
|
|
5001
5201
|
return;
|
|
5002
|
-
|
|
5202
|
+
}
|
|
5203
|
+
// Check for duplicate names
|
|
5204
|
+
const existingPreset = this.presets().find((p) => p.name.toLowerCase() === name.toLowerCase());
|
|
5205
|
+
if (existingPreset) {
|
|
5206
|
+
this.nameError.set('A preset with this name already exists');
|
|
5207
|
+
return;
|
|
5208
|
+
}
|
|
5209
|
+
this.presetsService.saveCurrentAsPreset(name, this.presetDescription(), {
|
|
5003
5210
|
includeFeatureFlags: this.includeFeatureFlags(),
|
|
5004
5211
|
includePermissions: this.includePermissions(),
|
|
5005
5212
|
includeAppFeatures: this.includeAppFeatures(),
|
|
@@ -5008,14 +5215,153 @@ class ToolbarPresetsToolComponent {
|
|
|
5008
5215
|
selectedPermissionIds: Array.from(this.selectedPermissionIds()),
|
|
5009
5216
|
selectedFeatureIds: Array.from(this.selectedFeatureIds()),
|
|
5010
5217
|
});
|
|
5218
|
+
this.showToast('Preset created successfully');
|
|
5219
|
+
this.onSwitchToListMode();
|
|
5220
|
+
}
|
|
5221
|
+
// Edit preset
|
|
5222
|
+
onStartEdit(presetId) {
|
|
5223
|
+
const preset = this.presets().find((p) => p.id === presetId);
|
|
5224
|
+
if (!preset)
|
|
5225
|
+
return;
|
|
5226
|
+
this.editingPresetId.set(presetId);
|
|
5227
|
+
this.editName.set(preset.name);
|
|
5228
|
+
this.editDescription.set(preset.description || '');
|
|
5229
|
+
this.nameError.set(null);
|
|
5230
|
+
this.viewMode.set('edit');
|
|
5231
|
+
}
|
|
5232
|
+
onEditNameChange(value) {
|
|
5233
|
+
this.editName.set(value);
|
|
5234
|
+
if (value.trim()) {
|
|
5235
|
+
this.nameError.set(null);
|
|
5236
|
+
}
|
|
5237
|
+
}
|
|
5238
|
+
onSaveEdit(event) {
|
|
5239
|
+
event.preventDefault();
|
|
5240
|
+
const name = this.editName().trim();
|
|
5241
|
+
const presetId = this.editingPresetId();
|
|
5242
|
+
if (!name) {
|
|
5243
|
+
this.nameError.set('Name is required');
|
|
5244
|
+
return;
|
|
5245
|
+
}
|
|
5246
|
+
if (!presetId)
|
|
5247
|
+
return;
|
|
5248
|
+
// Check for duplicate names (excluding current preset)
|
|
5249
|
+
const existingPreset = this.presets().find((p) => p.id !== presetId && p.name.toLowerCase() === name.toLowerCase());
|
|
5250
|
+
if (existingPreset) {
|
|
5251
|
+
this.nameError.set('A preset with this name already exists');
|
|
5252
|
+
return;
|
|
5253
|
+
}
|
|
5254
|
+
this.presetsService.updatePresetMetadata(presetId, name, this.editDescription());
|
|
5255
|
+
this.showToast('Preset updated successfully');
|
|
5011
5256
|
this.onSwitchToListMode();
|
|
5012
5257
|
}
|
|
5013
|
-
|
|
5014
|
-
this.
|
|
5258
|
+
onReplaceConfig() {
|
|
5259
|
+
const presetId = this.editingPresetId();
|
|
5260
|
+
if (!presetId)
|
|
5261
|
+
return;
|
|
5262
|
+
this.presetsService.updatePreset(presetId);
|
|
5263
|
+
this.showToast('Configuration replaced with current state');
|
|
5264
|
+
}
|
|
5265
|
+
// Import preset
|
|
5266
|
+
onDragOver(event) {
|
|
5267
|
+
event.preventDefault();
|
|
5268
|
+
event.stopPropagation();
|
|
5269
|
+
this.isDragOver.set(true);
|
|
5270
|
+
}
|
|
5271
|
+
onDragLeave(event) {
|
|
5272
|
+
event.preventDefault();
|
|
5273
|
+
event.stopPropagation();
|
|
5274
|
+
this.isDragOver.set(false);
|
|
5275
|
+
}
|
|
5276
|
+
onFileDrop(event) {
|
|
5277
|
+
event.preventDefault();
|
|
5278
|
+
event.stopPropagation();
|
|
5279
|
+
this.isDragOver.set(false);
|
|
5280
|
+
const files = event.dataTransfer?.files;
|
|
5281
|
+
if (files && files.length > 0) {
|
|
5282
|
+
this.processFile(files[0]);
|
|
5283
|
+
}
|
|
5284
|
+
}
|
|
5285
|
+
onFileSelect(event) {
|
|
5286
|
+
const input = event.target;
|
|
5287
|
+
if (input.files && input.files.length > 0) {
|
|
5288
|
+
this.processFile(input.files[0]);
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
processFile(file) {
|
|
5292
|
+
if (!file.name.endsWith('.json')) {
|
|
5293
|
+
this.importError.set('Please select a .json file');
|
|
5294
|
+
return;
|
|
5295
|
+
}
|
|
5296
|
+
const reader = new FileReader();
|
|
5297
|
+
reader.onload = (e) => {
|
|
5298
|
+
const content = e.target?.result;
|
|
5299
|
+
this.importJson.set(content);
|
|
5300
|
+
this.importError.set(null);
|
|
5301
|
+
};
|
|
5302
|
+
reader.onerror = () => {
|
|
5303
|
+
this.importError.set('Failed to read file');
|
|
5304
|
+
};
|
|
5305
|
+
reader.readAsText(file);
|
|
5306
|
+
}
|
|
5307
|
+
onImportJsonChange(event) {
|
|
5308
|
+
const textarea = event.target;
|
|
5309
|
+
this.importJson.set(textarea.value);
|
|
5310
|
+
this.importError.set(null);
|
|
5015
5311
|
}
|
|
5312
|
+
onImportPreset() {
|
|
5313
|
+
const json = this.importJson().trim();
|
|
5314
|
+
if (!json) {
|
|
5315
|
+
this.importError.set('Please provide JSON content');
|
|
5316
|
+
return;
|
|
5317
|
+
}
|
|
5318
|
+
try {
|
|
5319
|
+
const parsed = JSON.parse(json);
|
|
5320
|
+
// Validate required fields
|
|
5321
|
+
if (!parsed.name) {
|
|
5322
|
+
this.importError.set('Preset must have a name');
|
|
5323
|
+
return;
|
|
5324
|
+
}
|
|
5325
|
+
if (!parsed.config) {
|
|
5326
|
+
this.importError.set('Preset must have a config object');
|
|
5327
|
+
return;
|
|
5328
|
+
}
|
|
5329
|
+
this.presetsService.addPreset(parsed);
|
|
5330
|
+
this.showToast('Preset imported successfully');
|
|
5331
|
+
this.onSwitchToListMode();
|
|
5332
|
+
}
|
|
5333
|
+
catch {
|
|
5334
|
+
this.importError.set('Invalid JSON format');
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
5337
|
+
// Apply preset (partial)
|
|
5338
|
+
onStartApply(presetId) {
|
|
5339
|
+
this.applyingPresetId.set(presetId);
|
|
5340
|
+
this.applyFeatureFlags.set(true);
|
|
5341
|
+
this.applyPermissions.set(true);
|
|
5342
|
+
this.applyAppFeatures.set(true);
|
|
5343
|
+
this.applyLanguage.set(true);
|
|
5344
|
+
this.viewMode.set('apply');
|
|
5345
|
+
}
|
|
5346
|
+
onConfirmPartialApply() {
|
|
5347
|
+
const presetId = this.applyingPresetId();
|
|
5348
|
+
if (!presetId)
|
|
5349
|
+
return;
|
|
5350
|
+
this.presetsService.partialApplyPreset(presetId, {
|
|
5351
|
+
applyFeatureFlags: this.applyFeatureFlags(),
|
|
5352
|
+
applyPermissions: this.applyPermissions(),
|
|
5353
|
+
applyAppFeatures: this.applyAppFeatures(),
|
|
5354
|
+
applyLanguage: this.applyLanguage(),
|
|
5355
|
+
});
|
|
5356
|
+
this.showToast('Preset applied successfully');
|
|
5357
|
+
this.onSwitchToListMode();
|
|
5358
|
+
}
|
|
5359
|
+
// Update preset (with current state)
|
|
5016
5360
|
onUpdatePreset(presetId) {
|
|
5017
5361
|
this.presetsService.updatePreset(presetId);
|
|
5362
|
+
this.showToast('Preset updated with current state');
|
|
5018
5363
|
}
|
|
5364
|
+
// Export preset
|
|
5019
5365
|
onExportPreset(presetId) {
|
|
5020
5366
|
const preset = this.presets().find((p) => p.id === presetId);
|
|
5021
5367
|
if (!preset)
|
|
@@ -5028,11 +5374,25 @@ class ToolbarPresetsToolComponent {
|
|
|
5028
5374
|
link.download = `preset-${preset.name.toLowerCase().replace(/\s+/g, '-')}.json`;
|
|
5029
5375
|
link.click();
|
|
5030
5376
|
URL.revokeObjectURL(url);
|
|
5377
|
+
this.showToast('Preset exported');
|
|
5031
5378
|
}
|
|
5379
|
+
// Delete preset
|
|
5032
5380
|
onDeletePreset(presetId) {
|
|
5033
|
-
|
|
5381
|
+
this.deletePresetId.set(presetId);
|
|
5382
|
+
this.viewMode.set('delete');
|
|
5383
|
+
}
|
|
5384
|
+
onConfirmDelete() {
|
|
5385
|
+
const presetId = this.deletePresetId();
|
|
5386
|
+
if (presetId) {
|
|
5034
5387
|
this.presetsService.deletePreset(presetId);
|
|
5388
|
+
this.showToast('Preset deleted');
|
|
5035
5389
|
}
|
|
5390
|
+
this.deletePresetId.set(null);
|
|
5391
|
+
this.viewMode.set('list');
|
|
5392
|
+
}
|
|
5393
|
+
// Favorites
|
|
5394
|
+
onToggleFavorite(presetId) {
|
|
5395
|
+
this.presetsService.toggleFavorite(presetId);
|
|
5036
5396
|
}
|
|
5037
5397
|
// Protected methods
|
|
5038
5398
|
getCurrentFlagsCount() {
|
|
@@ -5053,9 +5413,44 @@ class ToolbarPresetsToolComponent {
|
|
|
5053
5413
|
formatDate(isoString) {
|
|
5054
5414
|
return new Date(isoString).toLocaleDateString();
|
|
5055
5415
|
}
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5416
|
+
getPresetTooltip(preset) {
|
|
5417
|
+
const lines = [];
|
|
5418
|
+
// Feature Flags
|
|
5419
|
+
const flagsEnabled = preset.config.featureFlags.enabled;
|
|
5420
|
+
const flagsDisabled = preset.config.featureFlags.disabled;
|
|
5421
|
+
if (flagsEnabled.length > 0 || flagsDisabled.length > 0) {
|
|
5422
|
+
lines.push('Feature Flags:');
|
|
5423
|
+
flagsEnabled.forEach(id => lines.push(` ✓ ${id}: ON`));
|
|
5424
|
+
flagsDisabled.forEach(id => lines.push(` ✗ ${id}: OFF`));
|
|
5425
|
+
}
|
|
5426
|
+
// Permissions
|
|
5427
|
+
const permsGranted = preset.config.permissions.granted;
|
|
5428
|
+
const permsDenied = preset.config.permissions.denied;
|
|
5429
|
+
if (permsGranted.length > 0 || permsDenied.length > 0) {
|
|
5430
|
+
if (lines.length > 0)
|
|
5431
|
+
lines.push('');
|
|
5432
|
+
lines.push('Permissions:');
|
|
5433
|
+
permsGranted.forEach(id => lines.push(` ✓ ${id}: GRANTED`));
|
|
5434
|
+
permsDenied.forEach(id => lines.push(` ✗ ${id}: DENIED`));
|
|
5435
|
+
}
|
|
5436
|
+
// App Features
|
|
5437
|
+
const featuresEnabled = preset.config.appFeatures.enabled;
|
|
5438
|
+
const featuresDisabled = preset.config.appFeatures.disabled;
|
|
5439
|
+
if (featuresEnabled.length > 0 || featuresDisabled.length > 0) {
|
|
5440
|
+
if (lines.length > 0)
|
|
5441
|
+
lines.push('');
|
|
5442
|
+
lines.push('App Features:');
|
|
5443
|
+
featuresEnabled.forEach(id => lines.push(` ✓ ${id}: ON`));
|
|
5444
|
+
featuresDisabled.forEach(id => lines.push(` ✗ ${id}: OFF`));
|
|
5445
|
+
}
|
|
5446
|
+
// Language
|
|
5447
|
+
if (preset.config.language) {
|
|
5448
|
+
if (lines.length > 0)
|
|
5449
|
+
lines.push('');
|
|
5450
|
+
lines.push(`Language: ${preset.config.language}`);
|
|
5451
|
+
}
|
|
5452
|
+
return lines.length > 0 ? lines.join('\n') : 'No configuration';
|
|
5453
|
+
}
|
|
5059
5454
|
toggleItemSelection(signal, itemId) {
|
|
5060
5455
|
const current = new Set(signal());
|
|
5061
5456
|
if (current.has(itemId)) {
|
|
@@ -5066,9 +5461,6 @@ class ToolbarPresetsToolComponent {
|
|
|
5066
5461
|
}
|
|
5067
5462
|
signal.set(current);
|
|
5068
5463
|
}
|
|
5069
|
-
/**
|
|
5070
|
-
* Check if an item is selected
|
|
5071
|
-
*/
|
|
5072
5464
|
isItemSelected(selectedSet, itemId) {
|
|
5073
5465
|
return selectedSet.has(itemId);
|
|
5074
5466
|
}
|
|
@@ -5076,8 +5468,17 @@ class ToolbarPresetsToolComponent {
|
|
|
5076
5468
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarPresetsToolComponent, isStandalone: true, selector: "ngt-presets-tool", ngImport: i0, template: `
|
|
5077
5469
|
<ngt-toolbar-tool [options]="options" title="Presets" icon="layout">
|
|
5078
5470
|
<div class="container">
|
|
5471
|
+
<!-- Toast Notification -->
|
|
5472
|
+
@if (toastMessage()) {
|
|
5473
|
+
<div class="toast" [class.toast--success]="toastType() === 'success'" [class.toast--error]="toastType() === 'error'">
|
|
5474
|
+
<span class="toast__icon">{{ toastType() === 'success' ? '✓' : '✕' }}</span>
|
|
5475
|
+
<span class="toast__message">{{ toastMessage() }}</span>
|
|
5476
|
+
</div>
|
|
5477
|
+
}
|
|
5478
|
+
|
|
5479
|
+
|
|
5079
5480
|
<!-- Mode Toggle -->
|
|
5080
|
-
@if (!hasNoPresets() || viewMode()
|
|
5481
|
+
@if (!hasNoPresets() || viewMode() !== 'list') {
|
|
5081
5482
|
<div class="tool-header">
|
|
5082
5483
|
@if (viewMode() === 'list') {
|
|
5083
5484
|
<ngt-input
|
|
@@ -5086,18 +5487,24 @@ class ToolbarPresetsToolComponent {
|
|
|
5086
5487
|
placeholder="Search presets..."
|
|
5087
5488
|
[ariaLabel]="'Search presets'"
|
|
5088
5489
|
/>
|
|
5490
|
+
<ngt-button
|
|
5491
|
+
(click)="onSwitchToImportMode()"
|
|
5492
|
+
[ariaLabel]="'Import preset'"
|
|
5493
|
+
>
|
|
5494
|
+
Import
|
|
5495
|
+
</ngt-button>
|
|
5089
5496
|
<ngt-button
|
|
5090
5497
|
(click)="onSwitchToCreateMode()"
|
|
5091
5498
|
[ariaLabel]="'Create new preset'"
|
|
5092
5499
|
>
|
|
5093
|
-
New
|
|
5500
|
+
New
|
|
5094
5501
|
</ngt-button>
|
|
5095
5502
|
} @else {
|
|
5096
5503
|
<ngt-button
|
|
5097
5504
|
(click)="onSwitchToListMode()"
|
|
5098
5505
|
[ariaLabel]="'Back to list'"
|
|
5099
5506
|
>
|
|
5100
|
-
← Back
|
|
5507
|
+
← Back
|
|
5101
5508
|
</ngt-button>
|
|
5102
5509
|
}
|
|
5103
5510
|
</div>
|
|
@@ -5106,13 +5513,20 @@ class ToolbarPresetsToolComponent {
|
|
|
5106
5513
|
<!-- Create Form -->
|
|
5107
5514
|
@if (viewMode() === 'create') {
|
|
5108
5515
|
<form (submit)="onSavePreset($event)" class="preset-form">
|
|
5109
|
-
<
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5516
|
+
<h3 class="form-title">Create Preset</h3>
|
|
5517
|
+
<p class="form-hint">This will save the current forced values from other tools. Only items you've explicitly set will be included.</p>
|
|
5518
|
+
<div class="form-field">
|
|
5519
|
+
<ngt-input
|
|
5520
|
+
label="Preset Name *"
|
|
5521
|
+
[value]="presetName()"
|
|
5522
|
+
(valueChange)="onPresetNameChange($event)"
|
|
5523
|
+
placeholder="e.g., Admin User - Full Access"
|
|
5524
|
+
[ariaLabel]="'Preset name'"
|
|
5525
|
+
/>
|
|
5526
|
+
@if (nameError()) {
|
|
5527
|
+
<span class="field-error">{{ nameError() }}</span>
|
|
5528
|
+
}
|
|
5529
|
+
</div>
|
|
5116
5530
|
<ngt-input
|
|
5117
5531
|
label="Description (optional)"
|
|
5118
5532
|
[value]="presetDescription()"
|
|
@@ -5240,11 +5654,305 @@ class ToolbarPresetsToolComponent {
|
|
|
5240
5654
|
</div>
|
|
5241
5655
|
|
|
5242
5656
|
<div class="form-actions">
|
|
5657
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
5243
5658
|
<ngt-button type="submit">Save Preset</ngt-button>
|
|
5244
5659
|
</div>
|
|
5245
5660
|
</form>
|
|
5246
5661
|
}
|
|
5247
5662
|
|
|
5663
|
+
<!-- Edit Form -->
|
|
5664
|
+
@if (viewMode() === 'edit') {
|
|
5665
|
+
<form (submit)="onSaveEdit($event)" class="preset-form">
|
|
5666
|
+
<h3 class="form-title">Edit Preset</h3>
|
|
5667
|
+
<div class="form-field">
|
|
5668
|
+
<ngt-input
|
|
5669
|
+
label="Preset Name *"
|
|
5670
|
+
[value]="editName()"
|
|
5671
|
+
(valueChange)="onEditNameChange($event)"
|
|
5672
|
+
placeholder="e.g., Admin User - Full Access"
|
|
5673
|
+
[ariaLabel]="'Preset name'"
|
|
5674
|
+
/>
|
|
5675
|
+
@if (nameError()) {
|
|
5676
|
+
<span class="field-error">{{ nameError() }}</span>
|
|
5677
|
+
}
|
|
5678
|
+
</div>
|
|
5679
|
+
<ngt-input
|
|
5680
|
+
label="Description (optional)"
|
|
5681
|
+
[value]="editDescription()"
|
|
5682
|
+
(valueChange)="editDescription.set($event)"
|
|
5683
|
+
placeholder="Brief description of this preset"
|
|
5684
|
+
[ariaLabel]="'Preset description'"
|
|
5685
|
+
/>
|
|
5686
|
+
|
|
5687
|
+
<!-- Show saved configuration read-only -->
|
|
5688
|
+
@if (editingPreset()) {
|
|
5689
|
+
<div class="config-preview">
|
|
5690
|
+
<h4>Saved Configuration</h4>
|
|
5691
|
+
@if (editingPreset()!.config.featureFlags.enabled.length > 0 || editingPreset()!.config.featureFlags.disabled.length > 0) {
|
|
5692
|
+
<div class="config-category">
|
|
5693
|
+
<span class="config-category__title">Feature Flags ({{ editingPreset()!.config.featureFlags.enabled.length + editingPreset()!.config.featureFlags.disabled.length }})</span>
|
|
5694
|
+
<div class="config-items">
|
|
5695
|
+
@for (id of editingPreset()!.config.featureFlags.enabled; track id) {
|
|
5696
|
+
<span class="config-item config-item--on">{{ id }}: ON</span>
|
|
5697
|
+
}
|
|
5698
|
+
@for (id of editingPreset()!.config.featureFlags.disabled; track id) {
|
|
5699
|
+
<span class="config-item config-item--off">{{ id }}: OFF</span>
|
|
5700
|
+
}
|
|
5701
|
+
</div>
|
|
5702
|
+
</div>
|
|
5703
|
+
}
|
|
5704
|
+
@if (editingPreset()!.config.permissions.granted.length > 0 || editingPreset()!.config.permissions.denied.length > 0) {
|
|
5705
|
+
<div class="config-category">
|
|
5706
|
+
<span class="config-category__title">Permissions ({{ editingPreset()!.config.permissions.granted.length + editingPreset()!.config.permissions.denied.length }})</span>
|
|
5707
|
+
<div class="config-items">
|
|
5708
|
+
@for (id of editingPreset()!.config.permissions.granted; track id) {
|
|
5709
|
+
<span class="config-item config-item--on">{{ id }}: GRANTED</span>
|
|
5710
|
+
}
|
|
5711
|
+
@for (id of editingPreset()!.config.permissions.denied; track id) {
|
|
5712
|
+
<span class="config-item config-item--off">{{ id }}: DENIED</span>
|
|
5713
|
+
}
|
|
5714
|
+
</div>
|
|
5715
|
+
</div>
|
|
5716
|
+
}
|
|
5717
|
+
@if (editingPreset()!.config.appFeatures.enabled.length > 0 || editingPreset()!.config.appFeatures.disabled.length > 0) {
|
|
5718
|
+
<div class="config-category">
|
|
5719
|
+
<span class="config-category__title">App Features ({{ editingPreset()!.config.appFeatures.enabled.length + editingPreset()!.config.appFeatures.disabled.length }})</span>
|
|
5720
|
+
<div class="config-items">
|
|
5721
|
+
@for (id of editingPreset()!.config.appFeatures.enabled; track id) {
|
|
5722
|
+
<span class="config-item config-item--on">{{ id }}: ON</span>
|
|
5723
|
+
}
|
|
5724
|
+
@for (id of editingPreset()!.config.appFeatures.disabled; track id) {
|
|
5725
|
+
<span class="config-item config-item--off">{{ id }}: OFF</span>
|
|
5726
|
+
}
|
|
5727
|
+
</div>
|
|
5728
|
+
</div>
|
|
5729
|
+
}
|
|
5730
|
+
@if (editingPreset()!.config.language) {
|
|
5731
|
+
<div class="config-category">
|
|
5732
|
+
<span class="config-category__title">Language</span>
|
|
5733
|
+
<span class="config-item">{{ editingPreset()!.config.language }}</span>
|
|
5734
|
+
</div>
|
|
5735
|
+
}
|
|
5736
|
+
<button type="button" class="replace-config-button" (click)="onReplaceConfig()">
|
|
5737
|
+
↻ Replace with current toolbar state
|
|
5738
|
+
</button>
|
|
5739
|
+
</div>
|
|
5740
|
+
}
|
|
5741
|
+
|
|
5742
|
+
<div class="form-actions">
|
|
5743
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
5744
|
+
<ngt-button type="submit">Save Changes</ngt-button>
|
|
5745
|
+
</div>
|
|
5746
|
+
</form>
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5749
|
+
<!-- Import View -->
|
|
5750
|
+
@if (viewMode() === 'import') {
|
|
5751
|
+
<div class="import-view">
|
|
5752
|
+
<h3 class="form-title">Import Preset</h3>
|
|
5753
|
+
|
|
5754
|
+
<!-- File Drop Zone -->
|
|
5755
|
+
<div
|
|
5756
|
+
class="drop-zone"
|
|
5757
|
+
[class.drop-zone--active]="isDragOver()"
|
|
5758
|
+
(dragover)="onDragOver($event)"
|
|
5759
|
+
(dragleave)="onDragLeave($event)"
|
|
5760
|
+
(drop)="onFileDrop($event)"
|
|
5761
|
+
(click)="fileInput.click()"
|
|
5762
|
+
(keydown.enter)="fileInput.click()"
|
|
5763
|
+
(keydown.space)="fileInput.click()"
|
|
5764
|
+
tabindex="0"
|
|
5765
|
+
role="button"
|
|
5766
|
+
>
|
|
5767
|
+
<input
|
|
5768
|
+
#fileInput
|
|
5769
|
+
type="file"
|
|
5770
|
+
accept=".json"
|
|
5771
|
+
(change)="onFileSelect($event)"
|
|
5772
|
+
hidden
|
|
5773
|
+
/>
|
|
5774
|
+
<span class="drop-zone__icon">📁</span>
|
|
5775
|
+
<span class="drop-zone__text">Drop a .json file here</span>
|
|
5776
|
+
<span class="drop-zone__hint">or click to browse</span>
|
|
5777
|
+
</div>
|
|
5778
|
+
|
|
5779
|
+
<div class="divider">
|
|
5780
|
+
<span>or paste JSON</span>
|
|
5781
|
+
</div>
|
|
5782
|
+
|
|
5783
|
+
<!-- JSON Textarea -->
|
|
5784
|
+
<textarea
|
|
5785
|
+
class="json-textarea"
|
|
5786
|
+
[value]="importJson()"
|
|
5787
|
+
(input)="onImportJsonChange($event)"
|
|
5788
|
+
placeholder='{"name": "...", "config": { ... }}'
|
|
5789
|
+
></textarea>
|
|
5790
|
+
|
|
5791
|
+
@if (importError()) {
|
|
5792
|
+
<span class="field-error">{{ importError() }}</span>
|
|
5793
|
+
}
|
|
5794
|
+
|
|
5795
|
+
<div class="form-actions">
|
|
5796
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
5797
|
+
<ngt-button (click)="onImportPreset()">Import Preset</ngt-button>
|
|
5798
|
+
</div>
|
|
5799
|
+
</div>
|
|
5800
|
+
}
|
|
5801
|
+
|
|
5802
|
+
<!-- Partial Apply View -->
|
|
5803
|
+
@if (viewMode() === 'apply') {
|
|
5804
|
+
<div class="apply-view">
|
|
5805
|
+
<h3 class="form-title">Apply: {{ applyingPreset()?.name }}</h3>
|
|
5806
|
+
<p class="apply-description">Select which parts to apply</p>
|
|
5807
|
+
|
|
5808
|
+
@if (applyingPreset()) {
|
|
5809
|
+
<div class="apply-categories">
|
|
5810
|
+
<!-- Feature Flags -->
|
|
5811
|
+
@if (applyingPreset()!.config.featureFlags.enabled.length > 0 || applyingPreset()!.config.featureFlags.disabled.length > 0) {
|
|
5812
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyFeatureFlags()">
|
|
5813
|
+
<label class="apply-category__header">
|
|
5814
|
+
<input
|
|
5815
|
+
type="checkbox"
|
|
5816
|
+
[checked]="applyFeatureFlags()"
|
|
5817
|
+
(change)="applyFeatureFlags.set(!applyFeatureFlags())"
|
|
5818
|
+
/>
|
|
5819
|
+
<span>Feature Flags ({{ applyingPreset()!.config.featureFlags.enabled.length + applyingPreset()!.config.featureFlags.disabled.length }})</span>
|
|
5820
|
+
</label>
|
|
5821
|
+
@if (applyFeatureFlags()) {
|
|
5822
|
+
<div class="apply-diff">
|
|
5823
|
+
@for (id of applyingPreset()!.config.featureFlags.enabled; track id) {
|
|
5824
|
+
<div class="diff-item">
|
|
5825
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
5826
|
+
<span class="diff-item__arrow">→</span>
|
|
5827
|
+
<span class="diff-item__value diff-item__value--on">ON</span>
|
|
5828
|
+
</div>
|
|
5829
|
+
}
|
|
5830
|
+
@for (id of applyingPreset()!.config.featureFlags.disabled; track id) {
|
|
5831
|
+
<div class="diff-item">
|
|
5832
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
5833
|
+
<span class="diff-item__arrow">→</span>
|
|
5834
|
+
<span class="diff-item__value diff-item__value--off">OFF</span>
|
|
5835
|
+
</div>
|
|
5836
|
+
}
|
|
5837
|
+
</div>
|
|
5838
|
+
}
|
|
5839
|
+
</div>
|
|
5840
|
+
}
|
|
5841
|
+
|
|
5842
|
+
<!-- Permissions -->
|
|
5843
|
+
@if (applyingPreset()!.config.permissions.granted.length > 0 || applyingPreset()!.config.permissions.denied.length > 0) {
|
|
5844
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyPermissions()">
|
|
5845
|
+
<label class="apply-category__header">
|
|
5846
|
+
<input
|
|
5847
|
+
type="checkbox"
|
|
5848
|
+
[checked]="applyPermissions()"
|
|
5849
|
+
(change)="applyPermissions.set(!applyPermissions())"
|
|
5850
|
+
/>
|
|
5851
|
+
<span>Permissions ({{ applyingPreset()!.config.permissions.granted.length + applyingPreset()!.config.permissions.denied.length }})</span>
|
|
5852
|
+
</label>
|
|
5853
|
+
@if (applyPermissions()) {
|
|
5854
|
+
<div class="apply-diff">
|
|
5855
|
+
@for (id of applyingPreset()!.config.permissions.granted; track id) {
|
|
5856
|
+
<div class="diff-item">
|
|
5857
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
5858
|
+
<span class="diff-item__arrow">→</span>
|
|
5859
|
+
<span class="diff-item__value diff-item__value--on">GRANTED</span>
|
|
5860
|
+
</div>
|
|
5861
|
+
}
|
|
5862
|
+
@for (id of applyingPreset()!.config.permissions.denied; track id) {
|
|
5863
|
+
<div class="diff-item">
|
|
5864
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
5865
|
+
<span class="diff-item__arrow">→</span>
|
|
5866
|
+
<span class="diff-item__value diff-item__value--off">DENIED</span>
|
|
5867
|
+
</div>
|
|
5868
|
+
}
|
|
5869
|
+
</div>
|
|
5870
|
+
}
|
|
5871
|
+
</div>
|
|
5872
|
+
}
|
|
5873
|
+
|
|
5874
|
+
<!-- App Features -->
|
|
5875
|
+
@if (applyingPreset()!.config.appFeatures.enabled.length > 0 || applyingPreset()!.config.appFeatures.disabled.length > 0) {
|
|
5876
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyAppFeatures()">
|
|
5877
|
+
<label class="apply-category__header">
|
|
5878
|
+
<input
|
|
5879
|
+
type="checkbox"
|
|
5880
|
+
[checked]="applyAppFeatures()"
|
|
5881
|
+
(change)="applyAppFeatures.set(!applyAppFeatures())"
|
|
5882
|
+
/>
|
|
5883
|
+
<span>App Features ({{ applyingPreset()!.config.appFeatures.enabled.length + applyingPreset()!.config.appFeatures.disabled.length }})</span>
|
|
5884
|
+
</label>
|
|
5885
|
+
@if (applyAppFeatures()) {
|
|
5886
|
+
<div class="apply-diff">
|
|
5887
|
+
@for (id of applyingPreset()!.config.appFeatures.enabled; track id) {
|
|
5888
|
+
<div class="diff-item">
|
|
5889
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
5890
|
+
<span class="diff-item__arrow">→</span>
|
|
5891
|
+
<span class="diff-item__value diff-item__value--on">ON</span>
|
|
5892
|
+
</div>
|
|
5893
|
+
}
|
|
5894
|
+
@for (id of applyingPreset()!.config.appFeatures.disabled; track id) {
|
|
5895
|
+
<div class="diff-item">
|
|
5896
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
5897
|
+
<span class="diff-item__arrow">→</span>
|
|
5898
|
+
<span class="diff-item__value diff-item__value--off">OFF</span>
|
|
5899
|
+
</div>
|
|
5900
|
+
}
|
|
5901
|
+
</div>
|
|
5902
|
+
}
|
|
5903
|
+
</div>
|
|
5904
|
+
}
|
|
5905
|
+
|
|
5906
|
+
<!-- Language -->
|
|
5907
|
+
@if (applyingPreset()!.config.language) {
|
|
5908
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyLanguage()">
|
|
5909
|
+
<label class="apply-category__header">
|
|
5910
|
+
<input
|
|
5911
|
+
type="checkbox"
|
|
5912
|
+
[checked]="applyLanguage()"
|
|
5913
|
+
(change)="applyLanguage.set(!applyLanguage())"
|
|
5914
|
+
/>
|
|
5915
|
+
<span>Language</span>
|
|
5916
|
+
</label>
|
|
5917
|
+
@if (applyLanguage()) {
|
|
5918
|
+
<div class="apply-diff">
|
|
5919
|
+
<div class="diff-item">
|
|
5920
|
+
<span class="diff-item__name">Language</span>
|
|
5921
|
+
<span class="diff-item__arrow">→</span>
|
|
5922
|
+
<span class="diff-item__value">{{ applyingPreset()!.config.language }}</span>
|
|
5923
|
+
</div>
|
|
5924
|
+
</div>
|
|
5925
|
+
}
|
|
5926
|
+
</div>
|
|
5927
|
+
}
|
|
5928
|
+
</div>
|
|
5929
|
+
}
|
|
5930
|
+
|
|
5931
|
+
<div class="form-actions">
|
|
5932
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
5933
|
+
<ngt-button (click)="onConfirmPartialApply()">Apply Selected</ngt-button>
|
|
5934
|
+
</div>
|
|
5935
|
+
</div>
|
|
5936
|
+
}
|
|
5937
|
+
|
|
5938
|
+
<!-- Delete Confirmation View -->
|
|
5939
|
+
@if (viewMode() === 'delete') {
|
|
5940
|
+
<div class="delete-view">
|
|
5941
|
+
<div class="delete-view__content">
|
|
5942
|
+
<div class="delete-view__icon">🗑️</div>
|
|
5943
|
+
<h3 class="delete-view__title">Delete "{{ deletePresetName() }}"?</h3>
|
|
5944
|
+
<p class="delete-view__description">
|
|
5945
|
+
This preset will be permanently removed.
|
|
5946
|
+
This action cannot be undone.
|
|
5947
|
+
</p>
|
|
5948
|
+
</div>
|
|
5949
|
+
<div class="form-actions">
|
|
5950
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">← Back</ngt-button>
|
|
5951
|
+
<button class="delete-button" (click)="onConfirmDelete()">Delete Preset</button>
|
|
5952
|
+
</div>
|
|
5953
|
+
</div>
|
|
5954
|
+
}
|
|
5955
|
+
|
|
5248
5956
|
<!-- Empty State -->
|
|
5249
5957
|
@if (viewMode() === 'list' && hasNoPresets()) {
|
|
5250
5958
|
<div class="empty">
|
|
@@ -5263,83 +5971,49 @@ class ToolbarPresetsToolComponent {
|
|
|
5263
5971
|
} @else if (viewMode() === 'list') {
|
|
5264
5972
|
<!-- Preset List -->
|
|
5265
5973
|
<div class="preset-list">
|
|
5266
|
-
@for (preset of
|
|
5267
|
-
<div class="preset-card">
|
|
5974
|
+
@for (preset of sortedPresets(); track preset.id) {
|
|
5975
|
+
<div class="preset-card" [title]="getPresetTooltip(preset)">
|
|
5268
5976
|
<div class="preset-card__header">
|
|
5269
|
-
<
|
|
5977
|
+
<button
|
|
5978
|
+
class="favorite-button"
|
|
5979
|
+
[class.favorite-button--active]="preset.isFavorite"
|
|
5980
|
+
(click)="onToggleFavorite(preset.id); $event.stopPropagation()"
|
|
5981
|
+
[attr.aria-label]="preset.isFavorite ? 'Remove from favorites' : 'Add to favorites'"
|
|
5982
|
+
>{{ preset.isFavorite ? '★' : '☆' }}</button>
|
|
5983
|
+
<span class="preset-card__name">{{ preset.name }}</span>
|
|
5984
|
+
@if (preset.isSystem) {<span class="system-badge">SYS</span>}
|
|
5985
|
+
<span class="preset-card__spacer"></span>
|
|
5270
5986
|
<div class="preset-card__actions">
|
|
5271
|
-
<button
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
>
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
class="icon-button"
|
|
5281
|
-
(click)="onUpdatePreset(preset.id)"
|
|
5282
|
-
[attr.aria-label]="'Update preset ' + preset.name"
|
|
5283
|
-
title="Update with current state"
|
|
5284
|
-
>
|
|
5285
|
-
<ngt-icon name="gear" />
|
|
5286
|
-
</button>
|
|
5287
|
-
<button
|
|
5288
|
-
class="icon-button"
|
|
5289
|
-
(click)="onExportPreset(preset.id)"
|
|
5290
|
-
[attr.aria-label]="'Export preset ' + preset.name"
|
|
5291
|
-
title="Export as JSON"
|
|
5292
|
-
>
|
|
5293
|
-
<ngt-icon name="export" />
|
|
5294
|
-
</button>
|
|
5295
|
-
<button
|
|
5296
|
-
class="icon-button"
|
|
5297
|
-
(click)="onDeletePreset(preset.id)"
|
|
5298
|
-
[attr.aria-label]="'Delete preset ' + preset.name"
|
|
5299
|
-
title="Delete preset"
|
|
5300
|
-
>
|
|
5301
|
-
<ngt-icon name="trash" />
|
|
5302
|
-
</button>
|
|
5987
|
+
<button class="icon-button" (click)="onStartApply(preset.id)"><ngt-icon name="refresh" /></button>
|
|
5988
|
+
@if (!preset.isSystem) {
|
|
5989
|
+
<button class="icon-button" (click)="onStartEdit(preset.id)"><ngt-icon name="edit" /></button>
|
|
5990
|
+
<button class="icon-button" (click)="onUpdatePreset(preset.id)"><ngt-icon name="gear" /></button>
|
|
5991
|
+
}
|
|
5992
|
+
<button class="icon-button" (click)="onExportPreset(preset.id)"><ngt-icon name="export" /></button>
|
|
5993
|
+
@if (!preset.isSystem) {
|
|
5994
|
+
<button class="icon-button" (click)="onDeletePreset(preset.id)"><ngt-icon name="trash" /></button>
|
|
5995
|
+
}
|
|
5303
5996
|
</div>
|
|
5304
5997
|
</div>
|
|
5305
5998
|
@if (preset.description) {
|
|
5306
|
-
<
|
|
5307
|
-
|
|
5308
|
-
<div class="preset-card__meta">
|
|
5309
|
-
<span>Updated: {{ formatDate(preset.updatedAt) }}</span>
|
|
5999
|
+
<div class="preset-card__row preset-card__row--meta">
|
|
6000
|
+
<span class="preset-card__description">{{ preset.description }}</span>
|
|
5310
6001
|
</div>
|
|
5311
|
-
|
|
5312
|
-
<div class="preset-
|
|
5313
|
-
@if (preset.config.featureFlags.enabled.length > 0 ||
|
|
5314
|
-
preset.config.featureFlags.disabled.length >
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
preset.config.featureFlags.disabled.length
|
|
5319
|
-
}}
|
|
5320
|
-
flags
|
|
5321
|
-
</span>
|
|
5322
|
-
} @if (preset.config.permissions.granted.length > 0 ||
|
|
5323
|
-
preset.config.permissions.denied.length > 0) {
|
|
5324
|
-
<span class="badge">
|
|
5325
|
-
{{
|
|
5326
|
-
preset.config.permissions.granted.length +
|
|
5327
|
-
preset.config.permissions.denied.length
|
|
5328
|
-
}}
|
|
5329
|
-
perms
|
|
5330
|
-
</span>
|
|
5331
|
-
} @if (preset.config.appFeatures.enabled.length > 0 ||
|
|
5332
|
-
preset.config.appFeatures.disabled.length > 0) {
|
|
5333
|
-
<span class="badge">
|
|
5334
|
-
{{
|
|
5335
|
-
preset.config.appFeatures.enabled.length +
|
|
5336
|
-
preset.config.appFeatures.disabled.length
|
|
5337
|
-
}}
|
|
5338
|
-
features
|
|
5339
|
-
</span>
|
|
5340
|
-
} @if (preset.config.language) {
|
|
5341
|
-
<span class="badge">{{ preset.config.language }}</span>
|
|
6002
|
+
}
|
|
6003
|
+
<div class="preset-card__row preset-card__row--badges">
|
|
6004
|
+
@if (preset.config.featureFlags.enabled.length > 0 || preset.config.featureFlags.disabled.length > 0) {
|
|
6005
|
+
<span class="badge">{{ preset.config.featureFlags.enabled.length + preset.config.featureFlags.disabled.length }} flags</span>
|
|
6006
|
+
}
|
|
6007
|
+
@if (preset.config.permissions.granted.length > 0 || preset.config.permissions.denied.length > 0) {
|
|
6008
|
+
<span class="badge">{{ preset.config.permissions.granted.length + preset.config.permissions.denied.length }} perms</span>
|
|
5342
6009
|
}
|
|
6010
|
+
@if (preset.config.appFeatures.enabled.length > 0 || preset.config.appFeatures.disabled.length > 0) {
|
|
6011
|
+
<span class="badge">{{ preset.config.appFeatures.enabled.length + preset.config.appFeatures.disabled.length }} features</span>
|
|
6012
|
+
}
|
|
6013
|
+
@if (preset.config.language) {
|
|
6014
|
+
<span class="badge badge--lang">{{ preset.config.language }}</span>
|
|
6015
|
+
}
|
|
6016
|
+
<span class="preset-card__date">{{ formatDate(preset.updatedAt) }}</span>
|
|
5343
6017
|
</div>
|
|
5344
6018
|
</div>
|
|
5345
6019
|
}
|
|
@@ -5347,7 +6021,7 @@ class ToolbarPresetsToolComponent {
|
|
|
5347
6021
|
}
|
|
5348
6022
|
</div>
|
|
5349
6023
|
</ngt-toolbar-tool>
|
|
5350
|
-
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-md);ngt-input{flex:1}ngt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ngt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ngt-border-subtle);border-radius:var(--ngt-border-radius-medium);padding:var(--ngt-spacing-md);background:transparent;color:var(--ngt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ngt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ngt-spacing-md);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ngt-spacing-sm);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ngt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ngt-border-primary);border-radius:4px;&:hover{background:var(--ngt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ngt-border-primary) var(--ngt-background-secondary)}.preset-card{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-sm)}.preset-card__header{display:flex;justify-content:space-between;align-items:center;gap:var(--ngt-spacing-sm);h3{margin:0;font-size:var(--ngt-font-size-md);color:var(--ngt-text-primary);flex:1}}.preset-card__actions{display:flex;gap:var(--ngt-spacing-xs)}.icon-button{background:transparent;border:none;cursor:pointer;padding:var(--ngt-spacing-xs);border-radius:var(--ngt-border-radius-small);color:var(--ngt-text-secondary);display:flex;align-items:center;justify-content:center;&:hover{background:var(--ngt-hover-bg);color:var(--ngt-text-primary)}ngt-icon{width:16px;height:16px}}.preset-card__description{margin:0;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-secondary)}.preset-card__meta{font-size:var(--ngt-font-size-xs);color:var(--ngt-text-muted);span{margin-right:var(--ngt-spacing-sm)}}.preset-card__preview{display:flex;gap:var(--ngt-spacing-xs);flex-wrap:wrap}.badge{background:var(--ngt-primary-color);color:#fff;padding:2px 8px;border-radius:12px;font-size:var(--ngt-font-size-xs);font-weight:500}.preset-form{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ngt-spacing-md);padding:var(--ngt-spacing-md);ngt-input{width:100%}}.preset-summary{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-sm);h4{margin:0;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-primary)}}.category-section{display:flex;flex-direction:column;gap:var(--ngt-spacing-xs)}.checkbox-option{display:flex;align-items:center;gap:var(--ngt-spacing-sm);cursor:pointer;color:var(--ngt-text-secondary);font-size:var(--ngt-font-size-sm);input[type=checkbox]{cursor:pointer;width:16px;height:16px;accent-color:var(--ngt-primary);&:disabled{cursor:not-allowed;opacity:.5}}&:has(input:disabled){opacity:.6;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 var(--ngt-spacing-lg);display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);font-size:var(--ngt-font-size-xs);li{background:rgba(var(--ngt-primary-rgb),.05);border-radius:var(--ngt-border-radius-small);border-left:2px solid rgba(var(--ngt-primary-rgb),.3)}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:var(--ngt-spacing-xs) var(--ngt-spacing-sm);cursor:pointer;gap:var(--ngt-spacing-sm);input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:var(--ngt-primary);flex-shrink:0}&:hover{background:rgba(var(--ngt-primary-rgb),.08)}}.item-name{color:var(--ngt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:2px 6px;border-radius:var(--ngt-border-radius-small);font-size:10px;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0;&.enabled{background:#22c55e26;color:#22c55e}&.disabled{background:#ef444426;color:#ef4444}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ngt-spacing-sm)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarButtonComponent, selector: "ngt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6024
|
+
`, isInline: true, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.toast{position:absolute;bottom:var(--ngt-spacing-md);left:var(--ngt-spacing-md);right:var(--ngt-spacing-md);z-index:10;display:flex;align-items:center;gap:var(--ngt-spacing-sm);padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-small);font-size:var(--ngt-font-size-sm);animation:slideUp .15s ease-out}.toast--success{background:#22c55e;color:#fff}.toast--error{background:#ef4444;color:#fff}.toast__icon{font-weight:700}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.delete-view{flex:1;display:flex;flex-direction:column;justify-content:center;padding:var(--ngt-spacing-md)}.delete-view__content{text-align:center;padding:var(--ngt-spacing-lg) var(--ngt-spacing-md)}.delete-view__icon{font-size:48px;margin-bottom:var(--ngt-spacing-md)}.delete-view__title{margin:0 0 var(--ngt-spacing-sm);font-size:var(--ngt-font-size-md);color:var(--ngt-text-primary)}.delete-view__description{margin:0;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-secondary);line-height:1.5}.delete-button{background:#ef4444;color:#fff;border:none;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-small);cursor:pointer;font-size:var(--ngt-font-size-sm);font-weight:500;transition:background .2s ease-out;&:hover{background:#dc2626}}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-md);ngt-input{flex:1}ngt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ngt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ngt-border-subtle);border-radius:var(--ngt-border-radius-medium);padding:var(--ngt-spacing-md);background:transparent;color:var(--ngt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ngt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ngt-spacing-xs);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ngt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ngt-border-primary);border-radius:4px;&:hover{background:var(--ngt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ngt-border-primary) var(--ngt-background-secondary)}.preset-card{background:var(--ngt-background-secondary);padding:6px var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:2px}.preset-card__header{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}.preset-card__row{display:flex;align-items:center;gap:6px;min-height:18px}.preset-card__row--meta{padding-left:18px}.preset-card__row--badges{padding-left:18px;gap:4px}.preset-card__name{font-size:var(--ngt-font-size-sm);font-weight:600;color:var(--ngt-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__spacer{flex:1;min-width:8px}.system-badge{font-size:8px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 4px;border-radius:3px;background:var(--ngt-border-primary);color:var(--ngt-text-muted);flex-shrink:0}.favorite-button{background:transparent;border:none;cursor:pointer;font-size:12px;color:var(--ngt-text-muted);padding:0;line-height:1;transition:color .15s ease-out;flex-shrink:0}.favorite-button:hover,.favorite-button--active{color:#f59e0b}.preset-card__actions{display:flex;gap:0;flex-shrink:0}.icon-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:4px;border-radius:4px;color:var(--ngt-text-muted);display:inline-flex;align-items:center;justify-content:center;opacity:.5;transition:opacity .15s ease-out,color .15s ease-out;line-height:0;&:hover{background:var(--ngt-hover-bg);color:var(--ngt-text-primary);opacity:1}ngt-icon,ngt-icon>*,svg{display:block;width:12px!important;height:12px!important}}.preset-card__description{font-size:11px;color:var(--ngt-text-secondary);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__date{font-size:10px;color:var(--ngt-text-muted);margin-left:auto;flex-shrink:0}.badge{background:#6366f126;color:#6366f1;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:500;white-space:nowrap}.badge--lang{background:#22c55e26;color:#22c55e}.preset-form,.import-view,.apply-view{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ngt-spacing-sm);padding:var(--ngt-spacing-sm);ngt-input{width:100%}}.form-title{margin:0;font-size:var(--ngt-font-size-sm);font-weight:600;color:var(--ngt-text-primary)}.form-hint{margin:0;font-size:11px;color:var(--ngt-text-muted);line-height:1.3}.form-field{display:flex;flex-direction:column;gap:2px}.field-error{color:#ef4444;font-size:11px}.preset-summary{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ngt-text-secondary)}}.category-section{display:flex;flex-direction:column;gap:2px}.checkbox-option{display:flex;align-items:center;gap:var(--ngt-spacing-xs);cursor:pointer;color:var(--ngt-text-primary);font-size:var(--ngt-font-size-sm);padding:2px 0;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241);border-radius:3px;&:disabled{cursor:not-allowed;opacity:.4}}&:has(input:disabled){opacity:.5;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 20px;display:flex;flex-direction:column;gap:2px;font-size:11px;max-height:100px;overflow-y:auto;li{background:#6366f10d;border-radius:3px;border-left:2px solid rgba(99,102,241,.3)}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:3px 6px;cursor:pointer;gap:6px;input[type=checkbox]{cursor:pointer;width:12px;height:12px;accent-color:rgb(99,102,241);flex-shrink:0}&:hover{background:#6366f114}}.item-name{color:var(--ngt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0;&.enabled{background:#22c55e26;color:#22c55e}&.disabled{background:#ef444426;color:#ef4444}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ngt-spacing-sm);margin-top:auto;padding-top:var(--ngt-spacing-sm)}.config-preview{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ngt-text-secondary)}}.config-category{display:flex;flex-direction:column;gap:2px}.config-category__title{font-size:10px;color:var(--ngt-text-muted);font-weight:500}.config-items{display:flex;flex-wrap:wrap;gap:4px}.config-item{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--ngt-background-primary);color:var(--ngt-text-secondary)}.config-item--on{background:#22c55e1a;color:#22c55e}.config-item--off{background:#ef44441a;color:#ef4444}.replace-config-button{background:transparent;border:1px dashed var(--ngt-border-primary);padding:6px var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-small);color:var(--ngt-text-secondary);cursor:pointer;font-size:11px;transition:all .15s ease-out;&:hover{background:var(--ngt-hover-bg);border-color:#6366f1;color:#6366f1}}.drop-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--ngt-spacing-md);border:2px dashed var(--ngt-border-primary);border-radius:var(--ngt-border-radius-medium);cursor:pointer;transition:all .15s ease-out}.drop-zone:hover,.drop-zone--active{border-color:#6366f1;background:#6366f10d}.drop-zone__icon{font-size:24px}.drop-zone__text{font-size:var(--ngt-font-size-sm);color:var(--ngt-text-primary)}.drop-zone__hint{font-size:11px;color:var(--ngt-text-muted)}.divider{display:flex;align-items:center;gap:var(--ngt-spacing-sm);color:var(--ngt-text-muted);font-size:10px;&:before,&:after{content:\"\";flex:1;height:1px;background:var(--ngt-border-primary)}}.json-textarea{width:100%;min-height:80px;padding:var(--ngt-spacing-xs);border:1px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-small);background:var(--ngt-background-secondary);color:var(--ngt-text-primary);font-family:monospace;font-size:11px;resize:vertical;&:focus{outline:none;border-color:#6366f1}&::placeholder{color:var(--ngt-text-muted)}}.apply-description{margin:0;font-size:11px;color:var(--ngt-text-secondary)}.apply-categories{display:flex;flex-direction:column;gap:var(--ngt-spacing-xs)}.apply-category{background:var(--ngt-background-secondary);border-radius:var(--ngt-border-radius-small);overflow:hidden;transition:opacity .15s ease-out}.apply-category--disabled{opacity:.5}.apply-category__header{display:flex;align-items:center;gap:var(--ngt-spacing-xs);padding:6px var(--ngt-spacing-sm);cursor:pointer;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-primary);font-weight:500;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241)}}.apply-diff{padding:0 var(--ngt-spacing-sm) 6px;display:flex;flex-direction:column;gap:2px}.diff-item{display:flex;align-items:center;gap:6px;font-size:11px;padding:3px 6px;background:var(--ngt-background-primary);border-radius:3px}.diff-item__name{flex:1;color:var(--ngt-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-item__arrow{color:var(--ngt-text-muted);font-size:10px}.diff-item__value{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px}.diff-item__value--on{background:#22c55e26;color:#22c55e}.diff-item__value--off{background:#ef444426;color:#ef4444}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ToolbarToolComponent, selector: "ngt-toolbar-tool", inputs: ["options", "icon", "title", "badge"] }, { kind: "component", type: ToolbarInputComponent, selector: "ngt-input", inputs: ["value", "type", "placeholder", "ariaLabel", "inputClass"], outputs: ["valueChange"] }, { kind: "component", type: ToolbarButtonComponent, selector: "ngt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }, { kind: "component", type: ToolbarIconComponent, selector: "ngt-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5351
6025
|
}
|
|
5352
6026
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarPresetsToolComponent, decorators: [{
|
|
5353
6027
|
type: Component,
|
|
@@ -5360,8 +6034,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
5360
6034
|
], template: `
|
|
5361
6035
|
<ngt-toolbar-tool [options]="options" title="Presets" icon="layout">
|
|
5362
6036
|
<div class="container">
|
|
6037
|
+
<!-- Toast Notification -->
|
|
6038
|
+
@if (toastMessage()) {
|
|
6039
|
+
<div class="toast" [class.toast--success]="toastType() === 'success'" [class.toast--error]="toastType() === 'error'">
|
|
6040
|
+
<span class="toast__icon">{{ toastType() === 'success' ? '✓' : '✕' }}</span>
|
|
6041
|
+
<span class="toast__message">{{ toastMessage() }}</span>
|
|
6042
|
+
</div>
|
|
6043
|
+
}
|
|
6044
|
+
|
|
6045
|
+
|
|
5363
6046
|
<!-- Mode Toggle -->
|
|
5364
|
-
@if (!hasNoPresets() || viewMode()
|
|
6047
|
+
@if (!hasNoPresets() || viewMode() !== 'list') {
|
|
5365
6048
|
<div class="tool-header">
|
|
5366
6049
|
@if (viewMode() === 'list') {
|
|
5367
6050
|
<ngt-input
|
|
@@ -5370,18 +6053,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
5370
6053
|
placeholder="Search presets..."
|
|
5371
6054
|
[ariaLabel]="'Search presets'"
|
|
5372
6055
|
/>
|
|
6056
|
+
<ngt-button
|
|
6057
|
+
(click)="onSwitchToImportMode()"
|
|
6058
|
+
[ariaLabel]="'Import preset'"
|
|
6059
|
+
>
|
|
6060
|
+
Import
|
|
6061
|
+
</ngt-button>
|
|
5373
6062
|
<ngt-button
|
|
5374
6063
|
(click)="onSwitchToCreateMode()"
|
|
5375
6064
|
[ariaLabel]="'Create new preset'"
|
|
5376
6065
|
>
|
|
5377
|
-
New
|
|
6066
|
+
New
|
|
5378
6067
|
</ngt-button>
|
|
5379
6068
|
} @else {
|
|
5380
6069
|
<ngt-button
|
|
5381
6070
|
(click)="onSwitchToListMode()"
|
|
5382
6071
|
[ariaLabel]="'Back to list'"
|
|
5383
6072
|
>
|
|
5384
|
-
← Back
|
|
6073
|
+
← Back
|
|
5385
6074
|
</ngt-button>
|
|
5386
6075
|
}
|
|
5387
6076
|
</div>
|
|
@@ -5390,13 +6079,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
5390
6079
|
<!-- Create Form -->
|
|
5391
6080
|
@if (viewMode() === 'create') {
|
|
5392
6081
|
<form (submit)="onSavePreset($event)" class="preset-form">
|
|
5393
|
-
<
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
6082
|
+
<h3 class="form-title">Create Preset</h3>
|
|
6083
|
+
<p class="form-hint">This will save the current forced values from other tools. Only items you've explicitly set will be included.</p>
|
|
6084
|
+
<div class="form-field">
|
|
6085
|
+
<ngt-input
|
|
6086
|
+
label="Preset Name *"
|
|
6087
|
+
[value]="presetName()"
|
|
6088
|
+
(valueChange)="onPresetNameChange($event)"
|
|
6089
|
+
placeholder="e.g., Admin User - Full Access"
|
|
6090
|
+
[ariaLabel]="'Preset name'"
|
|
6091
|
+
/>
|
|
6092
|
+
@if (nameError()) {
|
|
6093
|
+
<span class="field-error">{{ nameError() }}</span>
|
|
6094
|
+
}
|
|
6095
|
+
</div>
|
|
5400
6096
|
<ngt-input
|
|
5401
6097
|
label="Description (optional)"
|
|
5402
6098
|
[value]="presetDescription()"
|
|
@@ -5524,11 +6220,305 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
5524
6220
|
</div>
|
|
5525
6221
|
|
|
5526
6222
|
<div class="form-actions">
|
|
6223
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
5527
6224
|
<ngt-button type="submit">Save Preset</ngt-button>
|
|
5528
6225
|
</div>
|
|
5529
6226
|
</form>
|
|
5530
6227
|
}
|
|
5531
6228
|
|
|
6229
|
+
<!-- Edit Form -->
|
|
6230
|
+
@if (viewMode() === 'edit') {
|
|
6231
|
+
<form (submit)="onSaveEdit($event)" class="preset-form">
|
|
6232
|
+
<h3 class="form-title">Edit Preset</h3>
|
|
6233
|
+
<div class="form-field">
|
|
6234
|
+
<ngt-input
|
|
6235
|
+
label="Preset Name *"
|
|
6236
|
+
[value]="editName()"
|
|
6237
|
+
(valueChange)="onEditNameChange($event)"
|
|
6238
|
+
placeholder="e.g., Admin User - Full Access"
|
|
6239
|
+
[ariaLabel]="'Preset name'"
|
|
6240
|
+
/>
|
|
6241
|
+
@if (nameError()) {
|
|
6242
|
+
<span class="field-error">{{ nameError() }}</span>
|
|
6243
|
+
}
|
|
6244
|
+
</div>
|
|
6245
|
+
<ngt-input
|
|
6246
|
+
label="Description (optional)"
|
|
6247
|
+
[value]="editDescription()"
|
|
6248
|
+
(valueChange)="editDescription.set($event)"
|
|
6249
|
+
placeholder="Brief description of this preset"
|
|
6250
|
+
[ariaLabel]="'Preset description'"
|
|
6251
|
+
/>
|
|
6252
|
+
|
|
6253
|
+
<!-- Show saved configuration read-only -->
|
|
6254
|
+
@if (editingPreset()) {
|
|
6255
|
+
<div class="config-preview">
|
|
6256
|
+
<h4>Saved Configuration</h4>
|
|
6257
|
+
@if (editingPreset()!.config.featureFlags.enabled.length > 0 || editingPreset()!.config.featureFlags.disabled.length > 0) {
|
|
6258
|
+
<div class="config-category">
|
|
6259
|
+
<span class="config-category__title">Feature Flags ({{ editingPreset()!.config.featureFlags.enabled.length + editingPreset()!.config.featureFlags.disabled.length }})</span>
|
|
6260
|
+
<div class="config-items">
|
|
6261
|
+
@for (id of editingPreset()!.config.featureFlags.enabled; track id) {
|
|
6262
|
+
<span class="config-item config-item--on">{{ id }}: ON</span>
|
|
6263
|
+
}
|
|
6264
|
+
@for (id of editingPreset()!.config.featureFlags.disabled; track id) {
|
|
6265
|
+
<span class="config-item config-item--off">{{ id }}: OFF</span>
|
|
6266
|
+
}
|
|
6267
|
+
</div>
|
|
6268
|
+
</div>
|
|
6269
|
+
}
|
|
6270
|
+
@if (editingPreset()!.config.permissions.granted.length > 0 || editingPreset()!.config.permissions.denied.length > 0) {
|
|
6271
|
+
<div class="config-category">
|
|
6272
|
+
<span class="config-category__title">Permissions ({{ editingPreset()!.config.permissions.granted.length + editingPreset()!.config.permissions.denied.length }})</span>
|
|
6273
|
+
<div class="config-items">
|
|
6274
|
+
@for (id of editingPreset()!.config.permissions.granted; track id) {
|
|
6275
|
+
<span class="config-item config-item--on">{{ id }}: GRANTED</span>
|
|
6276
|
+
}
|
|
6277
|
+
@for (id of editingPreset()!.config.permissions.denied; track id) {
|
|
6278
|
+
<span class="config-item config-item--off">{{ id }}: DENIED</span>
|
|
6279
|
+
}
|
|
6280
|
+
</div>
|
|
6281
|
+
</div>
|
|
6282
|
+
}
|
|
6283
|
+
@if (editingPreset()!.config.appFeatures.enabled.length > 0 || editingPreset()!.config.appFeatures.disabled.length > 0) {
|
|
6284
|
+
<div class="config-category">
|
|
6285
|
+
<span class="config-category__title">App Features ({{ editingPreset()!.config.appFeatures.enabled.length + editingPreset()!.config.appFeatures.disabled.length }})</span>
|
|
6286
|
+
<div class="config-items">
|
|
6287
|
+
@for (id of editingPreset()!.config.appFeatures.enabled; track id) {
|
|
6288
|
+
<span class="config-item config-item--on">{{ id }}: ON</span>
|
|
6289
|
+
}
|
|
6290
|
+
@for (id of editingPreset()!.config.appFeatures.disabled; track id) {
|
|
6291
|
+
<span class="config-item config-item--off">{{ id }}: OFF</span>
|
|
6292
|
+
}
|
|
6293
|
+
</div>
|
|
6294
|
+
</div>
|
|
6295
|
+
}
|
|
6296
|
+
@if (editingPreset()!.config.language) {
|
|
6297
|
+
<div class="config-category">
|
|
6298
|
+
<span class="config-category__title">Language</span>
|
|
6299
|
+
<span class="config-item">{{ editingPreset()!.config.language }}</span>
|
|
6300
|
+
</div>
|
|
6301
|
+
}
|
|
6302
|
+
<button type="button" class="replace-config-button" (click)="onReplaceConfig()">
|
|
6303
|
+
↻ Replace with current toolbar state
|
|
6304
|
+
</button>
|
|
6305
|
+
</div>
|
|
6306
|
+
}
|
|
6307
|
+
|
|
6308
|
+
<div class="form-actions">
|
|
6309
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
6310
|
+
<ngt-button type="submit">Save Changes</ngt-button>
|
|
6311
|
+
</div>
|
|
6312
|
+
</form>
|
|
6313
|
+
}
|
|
6314
|
+
|
|
6315
|
+
<!-- Import View -->
|
|
6316
|
+
@if (viewMode() === 'import') {
|
|
6317
|
+
<div class="import-view">
|
|
6318
|
+
<h3 class="form-title">Import Preset</h3>
|
|
6319
|
+
|
|
6320
|
+
<!-- File Drop Zone -->
|
|
6321
|
+
<div
|
|
6322
|
+
class="drop-zone"
|
|
6323
|
+
[class.drop-zone--active]="isDragOver()"
|
|
6324
|
+
(dragover)="onDragOver($event)"
|
|
6325
|
+
(dragleave)="onDragLeave($event)"
|
|
6326
|
+
(drop)="onFileDrop($event)"
|
|
6327
|
+
(click)="fileInput.click()"
|
|
6328
|
+
(keydown.enter)="fileInput.click()"
|
|
6329
|
+
(keydown.space)="fileInput.click()"
|
|
6330
|
+
tabindex="0"
|
|
6331
|
+
role="button"
|
|
6332
|
+
>
|
|
6333
|
+
<input
|
|
6334
|
+
#fileInput
|
|
6335
|
+
type="file"
|
|
6336
|
+
accept=".json"
|
|
6337
|
+
(change)="onFileSelect($event)"
|
|
6338
|
+
hidden
|
|
6339
|
+
/>
|
|
6340
|
+
<span class="drop-zone__icon">📁</span>
|
|
6341
|
+
<span class="drop-zone__text">Drop a .json file here</span>
|
|
6342
|
+
<span class="drop-zone__hint">or click to browse</span>
|
|
6343
|
+
</div>
|
|
6344
|
+
|
|
6345
|
+
<div class="divider">
|
|
6346
|
+
<span>or paste JSON</span>
|
|
6347
|
+
</div>
|
|
6348
|
+
|
|
6349
|
+
<!-- JSON Textarea -->
|
|
6350
|
+
<textarea
|
|
6351
|
+
class="json-textarea"
|
|
6352
|
+
[value]="importJson()"
|
|
6353
|
+
(input)="onImportJsonChange($event)"
|
|
6354
|
+
placeholder='{"name": "...", "config": { ... }}'
|
|
6355
|
+
></textarea>
|
|
6356
|
+
|
|
6357
|
+
@if (importError()) {
|
|
6358
|
+
<span class="field-error">{{ importError() }}</span>
|
|
6359
|
+
}
|
|
6360
|
+
|
|
6361
|
+
<div class="form-actions">
|
|
6362
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
6363
|
+
<ngt-button (click)="onImportPreset()">Import Preset</ngt-button>
|
|
6364
|
+
</div>
|
|
6365
|
+
</div>
|
|
6366
|
+
}
|
|
6367
|
+
|
|
6368
|
+
<!-- Partial Apply View -->
|
|
6369
|
+
@if (viewMode() === 'apply') {
|
|
6370
|
+
<div class="apply-view">
|
|
6371
|
+
<h3 class="form-title">Apply: {{ applyingPreset()?.name }}</h3>
|
|
6372
|
+
<p class="apply-description">Select which parts to apply</p>
|
|
6373
|
+
|
|
6374
|
+
@if (applyingPreset()) {
|
|
6375
|
+
<div class="apply-categories">
|
|
6376
|
+
<!-- Feature Flags -->
|
|
6377
|
+
@if (applyingPreset()!.config.featureFlags.enabled.length > 0 || applyingPreset()!.config.featureFlags.disabled.length > 0) {
|
|
6378
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyFeatureFlags()">
|
|
6379
|
+
<label class="apply-category__header">
|
|
6380
|
+
<input
|
|
6381
|
+
type="checkbox"
|
|
6382
|
+
[checked]="applyFeatureFlags()"
|
|
6383
|
+
(change)="applyFeatureFlags.set(!applyFeatureFlags())"
|
|
6384
|
+
/>
|
|
6385
|
+
<span>Feature Flags ({{ applyingPreset()!.config.featureFlags.enabled.length + applyingPreset()!.config.featureFlags.disabled.length }})</span>
|
|
6386
|
+
</label>
|
|
6387
|
+
@if (applyFeatureFlags()) {
|
|
6388
|
+
<div class="apply-diff">
|
|
6389
|
+
@for (id of applyingPreset()!.config.featureFlags.enabled; track id) {
|
|
6390
|
+
<div class="diff-item">
|
|
6391
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
6392
|
+
<span class="diff-item__arrow">→</span>
|
|
6393
|
+
<span class="diff-item__value diff-item__value--on">ON</span>
|
|
6394
|
+
</div>
|
|
6395
|
+
}
|
|
6396
|
+
@for (id of applyingPreset()!.config.featureFlags.disabled; track id) {
|
|
6397
|
+
<div class="diff-item">
|
|
6398
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
6399
|
+
<span class="diff-item__arrow">→</span>
|
|
6400
|
+
<span class="diff-item__value diff-item__value--off">OFF</span>
|
|
6401
|
+
</div>
|
|
6402
|
+
}
|
|
6403
|
+
</div>
|
|
6404
|
+
}
|
|
6405
|
+
</div>
|
|
6406
|
+
}
|
|
6407
|
+
|
|
6408
|
+
<!-- Permissions -->
|
|
6409
|
+
@if (applyingPreset()!.config.permissions.granted.length > 0 || applyingPreset()!.config.permissions.denied.length > 0) {
|
|
6410
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyPermissions()">
|
|
6411
|
+
<label class="apply-category__header">
|
|
6412
|
+
<input
|
|
6413
|
+
type="checkbox"
|
|
6414
|
+
[checked]="applyPermissions()"
|
|
6415
|
+
(change)="applyPermissions.set(!applyPermissions())"
|
|
6416
|
+
/>
|
|
6417
|
+
<span>Permissions ({{ applyingPreset()!.config.permissions.granted.length + applyingPreset()!.config.permissions.denied.length }})</span>
|
|
6418
|
+
</label>
|
|
6419
|
+
@if (applyPermissions()) {
|
|
6420
|
+
<div class="apply-diff">
|
|
6421
|
+
@for (id of applyingPreset()!.config.permissions.granted; track id) {
|
|
6422
|
+
<div class="diff-item">
|
|
6423
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
6424
|
+
<span class="diff-item__arrow">→</span>
|
|
6425
|
+
<span class="diff-item__value diff-item__value--on">GRANTED</span>
|
|
6426
|
+
</div>
|
|
6427
|
+
}
|
|
6428
|
+
@for (id of applyingPreset()!.config.permissions.denied; track id) {
|
|
6429
|
+
<div class="diff-item">
|
|
6430
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
6431
|
+
<span class="diff-item__arrow">→</span>
|
|
6432
|
+
<span class="diff-item__value diff-item__value--off">DENIED</span>
|
|
6433
|
+
</div>
|
|
6434
|
+
}
|
|
6435
|
+
</div>
|
|
6436
|
+
}
|
|
6437
|
+
</div>
|
|
6438
|
+
}
|
|
6439
|
+
|
|
6440
|
+
<!-- App Features -->
|
|
6441
|
+
@if (applyingPreset()!.config.appFeatures.enabled.length > 0 || applyingPreset()!.config.appFeatures.disabled.length > 0) {
|
|
6442
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyAppFeatures()">
|
|
6443
|
+
<label class="apply-category__header">
|
|
6444
|
+
<input
|
|
6445
|
+
type="checkbox"
|
|
6446
|
+
[checked]="applyAppFeatures()"
|
|
6447
|
+
(change)="applyAppFeatures.set(!applyAppFeatures())"
|
|
6448
|
+
/>
|
|
6449
|
+
<span>App Features ({{ applyingPreset()!.config.appFeatures.enabled.length + applyingPreset()!.config.appFeatures.disabled.length }})</span>
|
|
6450
|
+
</label>
|
|
6451
|
+
@if (applyAppFeatures()) {
|
|
6452
|
+
<div class="apply-diff">
|
|
6453
|
+
@for (id of applyingPreset()!.config.appFeatures.enabled; track id) {
|
|
6454
|
+
<div class="diff-item">
|
|
6455
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
6456
|
+
<span class="diff-item__arrow">→</span>
|
|
6457
|
+
<span class="diff-item__value diff-item__value--on">ON</span>
|
|
6458
|
+
</div>
|
|
6459
|
+
}
|
|
6460
|
+
@for (id of applyingPreset()!.config.appFeatures.disabled; track id) {
|
|
6461
|
+
<div class="diff-item">
|
|
6462
|
+
<span class="diff-item__name">{{ id }}</span>
|
|
6463
|
+
<span class="diff-item__arrow">→</span>
|
|
6464
|
+
<span class="diff-item__value diff-item__value--off">OFF</span>
|
|
6465
|
+
</div>
|
|
6466
|
+
}
|
|
6467
|
+
</div>
|
|
6468
|
+
}
|
|
6469
|
+
</div>
|
|
6470
|
+
}
|
|
6471
|
+
|
|
6472
|
+
<!-- Language -->
|
|
6473
|
+
@if (applyingPreset()!.config.language) {
|
|
6474
|
+
<div class="apply-category" [class.apply-category--disabled]="!applyLanguage()">
|
|
6475
|
+
<label class="apply-category__header">
|
|
6476
|
+
<input
|
|
6477
|
+
type="checkbox"
|
|
6478
|
+
[checked]="applyLanguage()"
|
|
6479
|
+
(change)="applyLanguage.set(!applyLanguage())"
|
|
6480
|
+
/>
|
|
6481
|
+
<span>Language</span>
|
|
6482
|
+
</label>
|
|
6483
|
+
@if (applyLanguage()) {
|
|
6484
|
+
<div class="apply-diff">
|
|
6485
|
+
<div class="diff-item">
|
|
6486
|
+
<span class="diff-item__name">Language</span>
|
|
6487
|
+
<span class="diff-item__arrow">→</span>
|
|
6488
|
+
<span class="diff-item__value">{{ applyingPreset()!.config.language }}</span>
|
|
6489
|
+
</div>
|
|
6490
|
+
</div>
|
|
6491
|
+
}
|
|
6492
|
+
</div>
|
|
6493
|
+
}
|
|
6494
|
+
</div>
|
|
6495
|
+
}
|
|
6496
|
+
|
|
6497
|
+
<div class="form-actions">
|
|
6498
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">Cancel</ngt-button>
|
|
6499
|
+
<ngt-button (click)="onConfirmPartialApply()">Apply Selected</ngt-button>
|
|
6500
|
+
</div>
|
|
6501
|
+
</div>
|
|
6502
|
+
}
|
|
6503
|
+
|
|
6504
|
+
<!-- Delete Confirmation View -->
|
|
6505
|
+
@if (viewMode() === 'delete') {
|
|
6506
|
+
<div class="delete-view">
|
|
6507
|
+
<div class="delete-view__content">
|
|
6508
|
+
<div class="delete-view__icon">🗑️</div>
|
|
6509
|
+
<h3 class="delete-view__title">Delete "{{ deletePresetName() }}"?</h3>
|
|
6510
|
+
<p class="delete-view__description">
|
|
6511
|
+
This preset will be permanently removed.
|
|
6512
|
+
This action cannot be undone.
|
|
6513
|
+
</p>
|
|
6514
|
+
</div>
|
|
6515
|
+
<div class="form-actions">
|
|
6516
|
+
<ngt-button type="button" (click)="onSwitchToListMode()">← Back</ngt-button>
|
|
6517
|
+
<button class="delete-button" (click)="onConfirmDelete()">Delete Preset</button>
|
|
6518
|
+
</div>
|
|
6519
|
+
</div>
|
|
6520
|
+
}
|
|
6521
|
+
|
|
5532
6522
|
<!-- Empty State -->
|
|
5533
6523
|
@if (viewMode() === 'list' && hasNoPresets()) {
|
|
5534
6524
|
<div class="empty">
|
|
@@ -5547,83 +6537,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
5547
6537
|
} @else if (viewMode() === 'list') {
|
|
5548
6538
|
<!-- Preset List -->
|
|
5549
6539
|
<div class="preset-list">
|
|
5550
|
-
@for (preset of
|
|
5551
|
-
<div class="preset-card">
|
|
6540
|
+
@for (preset of sortedPresets(); track preset.id) {
|
|
6541
|
+
<div class="preset-card" [title]="getPresetTooltip(preset)">
|
|
5552
6542
|
<div class="preset-card__header">
|
|
5553
|
-
<
|
|
6543
|
+
<button
|
|
6544
|
+
class="favorite-button"
|
|
6545
|
+
[class.favorite-button--active]="preset.isFavorite"
|
|
6546
|
+
(click)="onToggleFavorite(preset.id); $event.stopPropagation()"
|
|
6547
|
+
[attr.aria-label]="preset.isFavorite ? 'Remove from favorites' : 'Add to favorites'"
|
|
6548
|
+
>{{ preset.isFavorite ? '★' : '☆' }}</button>
|
|
6549
|
+
<span class="preset-card__name">{{ preset.name }}</span>
|
|
6550
|
+
@if (preset.isSystem) {<span class="system-badge">SYS</span>}
|
|
6551
|
+
<span class="preset-card__spacer"></span>
|
|
5554
6552
|
<div class="preset-card__actions">
|
|
5555
|
-
<button
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
>
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
class="icon-button"
|
|
5565
|
-
(click)="onUpdatePreset(preset.id)"
|
|
5566
|
-
[attr.aria-label]="'Update preset ' + preset.name"
|
|
5567
|
-
title="Update with current state"
|
|
5568
|
-
>
|
|
5569
|
-
<ngt-icon name="gear" />
|
|
5570
|
-
</button>
|
|
5571
|
-
<button
|
|
5572
|
-
class="icon-button"
|
|
5573
|
-
(click)="onExportPreset(preset.id)"
|
|
5574
|
-
[attr.aria-label]="'Export preset ' + preset.name"
|
|
5575
|
-
title="Export as JSON"
|
|
5576
|
-
>
|
|
5577
|
-
<ngt-icon name="export" />
|
|
5578
|
-
</button>
|
|
5579
|
-
<button
|
|
5580
|
-
class="icon-button"
|
|
5581
|
-
(click)="onDeletePreset(preset.id)"
|
|
5582
|
-
[attr.aria-label]="'Delete preset ' + preset.name"
|
|
5583
|
-
title="Delete preset"
|
|
5584
|
-
>
|
|
5585
|
-
<ngt-icon name="trash" />
|
|
5586
|
-
</button>
|
|
6553
|
+
<button class="icon-button" (click)="onStartApply(preset.id)"><ngt-icon name="refresh" /></button>
|
|
6554
|
+
@if (!preset.isSystem) {
|
|
6555
|
+
<button class="icon-button" (click)="onStartEdit(preset.id)"><ngt-icon name="edit" /></button>
|
|
6556
|
+
<button class="icon-button" (click)="onUpdatePreset(preset.id)"><ngt-icon name="gear" /></button>
|
|
6557
|
+
}
|
|
6558
|
+
<button class="icon-button" (click)="onExportPreset(preset.id)"><ngt-icon name="export" /></button>
|
|
6559
|
+
@if (!preset.isSystem) {
|
|
6560
|
+
<button class="icon-button" (click)="onDeletePreset(preset.id)"><ngt-icon name="trash" /></button>
|
|
6561
|
+
}
|
|
5587
6562
|
</div>
|
|
5588
6563
|
</div>
|
|
5589
6564
|
@if (preset.description) {
|
|
5590
|
-
<
|
|
5591
|
-
|
|
5592
|
-
<div class="preset-card__meta">
|
|
5593
|
-
<span>Updated: {{ formatDate(preset.updatedAt) }}</span>
|
|
6565
|
+
<div class="preset-card__row preset-card__row--meta">
|
|
6566
|
+
<span class="preset-card__description">{{ preset.description }}</span>
|
|
5594
6567
|
</div>
|
|
5595
|
-
|
|
5596
|
-
<div class="preset-
|
|
5597
|
-
@if (preset.config.featureFlags.enabled.length > 0 ||
|
|
5598
|
-
preset.config.featureFlags.disabled.length >
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
preset.config.featureFlags.disabled.length
|
|
5603
|
-
}}
|
|
5604
|
-
flags
|
|
5605
|
-
</span>
|
|
5606
|
-
} @if (preset.config.permissions.granted.length > 0 ||
|
|
5607
|
-
preset.config.permissions.denied.length > 0) {
|
|
5608
|
-
<span class="badge">
|
|
5609
|
-
{{
|
|
5610
|
-
preset.config.permissions.granted.length +
|
|
5611
|
-
preset.config.permissions.denied.length
|
|
5612
|
-
}}
|
|
5613
|
-
perms
|
|
5614
|
-
</span>
|
|
5615
|
-
} @if (preset.config.appFeatures.enabled.length > 0 ||
|
|
5616
|
-
preset.config.appFeatures.disabled.length > 0) {
|
|
5617
|
-
<span class="badge">
|
|
5618
|
-
{{
|
|
5619
|
-
preset.config.appFeatures.enabled.length +
|
|
5620
|
-
preset.config.appFeatures.disabled.length
|
|
5621
|
-
}}
|
|
5622
|
-
features
|
|
5623
|
-
</span>
|
|
5624
|
-
} @if (preset.config.language) {
|
|
5625
|
-
<span class="badge">{{ preset.config.language }}</span>
|
|
6568
|
+
}
|
|
6569
|
+
<div class="preset-card__row preset-card__row--badges">
|
|
6570
|
+
@if (preset.config.featureFlags.enabled.length > 0 || preset.config.featureFlags.disabled.length > 0) {
|
|
6571
|
+
<span class="badge">{{ preset.config.featureFlags.enabled.length + preset.config.featureFlags.disabled.length }} flags</span>
|
|
6572
|
+
}
|
|
6573
|
+
@if (preset.config.permissions.granted.length > 0 || preset.config.permissions.denied.length > 0) {
|
|
6574
|
+
<span class="badge">{{ preset.config.permissions.granted.length + preset.config.permissions.denied.length }} perms</span>
|
|
5626
6575
|
}
|
|
6576
|
+
@if (preset.config.appFeatures.enabled.length > 0 || preset.config.appFeatures.disabled.length > 0) {
|
|
6577
|
+
<span class="badge">{{ preset.config.appFeatures.enabled.length + preset.config.appFeatures.disabled.length }} features</span>
|
|
6578
|
+
}
|
|
6579
|
+
@if (preset.config.language) {
|
|
6580
|
+
<span class="badge badge--lang">{{ preset.config.language }}</span>
|
|
6581
|
+
}
|
|
6582
|
+
<span class="preset-card__date">{{ formatDate(preset.updatedAt) }}</span>
|
|
5627
6583
|
</div>
|
|
5628
6584
|
</div>
|
|
5629
6585
|
}
|
|
@@ -5631,8 +6587,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
5631
6587
|
}
|
|
5632
6588
|
</div>
|
|
5633
6589
|
</ngt-toolbar-tool>
|
|
5634
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-md);ngt-input{flex:1}ngt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ngt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ngt-border-subtle);border-radius:var(--ngt-border-radius-medium);padding:var(--ngt-spacing-md);background:transparent;color:var(--ngt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ngt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ngt-spacing-md);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ngt-spacing-sm);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ngt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ngt-border-primary);border-radius:4px;&:hover{background:var(--ngt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ngt-border-primary) var(--ngt-background-secondary)}.preset-card{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-sm)}.preset-card__header{display:flex;justify-content:space-between;align-items:center;gap:var(--ngt-spacing-sm);h3{margin:0;font-size:var(--ngt-font-size-md);color:var(--ngt-text-primary);flex:1}}.preset-card__actions{display:flex;gap:var(--ngt-spacing-xs)}.icon-button{background:transparent;border:none;cursor:pointer;padding:var(--ngt-spacing-xs);border-radius:var(--ngt-border-radius-small);color:var(--ngt-text-secondary);display:flex;align-items:center;justify-content:center;&:hover{background:var(--ngt-hover-bg);color:var(--ngt-text-primary)}ngt-icon{width:16px;height:16px}}.preset-card__description{margin:0;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-secondary)}.preset-card__meta{font-size:var(--ngt-font-size-xs);color:var(--ngt-text-muted);span{margin-right:var(--ngt-spacing-sm)}}.preset-card__preview{display:flex;gap:var(--ngt-spacing-xs);flex-wrap:wrap}.badge{background:var(--ngt-primary-color);color:#fff;padding:2px 8px;border-radius:12px;font-size:var(--ngt-font-size-xs);font-weight:500}.preset-form{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ngt-spacing-md);padding:var(--ngt-spacing-md);ngt-input{width:100%}}.preset-summary{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-sm);h4{margin:0;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-primary)}}.category-section{display:flex;flex-direction:column;gap:var(--ngt-spacing-xs)}.checkbox-option{display:flex;align-items:center;gap:var(--ngt-spacing-sm);cursor:pointer;color:var(--ngt-text-secondary);font-size:var(--ngt-font-size-sm);input[type=checkbox]{cursor:pointer;width:16px;height:16px;accent-color:var(--ngt-primary);&:disabled{cursor:not-allowed;opacity:.5}}&:has(input:disabled){opacity:.6;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 var(--ngt-spacing-lg);display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);font-size:var(--ngt-font-size-xs);li{background:rgba(var(--ngt-primary-rgb),.05);border-radius:var(--ngt-border-radius-small);border-left:2px solid rgba(var(--ngt-primary-rgb),.3)}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:var(--ngt-spacing-xs) var(--ngt-spacing-sm);cursor:pointer;gap:var(--ngt-spacing-sm);input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:var(--ngt-primary);flex-shrink:0}&:hover{background:rgba(var(--ngt-primary-rgb),.08)}}.item-name{color:var(--ngt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:2px 6px;border-radius:var(--ngt-border-radius-small);font-size:10px;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0;&.enabled{background:#22c55e26;color:#22c55e}&.disabled{background:#ef444426;color:#ef4444}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ngt-spacing-sm)}\n"] }]
|
|
5635
|
-
}] });
|
|
6590
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".container{position:relative;display:flex;flex-direction:column;height:100%;padding:0}.toast{position:absolute;bottom:var(--ngt-spacing-md);left:var(--ngt-spacing-md);right:var(--ngt-spacing-md);z-index:10;display:flex;align-items:center;gap:var(--ngt-spacing-sm);padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-small);font-size:var(--ngt-font-size-sm);animation:slideUp .15s ease-out}.toast--success{background:#22c55e;color:#fff}.toast--error{background:#ef4444;color:#fff}.toast__icon{font-weight:700}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.delete-view{flex:1;display:flex;flex-direction:column;justify-content:center;padding:var(--ngt-spacing-md)}.delete-view__content{text-align:center;padding:var(--ngt-spacing-lg) var(--ngt-spacing-md)}.delete-view__icon{font-size:48px;margin-bottom:var(--ngt-spacing-md)}.delete-view__title{margin:0 0 var(--ngt-spacing-sm);font-size:var(--ngt-font-size-md);color:var(--ngt-text-primary)}.delete-view__description{margin:0;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-secondary);line-height:1.5}.delete-button{background:#ef4444;color:#fff;border:none;padding:var(--ngt-spacing-sm) var(--ngt-spacing-md);border-radius:var(--ngt-border-radius-small);cursor:pointer;font-size:var(--ngt-font-size-sm);font-weight:500;transition:background .2s ease-out;&:hover{background:#dc2626}}.tool-header{position:relative;flex-shrink:0;display:flex;gap:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-md);ngt-input{flex:1}ngt-button{flex-shrink:0}}.empty{display:flex;flex-direction:column;gap:var(--ngt-spacing-md);flex:1;min-height:0;justify-content:center;align-items:center;border:1px solid var(--ngt-border-subtle);border-radius:var(--ngt-border-radius-medium);padding:var(--ngt-spacing-md);background:transparent;color:var(--ngt-text-muted);text-align:center;p{margin:0}.hint{font-size:var(--ngt-font-size-xs)}}.preset-list{display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);flex:1;min-height:0;overflow-y:auto;padding-right:var(--ngt-spacing-xs);&::-webkit-scrollbar{width:8px}&::-webkit-scrollbar-track{background:var(--ngt-background-secondary);border-radius:4px}&::-webkit-scrollbar-thumb{background:var(--ngt-border-primary);border-radius:4px;&:hover{background:var(--ngt-hover-bg)}}scrollbar-width:thin;scrollbar-color:var(--ngt-border-primary) var(--ngt-background-secondary)}.preset-card{background:var(--ngt-background-secondary);padding:6px var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:2px}.preset-card__header{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}.preset-card__row{display:flex;align-items:center;gap:6px;min-height:18px}.preset-card__row--meta{padding-left:18px}.preset-card__row--badges{padding-left:18px;gap:4px}.preset-card__name{font-size:var(--ngt-font-size-sm);font-weight:600;color:var(--ngt-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__spacer{flex:1;min-width:8px}.system-badge{font-size:8px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 4px;border-radius:3px;background:var(--ngt-border-primary);color:var(--ngt-text-muted);flex-shrink:0}.favorite-button{background:transparent;border:none;cursor:pointer;font-size:12px;color:var(--ngt-text-muted);padding:0;line-height:1;transition:color .15s ease-out;flex-shrink:0}.favorite-button:hover,.favorite-button--active{color:#f59e0b}.preset-card__actions{display:flex;gap:0;flex-shrink:0}.icon-button{appearance:none;background:none;border:none;cursor:pointer;margin:0;padding:4px;border-radius:4px;color:var(--ngt-text-muted);display:inline-flex;align-items:center;justify-content:center;opacity:.5;transition:opacity .15s ease-out,color .15s ease-out;line-height:0;&:hover{background:var(--ngt-hover-bg);color:var(--ngt-text-primary);opacity:1}ngt-icon,ngt-icon>*,svg{display:block;width:12px!important;height:12px!important}}.preset-card__description{font-size:11px;color:var(--ngt-text-secondary);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preset-card__date{font-size:10px;color:var(--ngt-text-muted);margin-left:auto;flex-shrink:0}.badge{background:#6366f126;color:#6366f1;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:500;white-space:nowrap}.badge--lang{background:#22c55e26;color:#22c55e}.preset-form,.import-view,.apply-view{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--ngt-spacing-sm);padding:var(--ngt-spacing-sm);ngt-input{width:100%}}.form-title{margin:0;font-size:var(--ngt-font-size-sm);font-weight:600;color:var(--ngt-text-primary)}.form-hint{margin:0;font-size:11px;color:var(--ngt-text-muted);line-height:1.3}.form-field{display:flex;flex-direction:column;gap:2px}.field-error{color:#ef4444;font-size:11px}.preset-summary{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ngt-text-secondary)}}.category-section{display:flex;flex-direction:column;gap:2px}.checkbox-option{display:flex;align-items:center;gap:var(--ngt-spacing-xs);cursor:pointer;color:var(--ngt-text-primary);font-size:var(--ngt-font-size-sm);padding:2px 0;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241);border-radius:3px;&:disabled{cursor:not-allowed;opacity:.4}}&:has(input:disabled){opacity:.5;cursor:not-allowed}}.forced-items-list{list-style:none;padding:0;margin:0 0 0 20px;display:flex;flex-direction:column;gap:2px;font-size:11px;max-height:100px;overflow-y:auto;li{background:#6366f10d;border-radius:3px;border-left:2px solid rgba(99,102,241,.3)}.item-checkbox{display:flex;justify-content:space-between;align-items:center;padding:3px 6px;cursor:pointer;gap:6px;input[type=checkbox]{cursor:pointer;width:12px;height:12px;accent-color:rgb(99,102,241);flex-shrink:0}&:hover{background:#6366f114}}.item-name{color:var(--ngt-text-primary);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-status{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0;&.enabled{background:#22c55e26;color:#22c55e}&.disabled{background:#ef444426;color:#ef4444}}}.form-actions{display:flex;justify-content:flex-end;gap:var(--ngt-spacing-sm);margin-top:auto;padding-top:var(--ngt-spacing-sm)}.config-preview{background:var(--ngt-background-secondary);padding:var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-medium);display:flex;flex-direction:column;gap:var(--ngt-spacing-xs);h4{margin:0;font-size:11px;font-weight:500;color:var(--ngt-text-secondary)}}.config-category{display:flex;flex-direction:column;gap:2px}.config-category__title{font-size:10px;color:var(--ngt-text-muted);font-weight:500}.config-items{display:flex;flex-wrap:wrap;gap:4px}.config-item{font-size:10px;padding:1px 6px;border-radius:3px;background:var(--ngt-background-primary);color:var(--ngt-text-secondary)}.config-item--on{background:#22c55e1a;color:#22c55e}.config-item--off{background:#ef44441a;color:#ef4444}.replace-config-button{background:transparent;border:1px dashed var(--ngt-border-primary);padding:6px var(--ngt-spacing-sm);border-radius:var(--ngt-border-radius-small);color:var(--ngt-text-secondary);cursor:pointer;font-size:11px;transition:all .15s ease-out;&:hover{background:var(--ngt-hover-bg);border-color:#6366f1;color:#6366f1}}.drop-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:var(--ngt-spacing-md);border:2px dashed var(--ngt-border-primary);border-radius:var(--ngt-border-radius-medium);cursor:pointer;transition:all .15s ease-out}.drop-zone:hover,.drop-zone--active{border-color:#6366f1;background:#6366f10d}.drop-zone__icon{font-size:24px}.drop-zone__text{font-size:var(--ngt-font-size-sm);color:var(--ngt-text-primary)}.drop-zone__hint{font-size:11px;color:var(--ngt-text-muted)}.divider{display:flex;align-items:center;gap:var(--ngt-spacing-sm);color:var(--ngt-text-muted);font-size:10px;&:before,&:after{content:\"\";flex:1;height:1px;background:var(--ngt-border-primary)}}.json-textarea{width:100%;min-height:80px;padding:var(--ngt-spacing-xs);border:1px solid var(--ngt-border-primary);border-radius:var(--ngt-border-radius-small);background:var(--ngt-background-secondary);color:var(--ngt-text-primary);font-family:monospace;font-size:11px;resize:vertical;&:focus{outline:none;border-color:#6366f1}&::placeholder{color:var(--ngt-text-muted)}}.apply-description{margin:0;font-size:11px;color:var(--ngt-text-secondary)}.apply-categories{display:flex;flex-direction:column;gap:var(--ngt-spacing-xs)}.apply-category{background:var(--ngt-background-secondary);border-radius:var(--ngt-border-radius-small);overflow:hidden;transition:opacity .15s ease-out}.apply-category--disabled{opacity:.5}.apply-category__header{display:flex;align-items:center;gap:var(--ngt-spacing-xs);padding:6px var(--ngt-spacing-sm);cursor:pointer;font-size:var(--ngt-font-size-sm);color:var(--ngt-text-primary);font-weight:500;input[type=checkbox]{cursor:pointer;width:14px;height:14px;accent-color:rgb(99,102,241)}}.apply-diff{padding:0 var(--ngt-spacing-sm) 6px;display:flex;flex-direction:column;gap:2px}.diff-item{display:flex;align-items:center;gap:6px;font-size:11px;padding:3px 6px;background:var(--ngt-background-primary);border-radius:3px}.diff-item__name{flex:1;color:var(--ngt-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.diff-item__arrow{color:var(--ngt-text-muted);font-size:10px}.diff-item__value{font-weight:600;padding:1px 4px;border-radius:3px;font-size:9px;text-transform:uppercase;letter-spacing:.3px}.diff-item__value--on{background:#22c55e26;color:#22c55e}.diff-item__value--off{background:#ef444426;color:#ef4444}\n"] }]
|
|
6591
|
+
}], ctorParameters: () => [] });
|
|
5636
6592
|
|
|
5637
6593
|
class ToolbarComponent {
|
|
5638
6594
|
constructor() {
|
|
@@ -5934,6 +6890,68 @@ function initToolbar(appRef, options) {
|
|
|
5934
6890
|
};
|
|
5935
6891
|
}
|
|
5936
6892
|
|
|
6893
|
+
class ToolbarStepDirective {
|
|
6894
|
+
constructor() {
|
|
6895
|
+
this.ngtStep = input.required();
|
|
6896
|
+
this.stepTitle = input('');
|
|
6897
|
+
this.templateRef = inject(TemplateRef);
|
|
6898
|
+
}
|
|
6899
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarStepDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
6900
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.7", type: ToolbarStepDirective, isStandalone: true, selector: "[ngtStep]", inputs: { ngtStep: { classPropertyName: "ngtStep", publicName: "ngtStep", isSignal: true, isRequired: true, transformFunction: null }, stepTitle: { classPropertyName: "stepTitle", publicName: "stepTitle", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
6901
|
+
}
|
|
6902
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarStepDirective, decorators: [{
|
|
6903
|
+
type: Directive,
|
|
6904
|
+
args: [{
|
|
6905
|
+
selector: '[ngtStep]',
|
|
6906
|
+
standalone: true,
|
|
6907
|
+
}]
|
|
6908
|
+
}] });
|
|
6909
|
+
|
|
6910
|
+
class ToolbarStepViewComponent {
|
|
6911
|
+
constructor() {
|
|
6912
|
+
this.currentStep = input.required();
|
|
6913
|
+
this.defaultStep = input('list');
|
|
6914
|
+
this.back = output();
|
|
6915
|
+
this.steps = contentChildren(ToolbarStepDirective);
|
|
6916
|
+
this.isDefaultStep = computed(() => this.currentStep() === this.defaultStep());
|
|
6917
|
+
this.activeStep = computed(() => this.steps().find((s) => s.ngtStep() === this.currentStep()));
|
|
6918
|
+
this.activeTitle = computed(() => this.activeStep()?.stepTitle() ?? '');
|
|
6919
|
+
this.activeTemplate = computed(() => this.activeStep()?.templateRef ?? null);
|
|
6920
|
+
}
|
|
6921
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarStepViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6922
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.7", type: ToolbarStepViewComponent, isStandalone: true, selector: "ngt-step-view", inputs: { currentStep: { classPropertyName: "currentStep", publicName: "currentStep", isSignal: true, isRequired: true, transformFunction: null }, defaultStep: { classPropertyName: "defaultStep", publicName: "defaultStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { back: "back" }, queries: [{ propertyName: "steps", predicate: ToolbarStepDirective, isSignal: true }], ngImport: i0, template: `
|
|
6923
|
+
@if (!isDefaultStep()) {
|
|
6924
|
+
<div class="step-header">
|
|
6925
|
+
<ngt-button (click)="back.emit()" ariaLabel="Back">\u2190 Back</ngt-button>
|
|
6926
|
+
@if (activeTitle()) {
|
|
6927
|
+
<span class="step-title">{{ activeTitle() }}</span>
|
|
6928
|
+
}
|
|
6929
|
+
</div>
|
|
6930
|
+
}
|
|
6931
|
+
|
|
6932
|
+
@if (activeTemplate(); as tmpl) {
|
|
6933
|
+
<ng-container [ngTemplateOutlet]="tmpl" />
|
|
6934
|
+
}
|
|
6935
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column}.step-header{display:flex;align-items:center;gap:var(--ngt-spacing-sm);padding-bottom:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);border-bottom:1px solid var(--ngt-border-primary)}.step-title{font-size:var(--ngt-font-size-md);font-weight:600;color:var(--ngt-text-primary)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ToolbarButtonComponent, selector: "ngt-button", inputs: ["type", "variant", "icon", "label", "ariaLabel", "isActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6936
|
+
}
|
|
6937
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImport: i0, type: ToolbarStepViewComponent, decorators: [{
|
|
6938
|
+
type: Component,
|
|
6939
|
+
args: [{ selector: 'ngt-step-view', standalone: true, imports: [NgTemplateOutlet, ToolbarButtonComponent], template: `
|
|
6940
|
+
@if (!isDefaultStep()) {
|
|
6941
|
+
<div class="step-header">
|
|
6942
|
+
<ngt-button (click)="back.emit()" ariaLabel="Back">\u2190 Back</ngt-button>
|
|
6943
|
+
@if (activeTitle()) {
|
|
6944
|
+
<span class="step-title">{{ activeTitle() }}</span>
|
|
6945
|
+
}
|
|
6946
|
+
</div>
|
|
6947
|
+
}
|
|
6948
|
+
|
|
6949
|
+
@if (activeTemplate(); as tmpl) {
|
|
6950
|
+
<ng-container [ngTemplateOutlet]="tmpl" />
|
|
6951
|
+
}
|
|
6952
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;flex-direction:column}.step-header{display:flex;align-items:center;gap:var(--ngt-spacing-sm);padding-bottom:var(--ngt-spacing-sm);margin-bottom:var(--ngt-spacing-sm);border-bottom:1px solid var(--ngt-border-primary)}.step-title{font-size:var(--ngt-font-size-md);font-weight:600;color:var(--ngt-text-primary)}\n"] }]
|
|
6953
|
+
}] });
|
|
6954
|
+
|
|
5937
6955
|
/**
|
|
5938
6956
|
* Public service for managing dev toolbar presets.
|
|
5939
6957
|
* Allows developers to programmatically save, load, and manage presets.
|
|
@@ -5978,6 +6996,30 @@ class ToolbarPresetsService {
|
|
|
5978
6996
|
deletePreset(presetId) {
|
|
5979
6997
|
this.internalService.deletePreset(presetId);
|
|
5980
6998
|
}
|
|
6999
|
+
/**
|
|
7000
|
+
* Toggle favorite status for a preset
|
|
7001
|
+
* @param presetId - ID of the preset to toggle
|
|
7002
|
+
*/
|
|
7003
|
+
toggleFavorite(presetId) {
|
|
7004
|
+
this.internalService.toggleFavorite(presetId);
|
|
7005
|
+
}
|
|
7006
|
+
/**
|
|
7007
|
+
* Apply a preset with partial options (only selected categories)
|
|
7008
|
+
* @param presetId - ID of the preset to apply
|
|
7009
|
+
* @param options - Options for which categories to apply
|
|
7010
|
+
*/
|
|
7011
|
+
async partialApplyPreset(presetId, options) {
|
|
7012
|
+
return this.internalService.partialApplyPreset(presetId, options);
|
|
7013
|
+
}
|
|
7014
|
+
/**
|
|
7015
|
+
* Update only the metadata (name, description) of a preset
|
|
7016
|
+
* @param presetId - ID of the preset to update
|
|
7017
|
+
* @param name - New name for the preset
|
|
7018
|
+
* @param description - New description for the preset
|
|
7019
|
+
*/
|
|
7020
|
+
updatePresetMetadata(presetId, name, description) {
|
|
7021
|
+
this.internalService.updatePresetMetadata(presetId, name, description);
|
|
7022
|
+
}
|
|
5981
7023
|
/**
|
|
5982
7024
|
* Export a preset as JSON string
|
|
5983
7025
|
* @param presetId - ID of the preset to export
|
|
@@ -6002,9 +7044,10 @@ class ToolbarPresetsService {
|
|
|
6002
7044
|
/**
|
|
6003
7045
|
* Initialize presets with predefined configurations.
|
|
6004
7046
|
* Useful for setting up default presets that all developers can use.
|
|
7047
|
+
* Skips presets that already exist (by name) to avoid duplicates.
|
|
6005
7048
|
*
|
|
6006
7049
|
* @param presets - Array of preset configurations to initialize
|
|
6007
|
-
* @returns Array of created presets
|
|
7050
|
+
* @returns Array of created presets (only newly added ones)
|
|
6008
7051
|
*
|
|
6009
7052
|
* @example
|
|
6010
7053
|
* ```typescript
|
|
@@ -6053,10 +7096,15 @@ class ToolbarPresetsService {
|
|
|
6053
7096
|
* ```
|
|
6054
7097
|
*/
|
|
6055
7098
|
initializePresets(presets) {
|
|
6056
|
-
|
|
7099
|
+
const existingPresets = this.internalService.presets();
|
|
7100
|
+
const existingNames = new Set(existingPresets.map((p) => p.name.toLowerCase()));
|
|
7101
|
+
return presets
|
|
7102
|
+
.filter((preset) => !existingNames.has(preset.name.toLowerCase()))
|
|
7103
|
+
.map((preset) => this.internalService.addPreset({
|
|
6057
7104
|
id: '', // Will be generated
|
|
6058
7105
|
createdAt: '', // Will be generated
|
|
6059
7106
|
updatedAt: '', // Will be generated
|
|
7107
|
+
isSystem: true, // Mark as system preset (not editable)
|
|
6060
7108
|
...preset,
|
|
6061
7109
|
}));
|
|
6062
7110
|
}
|
|
@@ -6085,36 +7133,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.7", ngImpor
|
|
|
6085
7133
|
}] });
|
|
6086
7134
|
|
|
6087
7135
|
// Tree-shakeable tokens for dependency injection
|
|
6088
|
-
/** @deprecated Use TOOLBAR_FEATURE_FLAGS instead. Will be removed in v4.0 */
|
|
6089
|
-
const DEV_TOOLBAR_FEATURE_FLAGS = TOOLBAR_FEATURE_FLAGS;
|
|
6090
|
-
/** @deprecated Use TOOLBAR_PERMISSIONS instead. Will be removed in v4.0 */
|
|
6091
|
-
const DEV_TOOLBAR_PERMISSIONS = TOOLBAR_PERMISSIONS;
|
|
6092
|
-
/** @deprecated Use TOOLBAR_LANGUAGE instead. Will be removed in v4.0 */
|
|
6093
|
-
const DEV_TOOLBAR_LANGUAGE = TOOLBAR_LANGUAGE;
|
|
6094
|
-
/** @deprecated Use TOOLBAR_APP_FEATURES instead. Will be removed in v4.0 */
|
|
6095
|
-
const DEV_TOOLBAR_APP_FEATURES = TOOLBAR_APP_FEATURES;
|
|
6096
|
-
/** @deprecated Use provideToolbar instead. Will be removed in v4.0 */
|
|
6097
|
-
const provideDevToolbar = provideToolbar;
|
|
6098
|
-
/** @deprecated Use initToolbar instead. Will be removed in v4.0 */
|
|
6099
|
-
const initDevToolbar = initToolbar;
|
|
6100
|
-
/** @deprecated Use ToolbarComponent instead. Will be removed in v4.0 */
|
|
6101
|
-
const DevToolbarComponent = ToolbarComponent;
|
|
6102
|
-
/** @deprecated Use ToolbarToolComponent instead. Will be removed in v4.0 */
|
|
6103
|
-
const DevToolbarToolComponent = ToolbarToolComponent;
|
|
6104
|
-
/** @deprecated Use ToolbarFeatureFlagService instead. Will be removed in v4.0 */
|
|
6105
|
-
const DevToolbarFeatureFlagService = ToolbarFeatureFlagService;
|
|
6106
|
-
/** @deprecated Use ToolbarLanguageService instead. Will be removed in v4.0 */
|
|
6107
|
-
const DevToolbarLanguageService = ToolbarLanguageService;
|
|
6108
|
-
/** @deprecated Use ToolbarAppFeaturesService instead. Will be removed in v4.0 */
|
|
6109
|
-
const DevToolbarAppFeaturesService = ToolbarAppFeaturesService;
|
|
6110
|
-
/** @deprecated Use ToolbarPermissionsService instead. Will be removed in v4.0 */
|
|
6111
|
-
const DevToolbarPermissionsService = ToolbarPermissionsService;
|
|
6112
|
-
/** @deprecated Use ToolbarPresetsService instead. Will be removed in v4.0 */
|
|
6113
|
-
const DevToolbarPresetsService = ToolbarPresetsService;
|
|
6114
7136
|
|
|
6115
7137
|
/**
|
|
6116
7138
|
* Generated bundle index. Do not edit.
|
|
6117
7139
|
*/
|
|
6118
7140
|
|
|
6119
|
-
export {
|
|
7141
|
+
export { TOOLBAR_APP_FEATURES, TOOLBAR_FEATURE_FLAGS, TOOLBAR_LANGUAGE, TOOLBAR_PERMISSIONS, ToolbarAppFeaturesService, ToolbarAppFeaturesToolComponent, ToolbarButtonComponent, ToolbarCardComponent, ToolbarClickableCardComponent, ToolbarComponent, ToolbarFeatureFlagService, ToolbarIconComponent, ToolbarInputComponent, ToolbarLanguageService, ToolbarLinkButtonComponent, ToolbarListComponent, ToolbarListItemComponent, ToolbarPermissionsService, ToolbarPermissionsToolComponent, ToolbarPresetsService, ToolbarPresetsToolComponent, ToolbarSelectComponent, ToolbarStepDirective, ToolbarStepViewComponent, ToolbarToolComponent, initToolbar, provideToolbar };
|
|
6120
7142
|
//# sourceMappingURL=ngx-dev-toolbar.mjs.map
|