@elasticias/ui 1.0.39 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/elasticias-ui.mjs +126 -49
- package/fesm2022/elasticias-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/elasticias-ui.d.ts +53 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Pipe, input, Component, output, booleanAttribute, Input, Directive, signal, computed, inject, EventEmitter, Injector, forwardRef, Output, ContentChild, HostBinding, ChangeDetectionStrategy, ElementRef, LOCALE_ID, ViewContainerRef, DestroyRef, ChangeDetectorRef, effect, HostListener, ViewChild, model, InjectionToken, TemplateRef, ContentChildren, viewChild, contentChild, ViewEncapsulation, afterNextRender, ViewChildren, untracked, PLATFORM_ID } from '@angular/core';
|
|
3
|
-
import { NumberUtils, UuidUtils
|
|
3
|
+
import { NumberUtils, UuidUtils } from '@elasticias/utils';
|
|
4
4
|
import * as i1 from 'primeng/button';
|
|
5
5
|
import { ButtonModule } from 'primeng/button';
|
|
6
6
|
import * as i1$3 from '@angular/common';
|
|
@@ -22,7 +22,7 @@ import * as i1$6 from 'primeng/dialog';
|
|
|
22
22
|
import { DialogModule } from 'primeng/dialog';
|
|
23
23
|
import { SCREEN_REF_DATA_SERVICE, ScreenStateEnum } from '@elasticias/screens';
|
|
24
24
|
import { Permissions } from '@elasticias/types';
|
|
25
|
-
import { EfShortcutService, EfViewportService, formatShortcut, EfThemeConfigService, EF_BUILD_INFO, EfPermissionService, EfActiveModuleService, EF_SESSION, EfToastService } from '@elasticias/core';
|
|
25
|
+
import { EfShortcutService, EfViewportService, EF_PREFERENCE_STORE, formatShortcut, efTablePrefsKey, EfThemeConfigService, EF_BUILD_INFO, EfPermissionService, EfActiveModuleService, EF_SESSION, EF_SIDE_COLLAPSED_KEY, EfToastService } from '@elasticias/core';
|
|
26
26
|
import * as i1$7 from 'primeng/fieldset';
|
|
27
27
|
import { FieldsetModule } from 'primeng/fieldset';
|
|
28
28
|
import * as i2$2 from 'primeng/accordion';
|
|
@@ -570,6 +570,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
570
570
|
args: [{ transform: booleanAttribute }]
|
|
571
571
|
}] } });
|
|
572
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Scopes a read-only state to every descendant `ef-*` form control.
|
|
575
|
+
*
|
|
576
|
+
* Drop it on the container that wraps a form and bind whether the current
|
|
577
|
+
* user lacks write access; descendant controls fold it into their effective
|
|
578
|
+
* disabled state, so no per-field `[disabled]` binding is needed:
|
|
579
|
+
*
|
|
580
|
+
* ```html
|
|
581
|
+
* <div class="detail-grid" [efReadOnly]="!canWrite()">
|
|
582
|
+
* <ef-input-text name="companyName" ... />
|
|
583
|
+
* <ef-select name="clientType" ... />
|
|
584
|
+
* </div>
|
|
585
|
+
* ```
|
|
586
|
+
*
|
|
587
|
+
* The input is a signal, so toggling it re-enables the controls under
|
|
588
|
+
* zoneless change detection (controls read it through `isDisabled`).
|
|
589
|
+
*/
|
|
590
|
+
class EfReadOnlyDirective {
|
|
591
|
+
/** When true, every descendant ef-* control renders disabled. */
|
|
592
|
+
readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), alias: 'efReadOnly', transform: booleanAttribute });
|
|
593
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfReadOnlyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
594
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.11", type: EfReadOnlyDirective, isStandalone: true, selector: "[efReadOnly]", inputs: { readOnly: { classPropertyName: "readOnly", publicName: "efReadOnly", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
595
|
+
}
|
|
596
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfReadOnlyDirective, decorators: [{
|
|
597
|
+
type: Directive,
|
|
598
|
+
args: [{
|
|
599
|
+
selector: '[efReadOnly]',
|
|
600
|
+
standalone: true,
|
|
601
|
+
}]
|
|
602
|
+
}], propDecorators: { readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "efReadOnly", required: false }] }] } });
|
|
603
|
+
|
|
573
604
|
/**
|
|
574
605
|
* Scopes a map of server/validation errors to its descendant `ef-*` form
|
|
575
606
|
* controls, which auto-link by their `name` — no per-field `[errors]`
|
|
@@ -702,14 +733,16 @@ class AbstractEfFormControl {
|
|
|
702
733
|
required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
703
734
|
readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
704
735
|
/** The `[disabled]` input. The **effective** disabled (input OR
|
|
705
|
-
* form-driven via CVA) is {@link isDisabled} — bind that in templates. */
|
|
736
|
+
* form-driven via CVA, or an enclosing `[efReadOnly]` scope) is {@link isDisabled} — bind that in templates. */
|
|
706
737
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
707
738
|
/** Form-driven disabled set by CVA `setDisabledState`, merged with the
|
|
708
739
|
* `[disabled]` input. Writable signal (the input itself is read-only). */
|
|
709
740
|
_cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
710
741
|
/** Effective disabled state — the `[disabled]` input OR a reactive-form
|
|
711
742
|
* `disable()`. Templates/logic should use this, not `disabled()`. */
|
|
712
|
-
isDisabled = computed(() => this.disabled() || this._cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
743
|
+
isDisabled = computed(() => this.disabled() || this._cvaDisabled() || (this.readOnlyScope?.readOnly() ?? false), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
744
|
+
/** Optional enclosing `[efReadOnly]` scope — disables the control when set. */
|
|
745
|
+
readOnlyScope = inject(EfReadOnlyDirective, { optional: true });
|
|
713
746
|
/** CVA hook for subclasses: `setDisabledState(d) { this.updateDisabledState(d); }`. */
|
|
714
747
|
updateDisabledState(disabled) {
|
|
715
748
|
this._cvaDisabled.set(disabled);
|
|
@@ -2604,6 +2637,12 @@ class EfQuantityStepperComponent {
|
|
|
2604
2637
|
* When present, it specifies that the component should be disabled
|
|
2605
2638
|
*/
|
|
2606
2639
|
disabled = false;
|
|
2640
|
+
/** Optional enclosing `[efReadOnly]` scope. */
|
|
2641
|
+
readOnlyScope = inject(EfReadOnlyDirective, { optional: true });
|
|
2642
|
+
/** Effective disabled: the input / CVA state OR a read-only scope. */
|
|
2643
|
+
get isDisabled() {
|
|
2644
|
+
return this.disabled || (this.readOnlyScope?.readOnly() ?? false);
|
|
2645
|
+
}
|
|
2607
2646
|
/**
|
|
2608
2647
|
* Callback to invoke when the value changes
|
|
2609
2648
|
*/
|
|
@@ -2675,7 +2714,7 @@ class EfQuantityStepperComponent {
|
|
|
2675
2714
|
useExisting: forwardRef(() => EfQuantityStepperComponent),
|
|
2676
2715
|
multi: true,
|
|
2677
2716
|
},
|
|
2678
|
-
], ngImport: i0, template: "<div\n class=\"flex h-12 items-center text-center justify-center gap-2 rounded-full !border !border-gray-200 bg-gray-100 dark:bg-slate-500 p-2\"\n>\n <ef-inputnumber\n [(ngModel)]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\"\n [minFractionDigits]=\"minFractionDigits\"\n [maxFractionDigits]=\"maxFractionDigits\"\n [locale]=\"locale\"\n [disabled]=\"
|
|
2717
|
+
], ngImport: i0, template: "<div\n class=\"flex h-12 items-center text-center justify-center gap-2 rounded-full !border !border-gray-200 bg-gray-100 dark:bg-slate-500 p-2\"\n>\n <ef-inputnumber\n [(ngModel)]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\"\n [minFractionDigits]=\"minFractionDigits\"\n [maxFractionDigits]=\"maxFractionDigits\"\n [locale]=\"locale\"\n [disabled]=\"isDisabled\"\n [showButtons]=\"true\"\n buttonLayout=\"horizontal\"\n decrementButtonIcon=\"-\"\n incrementButtonIcon=\"+\"\n [pt]=\"ptConfig\"\n (ngModelChange)=\"handleValueChange($event)\"\n (blurEvent)=\"handleBlur()\"\n >\n </ef-inputnumber>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: EfInputNumberComponent, selector: "ef-inputnumber", inputs: ["value", "invalid", "format", "showButtons", "buttonLayout", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "prefix", "suffix", "currency", "currencyDisplay", "locale", "localeMatcher", "mode", "useGrouping", "minFractionDigits", "maxFractionDigits", "min", "max", "step", "allowEmpty", "inputSize", "size", "maxlength", "minlength", "pattern", "tabindex", "title", "ariaLabelledBy", "inputStyle", "inputStyleClass", "style", "styleClass", "primeNgVariant", "autofocus", "autocomplete", "fluid", "inline", "variant", "pt", "ptOptions", "dt", "unstyled"], outputs: ["inputEvent", "valueChangeEvent", "focusEvent", "blurEvent", "keyDownEvent", "clearEvent"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2679
2718
|
}
|
|
2680
2719
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfQuantityStepperComponent, decorators: [{
|
|
2681
2720
|
type: Component,
|
|
@@ -2685,7 +2724,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
2685
2724
|
useExisting: forwardRef(() => EfQuantityStepperComponent),
|
|
2686
2725
|
multi: true,
|
|
2687
2726
|
},
|
|
2688
|
-
], template: "<div\n class=\"flex h-12 items-center text-center justify-center gap-2 rounded-full !border !border-gray-200 bg-gray-100 dark:bg-slate-500 p-2\"\n>\n <ef-inputnumber\n [(ngModel)]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\"\n [minFractionDigits]=\"minFractionDigits\"\n [maxFractionDigits]=\"maxFractionDigits\"\n [locale]=\"locale\"\n [disabled]=\"
|
|
2727
|
+
], template: "<div\n class=\"flex h-12 items-center text-center justify-center gap-2 rounded-full !border !border-gray-200 bg-gray-100 dark:bg-slate-500 p-2\"\n>\n <ef-inputnumber\n [(ngModel)]=\"value\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\"\n [minFractionDigits]=\"minFractionDigits\"\n [maxFractionDigits]=\"maxFractionDigits\"\n [locale]=\"locale\"\n [disabled]=\"isDisabled\"\n [showButtons]=\"true\"\n buttonLayout=\"horizontal\"\n decrementButtonIcon=\"-\"\n incrementButtonIcon=\"+\"\n [pt]=\"ptConfig\"\n (ngModelChange)=\"handleValueChange($event)\"\n (blurEvent)=\"handleBlur()\"\n >\n </ef-inputnumber>\n</div>\n" }]
|
|
2689
2728
|
}], propDecorators: { value: [{
|
|
2690
2729
|
type: Input
|
|
2691
2730
|
}], min: [{
|
|
@@ -4280,8 +4319,12 @@ class EfRowActionsComponent {
|
|
|
4280
4319
|
return true;
|
|
4281
4320
|
if (action.visible === false)
|
|
4282
4321
|
return false;
|
|
4283
|
-
if (action.permission && ctx
|
|
4284
|
-
|
|
4322
|
+
if (action.permission && ctx) {
|
|
4323
|
+
// Array.isArray does not narrow a ReadonlyArray out of the union.
|
|
4324
|
+
const required = typeof action.permission === 'string' ? [action.permission] : action.permission;
|
|
4325
|
+
if (!required.every(p => ctx.isGranted(p)))
|
|
4326
|
+
return false;
|
|
4327
|
+
}
|
|
4285
4328
|
return true;
|
|
4286
4329
|
}
|
|
4287
4330
|
/** Stable trackBy across renders. */
|
|
@@ -4528,6 +4571,7 @@ class EfDataCardComponent {
|
|
|
4528
4571
|
become a list instead, driven by the same column config —
|
|
4529
4572
|
each column declares (or is given) a role. */
|
|
4530
4573
|
viewport = inject(EfViewportService);
|
|
4574
|
+
prefs = inject(EF_PREFERENCE_STORE);
|
|
4531
4575
|
configuredMobileLayout = inject(EF_DATA_CARD_MOBILE_LAYOUT, { optional: true });
|
|
4532
4576
|
isMobile = this.viewport.isMobile;
|
|
4533
4577
|
/** Per-screen override of the app-wide default. */
|
|
@@ -4881,7 +4925,10 @@ class EfDataCardComponent {
|
|
|
4881
4925
|
labelKey: 'common_duplicate',
|
|
4882
4926
|
icon: 'pi pi-copy',
|
|
4883
4927
|
kbd: formatShortcut('mod+d'),
|
|
4884
|
-
|
|
4928
|
+
// Saved through create: without Create the row would open
|
|
4929
|
+
// a duplicate form the user cannot save. Hiding the item
|
|
4930
|
+
// also disarms mod+d, which only runs visible items.
|
|
4931
|
+
permission: [Permissions.Duplicate, Permissions.Create],
|
|
4885
4932
|
command: () => this.rowAction.emit({ action: 'duplicate', row }),
|
|
4886
4933
|
});
|
|
4887
4934
|
}
|
|
@@ -5145,14 +5192,17 @@ class EfDataCardComponent {
|
|
|
5145
5192
|
}
|
|
5146
5193
|
storageKey() {
|
|
5147
5194
|
const key = this.tableKey();
|
|
5148
|
-
return key ?
|
|
5195
|
+
return key ? efTablePrefsKey(key) : null;
|
|
5149
5196
|
}
|
|
5150
5197
|
loadPreferences() {
|
|
5151
5198
|
const key = this.storageKey();
|
|
5152
5199
|
if (!key)
|
|
5153
5200
|
return;
|
|
5154
5201
|
try {
|
|
5155
|
-
const
|
|
5202
|
+
const raw = this.prefs.get(key);
|
|
5203
|
+
if (!raw)
|
|
5204
|
+
return;
|
|
5205
|
+
const saved = JSON.parse(raw);
|
|
5156
5206
|
if (!saved)
|
|
5157
5207
|
return;
|
|
5158
5208
|
if (saved.density)
|
|
@@ -5170,10 +5220,10 @@ class EfDataCardComponent {
|
|
|
5170
5220
|
if (!key)
|
|
5171
5221
|
return;
|
|
5172
5222
|
try {
|
|
5173
|
-
|
|
5223
|
+
this.prefs.set(key, JSON.stringify({
|
|
5174
5224
|
density: this.density(),
|
|
5175
5225
|
hiddenColumnIds: this.hiddenColumnIds(),
|
|
5176
|
-
});
|
|
5226
|
+
}));
|
|
5177
5227
|
}
|
|
5178
5228
|
catch {
|
|
5179
5229
|
// Preferences are a convenience; losing them must never break
|
|
@@ -7273,7 +7323,8 @@ class EfModuleSideComponent {
|
|
|
7273
7323
|
return m.navSections
|
|
7274
7324
|
.map(section => ({
|
|
7275
7325
|
...section,
|
|
7276
|
-
items: section.items.filter(item => this.perms.can(m.id, item.requiredAction ?? 'read')
|
|
7326
|
+
items: section.items.filter(item => this.perms.can(m.id, item.requiredAction ?? 'read') &&
|
|
7327
|
+
(!item.screenCode || this.perms.canScreen(item.screenCode))),
|
|
7277
7328
|
}))
|
|
7278
7329
|
.filter(section => section.items.length > 0);
|
|
7279
7330
|
}, ...(ngDevMode ? [{ debugName: "visibleSections" }] : /* istanbul ignore next */ []));
|
|
@@ -7425,15 +7476,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
7425
7476
|
args: ['document:keydown.escape']
|
|
7426
7477
|
}] } });
|
|
7427
7478
|
|
|
7428
|
-
const SIDE_COLLAPSED_KEY = 'ef.shell.side-collapsed';
|
|
7429
|
-
function readSideCollapsed() {
|
|
7430
|
-
try {
|
|
7431
|
-
return localStorage.getItem(SIDE_COLLAPSED_KEY) === '1';
|
|
7432
|
-
}
|
|
7433
|
-
catch {
|
|
7434
|
-
return false;
|
|
7435
|
-
}
|
|
7436
|
-
}
|
|
7437
7479
|
/**
|
|
7438
7480
|
* Top-level Comptoir shell.
|
|
7439
7481
|
*
|
|
@@ -7481,20 +7523,22 @@ class EfAppShellComponent {
|
|
|
7481
7523
|
inside the side, so it is still there to bring the side back
|
|
7482
7524
|
once it is gone, and in the same spot. Remembered per browser:
|
|
7483
7525
|
it is a reading preference, not something worth a round trip. */
|
|
7484
|
-
|
|
7526
|
+
prefs = inject(EF_PREFERENCE_STORE);
|
|
7527
|
+
sideCollapsed = signal(this.prefs.get(EF_SIDE_COLLAPSED_KEY) === '1', ...(ngDevMode ? [{ debugName: "sideCollapsed" }] : /* istanbul ignore next */ []));
|
|
7485
7528
|
/** Shown in the toggle's tooltip: the button is far from the content, the shortcut is not. */
|
|
7486
7529
|
shortcutHint = formatShortcut('mod+b');
|
|
7487
7530
|
toggleSide() {
|
|
7488
7531
|
const collapsed = !this.sideCollapsed();
|
|
7489
7532
|
this.sideCollapsed.set(collapsed);
|
|
7490
|
-
|
|
7491
|
-
localStorage.setItem(SIDE_COLLAPSED_KEY, collapsed ? '1' : '0');
|
|
7492
|
-
}
|
|
7493
|
-
catch {
|
|
7494
|
-
/* private window or blocked storage: the toggle still works for this visit */
|
|
7495
|
-
}
|
|
7533
|
+
this.prefs.set(EF_SIDE_COLLAPSED_KEY, collapsed ? '1' : '0');
|
|
7496
7534
|
}
|
|
7497
7535
|
constructor() {
|
|
7536
|
+
// A store that hydrates after sign in announces the key it filled.
|
|
7537
|
+
this.prefs.changes?.pipe(takeUntilDestroyed()).subscribe((key) => {
|
|
7538
|
+
if (key === EF_SIDE_COLLAPSED_KEY) {
|
|
7539
|
+
this.sideCollapsed.set(this.prefs.get(EF_SIDE_COLLAPSED_KEY) === '1');
|
|
7540
|
+
}
|
|
7541
|
+
});
|
|
7498
7542
|
inject(EfShortcutService).register({
|
|
7499
7543
|
id: 'shell.toggle-side',
|
|
7500
7544
|
keys: 'mod+b',
|
|
@@ -7530,7 +7574,8 @@ class EfAppShellComponent {
|
|
|
7530
7574
|
return m.navSections
|
|
7531
7575
|
.map(section => ({
|
|
7532
7576
|
...section,
|
|
7533
|
-
items: section.items.filter(item => this.perms.can(m.id, item.requiredAction ?? 'read')
|
|
7577
|
+
items: section.items.filter(item => this.perms.can(m.id, item.requiredAction ?? 'read') &&
|
|
7578
|
+
(!item.screenCode || this.perms.canScreen(item.screenCode))),
|
|
7534
7579
|
}))
|
|
7535
7580
|
.filter(section => section.items.length > 0);
|
|
7536
7581
|
}, ...(ngDevMode ? [{ debugName: "moduleSections" }] : /* istanbul ignore next */ []));
|
|
@@ -8601,6 +8646,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8601
8646
|
* Custom actions can declare `permission` and `visible` like
|
|
8602
8647
|
* `EfRowAction`. With `[context]` bound, the toolbar filters them
|
|
8603
8648
|
* against `ScreenContext.isGranted()` automatically.
|
|
8649
|
+
*
|
|
8650
|
+
* Save and actions flagged `requiresWrite` follow `context.canWrite`,
|
|
8651
|
+
* which `AbstractDetailScreenV2` sets from its own `canWrite()` (Edit on
|
|
8652
|
+
* an existing record, Create on a new one or a duplicate). Binding
|
|
8653
|
+
* `[context]="context"` is all a screen does; it does not pass
|
|
8654
|
+
* `[showSaveAction]` for permissions. Without a context, or with one that
|
|
8655
|
+
* carries no `canWrite`, Save behaves as `[showSaveAction]` alone says.
|
|
8604
8656
|
*/
|
|
8605
8657
|
class EfDetailToolbarComponent {
|
|
8606
8658
|
/* ── Inputs ─────────────────────────────────────────────────── */
|
|
@@ -8638,12 +8690,17 @@ class EfDetailToolbarComponent {
|
|
|
8638
8690
|
/** Custom actions after permission + `visible` filtering. */
|
|
8639
8691
|
visibleCustomActions = computed(() => {
|
|
8640
8692
|
const ctx = this.context();
|
|
8641
|
-
|
|
8693
|
+
const canWrite = this.canWrite();
|
|
8694
|
+
return this.customActions().filter((a) => this.isCustomVisible(a, ctx, canWrite));
|
|
8642
8695
|
}, ...(ngDevMode ? [{ debugName: "visibleCustomActions" }] : /* istanbul ignore next */ []));
|
|
8643
8696
|
canPrint = computed(() => this.checkStandard(this.showPrintAction(), Permissions.Print), ...(ngDevMode ? [{ debugName: "canPrint" }] : /* istanbul ignore next */ []));
|
|
8644
8697
|
canDuplicate = computed(() => this.checkStandard(this.showDuplicateAction(), Permissions.Duplicate), ...(ngDevMode ? [{ debugName: "canDuplicate" }] : /* istanbul ignore next */ []));
|
|
8645
8698
|
canDelete = computed(() => this.checkStandard(this.showDeleteAction(), Permissions.Delete), ...(ngDevMode ? [{ debugName: "canDelete" }] : /* istanbul ignore next */ []));
|
|
8646
|
-
|
|
8699
|
+
/** The bound screen's write state; `true` when unknown (no context,
|
|
8700
|
+
* or a context no detail abstract has stamped), which keeps the
|
|
8701
|
+
* toolbar's behaviour for those callers what it always was. */
|
|
8702
|
+
canWrite = computed(() => this.context()?.canWrite?.() ?? true, ...(ngDevMode ? [{ debugName: "canWrite" }] : /* istanbul ignore next */ []));
|
|
8703
|
+
canSave = computed(() => this.showSaveAction() && this.canWrite(), ...(ngDevMode ? [{ debugName: "canSave" }] : /* istanbul ignore next */ []));
|
|
8647
8704
|
hasStandardActions = computed(() => this.canPrint() ||
|
|
8648
8705
|
this.canDuplicate() ||
|
|
8649
8706
|
this.canDelete() ||
|
|
@@ -8659,9 +8716,11 @@ class EfDetailToolbarComponent {
|
|
|
8659
8716
|
this.customAction.emit(action);
|
|
8660
8717
|
}
|
|
8661
8718
|
/* ── Internals ──────────────────────────────────────────────── */
|
|
8662
|
-
isCustomVisible(action, ctx) {
|
|
8719
|
+
isCustomVisible(action, ctx, canWrite) {
|
|
8663
8720
|
if (action.visible === false)
|
|
8664
8721
|
return false;
|
|
8722
|
+
if (action.requiresWrite && !canWrite)
|
|
8723
|
+
return false;
|
|
8665
8724
|
if (action.permission && ctx && !ctx.isGranted(action.permission))
|
|
8666
8725
|
return false;
|
|
8667
8726
|
return true;
|
|
@@ -8678,7 +8737,9 @@ class EfDetailToolbarComponent {
|
|
|
8678
8737
|
case Permissions.Print:
|
|
8679
8738
|
return ctx.hasPrintPermission;
|
|
8680
8739
|
case Permissions.Duplicate:
|
|
8681
|
-
|
|
8740
|
+
// A duplicate is saved through create, and duplicate() refuses
|
|
8741
|
+
// without Create; showing it on Duplicate alone gave a dead button.
|
|
8742
|
+
return ctx.hasDuplicatePermission && ctx.hasCreatePermission;
|
|
8682
8743
|
case Permissions.Delete:
|
|
8683
8744
|
return ctx.hasDeletePermission;
|
|
8684
8745
|
}
|
|
@@ -9541,11 +9602,11 @@ class EfCheckboxComponent extends AbstractEfFormControl {
|
|
|
9541
9602
|
this.onTouched();
|
|
9542
9603
|
}
|
|
9543
9604
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9544
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfCheckboxComponent, isStandalone: true, selector: "ef-checkbox", inputs: { value: "value", binary: ["binary", "binary", booleanAttribute], variant: "variant", inline: ["inline", "inline", booleanAttribute], checked: "checked" }, outputs: { checkedChange: "checkedChange" }, host: { properties: { "class.ef-stacked": "this.isStacked" } }, usesInheritance: true, ngImport: i0, template: "@if (!inline && hasLabel) {\n <ef-label [labelKey]=\"labelKey()\" [label]=\"label()\" [for]=\"effectiveId\" [required]=\"required()\" />\n}\n<div class=\"ef-checkbox-control\">\n @if (variant === 'comptoir') {\n <label class=\"ef-checkbox-native\" [class.is-disabled]=\"
|
|
9605
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfCheckboxComponent, isStandalone: true, selector: "ef-checkbox", inputs: { value: "value", binary: ["binary", "binary", booleanAttribute], variant: "variant", inline: ["inline", "inline", booleanAttribute], checked: "checked" }, outputs: { checkedChange: "checkedChange" }, host: { properties: { "class.ef-stacked": "this.isStacked" } }, usesInheritance: true, ngImport: i0, template: "@if (!inline && hasLabel) {\n <ef-label [labelKey]=\"labelKey()\" [label]=\"label()\" [for]=\"effectiveId\" [required]=\"required()\" />\n}\n<div class=\"ef-checkbox-control\">\n @if (variant === 'comptoir') {\n <label class=\"ef-checkbox-native\" [class.is-disabled]=\"isDisabled()\">\n <input\n type=\"checkbox\"\n [id]=\"effectiveId\"\n [attr.name]=\"name() || null\"\n [checked]=\"!!checked\"\n [disabled]=\"isDisabled()\"\n [class.is-invalid]=\"isInvalid\"\n [attr.aria-label]=\"effectiveAriaLabel\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : null\"\n [attr.aria-describedby]=\"(showRequired || serverErrors) ? errorsId : null\"\n (change)=\"handleNativeChange($any($event.target).checked)\"\n />\n <span class=\"ef-checkbox-box\" aria-hidden=\"true\"></span>\n @if (inline && hasLabel) {\n <span class=\"ef-checkbox-label\">\n {{ labelKey() ? (labelKey() | translate) : label() }}\n @if (required()) {\n <span class=\"ef-checkbox-required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n </label>\n } @else {\n <p-checkbox\n [inputId]=\"effectiveId\"\n [name]=\"name()\"\n [ngModel]=\"checked\"\n [ngModelOptions]=\"{standalone: true}\"\n (onChange)=\"handleChange($event)\"\n [value]=\"value\"\n [binary]=\"binary\"\n [disabled]=\"isDisabled()\"\n [ariaLabel]=\"effectiveAriaLabel || undefined\"\n />\n @if (inline && hasLabel) {\n <ef-label [labelKey]=\"labelKey()\" [label]=\"label()\" [for]=\"effectiveId\" styleClass=\"form-label-left cursor-pointer\" />\n }\n }\n</div>\n@if (showRequired || serverErrors) {\n <div [id]=\"errorsId\" role=\"alert\" aria-live=\"polite\">\n @if (showRequired) {\n <small class=\"text-danger\">{{ 'validation.required' | translate }}</small>\n }\n @if (serverErrors; as errors) {\n @for (error of errors; track error) {\n <small class=\"text-danger block\">{{ error }}</small>\n }\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-wrap:wrap;align-items:center;gap:.5rem;min-width:0}.ef-checkbox-control{display:inline-flex;align-items:center;gap:.5rem;min-width:0}:host(.ef-stacked){display:block}:host(.ef-stacked)>.ef-checkbox-control{display:flex;min-height:var(--hit-base)}\n"], dependencies: [{ kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i5.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfLabelComponent, selector: "ef-label", inputs: ["label", "labelKey", "for", "styleClass", "required"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
9545
9606
|
}
|
|
9546
9607
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfCheckboxComponent, decorators: [{
|
|
9547
9608
|
type: Component,
|
|
9548
|
-
args: [{ selector: 'ef-checkbox', standalone: true, imports: [CheckboxModule, FormsModule, TranslateModule, EfLabelComponent], template: "@if (!inline && hasLabel) {\n <ef-label [labelKey]=\"labelKey()\" [label]=\"label()\" [for]=\"effectiveId\" [required]=\"required()\" />\n}\n<div class=\"ef-checkbox-control\">\n @if (variant === 'comptoir') {\n <label class=\"ef-checkbox-native\" [class.is-disabled]=\"
|
|
9609
|
+
args: [{ selector: 'ef-checkbox', standalone: true, imports: [CheckboxModule, FormsModule, TranslateModule, EfLabelComponent], template: "@if (!inline && hasLabel) {\n <ef-label [labelKey]=\"labelKey()\" [label]=\"label()\" [for]=\"effectiveId\" [required]=\"required()\" />\n}\n<div class=\"ef-checkbox-control\">\n @if (variant === 'comptoir') {\n <label class=\"ef-checkbox-native\" [class.is-disabled]=\"isDisabled()\">\n <input\n type=\"checkbox\"\n [id]=\"effectiveId\"\n [attr.name]=\"name() || null\"\n [checked]=\"!!checked\"\n [disabled]=\"isDisabled()\"\n [class.is-invalid]=\"isInvalid\"\n [attr.aria-label]=\"effectiveAriaLabel\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : null\"\n [attr.aria-describedby]=\"(showRequired || serverErrors) ? errorsId : null\"\n (change)=\"handleNativeChange($any($event.target).checked)\"\n />\n <span class=\"ef-checkbox-box\" aria-hidden=\"true\"></span>\n @if (inline && hasLabel) {\n <span class=\"ef-checkbox-label\">\n {{ labelKey() ? (labelKey() | translate) : label() }}\n @if (required()) {\n <span class=\"ef-checkbox-required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n </label>\n } @else {\n <p-checkbox\n [inputId]=\"effectiveId\"\n [name]=\"name()\"\n [ngModel]=\"checked\"\n [ngModelOptions]=\"{standalone: true}\"\n (onChange)=\"handleChange($event)\"\n [value]=\"value\"\n [binary]=\"binary\"\n [disabled]=\"isDisabled()\"\n [ariaLabel]=\"effectiveAriaLabel || undefined\"\n />\n @if (inline && hasLabel) {\n <ef-label [labelKey]=\"labelKey()\" [label]=\"label()\" [for]=\"effectiveId\" styleClass=\"form-label-left cursor-pointer\" />\n }\n }\n</div>\n@if (showRequired || serverErrors) {\n <div [id]=\"errorsId\" role=\"alert\" aria-live=\"polite\">\n @if (showRequired) {\n <small class=\"text-danger\">{{ 'validation.required' | translate }}</small>\n }\n @if (serverErrors; as errors) {\n @for (error of errors; track error) {\n <small class=\"text-danger block\">{{ error }}</small>\n }\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-wrap:wrap;align-items:center;gap:.5rem;min-width:0}.ef-checkbox-control{display:inline-flex;align-items:center;gap:.5rem;min-width:0}:host(.ef-stacked){display:block}:host(.ef-stacked)>.ef-checkbox-control{display:flex;min-height:var(--hit-base)}\n"] }]
|
|
9549
9610
|
}], ctorParameters: () => [], propDecorators: { value: [{
|
|
9550
9611
|
type: Input
|
|
9551
9612
|
}], binary: [{
|
|
@@ -9708,6 +9769,12 @@ class EfDatepickerComponent {
|
|
|
9708
9769
|
showButtonBar = false;
|
|
9709
9770
|
minDate;
|
|
9710
9771
|
maxDate;
|
|
9772
|
+
/** Optional enclosing `[efReadOnly]` scope. */
|
|
9773
|
+
readOnlyScope = inject(EfReadOnlyDirective, { optional: true });
|
|
9774
|
+
/** Effective disabled: the input / CVA state OR a read-only scope. */
|
|
9775
|
+
get isDisabled() {
|
|
9776
|
+
return this.disabled || (this.readOnlyScope?.readOnly() ?? false);
|
|
9777
|
+
}
|
|
9711
9778
|
/**
|
|
9712
9779
|
* Take focus on load. Bound explicitly rather than left unset: PrimeNG's
|
|
9713
9780
|
* AutoFocus directive tests `autofocus === false`, and the control declares
|
|
@@ -9767,11 +9834,11 @@ class EfDatepickerComponent {
|
|
|
9767
9834
|
this.onTouched();
|
|
9768
9835
|
}
|
|
9769
9836
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9770
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfDatepickerComponent, isStandalone: true, selector: "ef-datepicker", inputs: { label: "label", labelKey: "labelKey", inputId: "inputId", name: "name", placeholder: "placeholder", placeholderKey: "placeholderKey", size: "size", required: ["required", "required", booleanAttribute], fluid: ["fluid", "fluid", booleanAttribute], inline: ["inline", "inline", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], showIcon: ["showIcon", "showIcon", booleanAttribute], iconDisplay: "iconDisplay", selectionMode: "selectionMode", dateFormat: "dateFormat", appendTo: "appendTo", showTime: ["showTime", "showTime", booleanAttribute], showButtonBar: ["showButtonBar", "showButtonBar", booleanAttribute], minDate: "minDate", maxDate: "maxDate", autofocus: ["autofocus", "autofocus", booleanAttribute] }, outputs: { dateSelectEvent: "dateSelectEvent" }, host: { properties: { "class.ef-inline": "this.isInline" } }, ngImport: i0, template: "@if (labelKey || label) {\n <ef-label [labelKey]=\"labelKey\" [label]=\"label\" [for]=\"effectiveId\" [required]=\"required\" />\n}\n<div class=\"ef-field-control\">\n <p-datepicker\n [autofocus]=\"autofocus\"\n [inputId]=\"effectiveId\"\n [name]=\"name\"\n [ngModel]=\"value\"\n [ngModelOptions]=\"{standalone: true}\"\n (ngModelChange)=\"handleChange($event)\"\n (onBlur)=\"handleBlur()\"\n [placeholder]=\"effectivePlaceholder\"\n [size]=\"size\"\n [disabled]=\"
|
|
9837
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfDatepickerComponent, isStandalone: true, selector: "ef-datepicker", inputs: { label: "label", labelKey: "labelKey", inputId: "inputId", name: "name", placeholder: "placeholder", placeholderKey: "placeholderKey", size: "size", required: ["required", "required", booleanAttribute], fluid: ["fluid", "fluid", booleanAttribute], inline: ["inline", "inline", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], showIcon: ["showIcon", "showIcon", booleanAttribute], iconDisplay: "iconDisplay", selectionMode: "selectionMode", dateFormat: "dateFormat", appendTo: "appendTo", showTime: ["showTime", "showTime", booleanAttribute], showButtonBar: ["showButtonBar", "showButtonBar", booleanAttribute], minDate: "minDate", maxDate: "maxDate", autofocus: ["autofocus", "autofocus", booleanAttribute] }, outputs: { dateSelectEvent: "dateSelectEvent" }, host: { properties: { "class.ef-inline": "this.isInline" } }, ngImport: i0, template: "@if (labelKey || label) {\n <ef-label [labelKey]=\"labelKey\" [label]=\"label\" [for]=\"effectiveId\" [required]=\"required\" />\n}\n<div class=\"ef-field-control\">\n <p-datepicker\n [autofocus]=\"autofocus\"\n [inputId]=\"effectiveId\"\n [name]=\"name\"\n [ngModel]=\"value\"\n [ngModelOptions]=\"{standalone: true}\"\n (ngModelChange)=\"handleChange($event)\"\n (onBlur)=\"handleBlur()\"\n [placeholder]=\"effectivePlaceholder\"\n [size]=\"size\"\n [disabled]=\"isDisabled\"\n [showIcon]=\"showIcon\"\n [iconDisplay]=\"iconDisplay\"\n [selectionMode]=\"selectionMode\"\n [dateFormat]=\"dateFormat\"\n [appendTo]=\"appendTo\"\n [showTime]=\"showTime\"\n [showButtonBar]=\"showButtonBar\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [fluid]=\"fluid\"\n [class.ng-invalid]=\"isInvalid\"\n [class.ng-touched]=\"ngControl?.touched\"\n />\n @if (showRequired) {\n <small class=\"text-danger\">{{ 'validation.required' | translate }}</small>\n }\n @if (serverErrors; as errors) {\n @for (error of errors; track error) {\n <small class=\"text-danger block\">{{ error }}</small>\n }\n }\n</div>\n", styles: [":host{display:block}:host(.ef-inline){display:flex;align-items:baseline;gap:.5rem}:host(.ef-inline)>label{white-space:nowrap;flex-shrink:0}:host(.ef-inline)>.ef-field-control{flex:1;min-width:0}\n"], dependencies: [{ kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i1$d.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfLabelComponent, selector: "ef-label", inputs: ["label", "labelKey", "for", "styleClass", "required"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
9771
9838
|
}
|
|
9772
9839
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfDatepickerComponent, decorators: [{
|
|
9773
9840
|
type: Component,
|
|
9774
|
-
args: [{ selector: 'ef-datepicker', standalone: true, imports: [DatePickerModule, FormsModule, TranslateModule, EfLabelComponent], template: "@if (labelKey || label) {\n <ef-label [labelKey]=\"labelKey\" [label]=\"label\" [for]=\"effectiveId\" [required]=\"required\" />\n}\n<div class=\"ef-field-control\">\n <p-datepicker\n [autofocus]=\"autofocus\"\n [inputId]=\"effectiveId\"\n [name]=\"name\"\n [ngModel]=\"value\"\n [ngModelOptions]=\"{standalone: true}\"\n (ngModelChange)=\"handleChange($event)\"\n (onBlur)=\"handleBlur()\"\n [placeholder]=\"effectivePlaceholder\"\n [size]=\"size\"\n [disabled]=\"
|
|
9841
|
+
args: [{ selector: 'ef-datepicker', standalone: true, imports: [DatePickerModule, FormsModule, TranslateModule, EfLabelComponent], template: "@if (labelKey || label) {\n <ef-label [labelKey]=\"labelKey\" [label]=\"label\" [for]=\"effectiveId\" [required]=\"required\" />\n}\n<div class=\"ef-field-control\">\n <p-datepicker\n [autofocus]=\"autofocus\"\n [inputId]=\"effectiveId\"\n [name]=\"name\"\n [ngModel]=\"value\"\n [ngModelOptions]=\"{standalone: true}\"\n (ngModelChange)=\"handleChange($event)\"\n (onBlur)=\"handleBlur()\"\n [placeholder]=\"effectivePlaceholder\"\n [size]=\"size\"\n [disabled]=\"isDisabled\"\n [showIcon]=\"showIcon\"\n [iconDisplay]=\"iconDisplay\"\n [selectionMode]=\"selectionMode\"\n [dateFormat]=\"dateFormat\"\n [appendTo]=\"appendTo\"\n [showTime]=\"showTime\"\n [showButtonBar]=\"showButtonBar\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [fluid]=\"fluid\"\n [class.ng-invalid]=\"isInvalid\"\n [class.ng-touched]=\"ngControl?.touched\"\n />\n @if (showRequired) {\n <small class=\"text-danger\">{{ 'validation.required' | translate }}</small>\n }\n @if (serverErrors; as errors) {\n @for (error of errors; track error) {\n <small class=\"text-danger block\">{{ error }}</small>\n }\n }\n</div>\n", styles: [":host{display:block}:host(.ef-inline){display:flex;align-items:baseline;gap:.5rem}:host(.ef-inline)>label{white-space:nowrap;flex-shrink:0}:host(.ef-inline)>.ef-field-control{flex:1;min-width:0}\n"] }]
|
|
9775
9842
|
}], ctorParameters: () => [], propDecorators: { label: [{
|
|
9776
9843
|
type: Input
|
|
9777
9844
|
}], labelKey: [{
|
|
@@ -10818,14 +10885,22 @@ class EfSmartBarComponent {
|
|
|
10818
10885
|
only text inside this label is the shortcut hint, so
|
|
10819
10886
|
without it a screen reader announced the primary
|
|
10820
10887
|
search field of every list screen as "Cmd K". -->
|
|
10888
|
+
<!-- type="search" fires a native, bubbling 'search' Event
|
|
10889
|
+
on Enter and on the browser's clear button (Chromium,
|
|
10890
|
+
WebKit). A host (search) binding hears that DOM event
|
|
10891
|
+
as well as the output below, so it would receive the
|
|
10892
|
+
Event as the search text. Stopped here; the output is
|
|
10893
|
+
the only 'search' that leaves this component. -->
|
|
10821
10894
|
<input
|
|
10822
10895
|
#searchInput
|
|
10823
10896
|
type="search"
|
|
10897
|
+
enterkeyhint="search"
|
|
10824
10898
|
[attr.aria-label]="accessibleLabel()"
|
|
10825
10899
|
[placeholder]="(placeholderKey() ? (placeholderKey() | translate) : placeholder())"
|
|
10826
10900
|
[ngModel]="searchText()"
|
|
10827
10901
|
(ngModelChange)="searchText.set($event)"
|
|
10828
10902
|
(keydown.enter)="onSubmit()"
|
|
10903
|
+
(search)="$event.stopPropagation()"
|
|
10829
10904
|
/>
|
|
10830
10905
|
@if (showKbdHint() && kbdLabel()) {
|
|
10831
10906
|
<!-- Decorative, and hidden from the accessibility tree:
|
|
@@ -10865,15 +10940,11 @@ class EfSmartBarComponent {
|
|
|
10865
10940
|
|
|
10866
10941
|
<ng-content select="[drawer]"></ng-content>
|
|
10867
10942
|
</div>
|
|
10868
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10943
|
+
`, isInline: true, styles: ["input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10869
10944
|
}
|
|
10870
10945
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfSmartBarComponent, decorators: [{
|
|
10871
10946
|
type: Component,
|
|
10872
|
-
args: [{
|
|
10873
|
-
selector: 'ef-smart-bar',
|
|
10874
|
-
standalone: true,
|
|
10875
|
-
imports: [CommonModule, FormsModule, TranslateModule],
|
|
10876
|
-
template: `
|
|
10947
|
+
args: [{ selector: 'ef-smart-bar', standalone: true, imports: [CommonModule, FormsModule, TranslateModule], template: `
|
|
10877
10948
|
<div class="screen-search">
|
|
10878
10949
|
<div class="smart-bar">
|
|
10879
10950
|
<label class="search">
|
|
@@ -10881,14 +10952,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
10881
10952
|
only text inside this label is the shortcut hint, so
|
|
10882
10953
|
without it a screen reader announced the primary
|
|
10883
10954
|
search field of every list screen as "Cmd K". -->
|
|
10955
|
+
<!-- type="search" fires a native, bubbling 'search' Event
|
|
10956
|
+
on Enter and on the browser's clear button (Chromium,
|
|
10957
|
+
WebKit). A host (search) binding hears that DOM event
|
|
10958
|
+
as well as the output below, so it would receive the
|
|
10959
|
+
Event as the search text. Stopped here; the output is
|
|
10960
|
+
the only 'search' that leaves this component. -->
|
|
10884
10961
|
<input
|
|
10885
10962
|
#searchInput
|
|
10886
10963
|
type="search"
|
|
10964
|
+
enterkeyhint="search"
|
|
10887
10965
|
[attr.aria-label]="accessibleLabel()"
|
|
10888
10966
|
[placeholder]="(placeholderKey() ? (placeholderKey() | translate) : placeholder())"
|
|
10889
10967
|
[ngModel]="searchText()"
|
|
10890
10968
|
(ngModelChange)="searchText.set($event)"
|
|
10891
10969
|
(keydown.enter)="onSubmit()"
|
|
10970
|
+
(search)="$event.stopPropagation()"
|
|
10892
10971
|
/>
|
|
10893
10972
|
@if (showKbdHint() && kbdLabel()) {
|
|
10894
10973
|
<!-- Decorative, and hidden from the accessibility tree:
|
|
@@ -10928,9 +11007,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
10928
11007
|
|
|
10929
11008
|
<ng-content select="[drawer]"></ng-content>
|
|
10930
11009
|
</div>
|
|
10931
|
-
`,
|
|
10932
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
10933
|
-
}]
|
|
11010
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;display:none}\n"] }]
|
|
10934
11011
|
}], ctorParameters: () => [], propDecorators: { searchInput: [{ type: i0.ViewChild, args: ['searchInput', { isSignal: true }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }], placeholderKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholderKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabelKey", required: false }] }], clearTitleKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTitleKey", required: false }] }], searchLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchLabelKey", required: false }] }], showKbdHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "showKbdHint", required: false }] }], hideClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClear", required: false }] }], hideSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSearch", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], shortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "shortcut", required: false }] }], search: [{ type: i0.Output, args: ["search"] }], clear: [{ type: i0.Output, args: ["clear"] }] } });
|
|
10935
11012
|
|
|
10936
11013
|
/**
|
|
@@ -12088,5 +12165,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
12088
12165
|
* Generated bundle index. Do not edit.
|
|
12089
12166
|
*/
|
|
12090
12167
|
|
|
12091
|
-
export { EF_BADGE_BG_COLORS, EF_BADGE_BG_LIGHT_COLORS, EF_BADGE_BORDER_COLORS, EF_BADGE_DEFAULTS, EF_BADGE_TEXT_COLORS, EF_CHART_PALETTE, EF_DATATABLE_ACTIONS_DEFAULTS, EF_DATATABLE_COLUMN_DEFAULTS, EF_DATATABLE_DEFAULTS, EF_DATA_CARD_MOBILE_LAYOUT, EF_STATUS_COLORS, EF_STATUS_COLOR_ALIASES, EfAboutDialogComponent, EfActivationFilterComponent, EfAppMainComponent, EfAppShellComponent, EfAppShellMobileComponent, EfAppTopComponent, EfBadgeComponent, EfBlockUiComponent, EfBlockableDivComponent, EfBottomSheetComponent, EfBuildStampComponent, EfBulkBarComponent, EfButtonComponent, EfButtonGroupComponent, EfCardComponent, EfChangeHistoryComponent, EfChangePasswordComponent, EfChartComponent, EfCheckboxComponent, EfClearButtonComponent, EfColumnHeaderTemplateDirective, EfColumnTemplateDirective, EfCompactPipe, EfConfirmDialogComponent, EfCurrencyPipe, EfDataCardComponent, EfDatatableActionBarComponent, EfDatatableComponent, EfDatepickerAdvancedComponent, EfDatepickerComponent, EfDetailToolbarComponent, EfDialogComponent, EfEmailMetricsCardComponent, EfEmptyStateComponent, EfFabComponent, EfFieldsetComponent, EfFilterDrawerComponent, EfFilterPillComponent, EfFormGridComponent, EfInputNumberComponent, EfInputTextComponent, EfKpiCardComponent, EfLabelComponent, EfModuleRailComponent, EfModuleSideComponent, EfMultiSelectComponent, EfOrderBuilderComponent, EfOrderSummaryComponent, EfOverflowTooltipDirective, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfProfileMenuComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRadioComponent, EfRankListComponent, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfServerErrorsDirective, EfShortcutsDialogComponent, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
|
|
12168
|
+
export { EF_BADGE_BG_COLORS, EF_BADGE_BG_LIGHT_COLORS, EF_BADGE_BORDER_COLORS, EF_BADGE_DEFAULTS, EF_BADGE_TEXT_COLORS, EF_CHART_PALETTE, EF_DATATABLE_ACTIONS_DEFAULTS, EF_DATATABLE_COLUMN_DEFAULTS, EF_DATATABLE_DEFAULTS, EF_DATA_CARD_MOBILE_LAYOUT, EF_STATUS_COLORS, EF_STATUS_COLOR_ALIASES, EfAboutDialogComponent, EfActivationFilterComponent, EfAppMainComponent, EfAppShellComponent, EfAppShellMobileComponent, EfAppTopComponent, EfBadgeComponent, EfBlockUiComponent, EfBlockableDivComponent, EfBottomSheetComponent, EfBuildStampComponent, EfBulkBarComponent, EfButtonComponent, EfButtonGroupComponent, EfCardComponent, EfChangeHistoryComponent, EfChangePasswordComponent, EfChartComponent, EfCheckboxComponent, EfClearButtonComponent, EfColumnHeaderTemplateDirective, EfColumnTemplateDirective, EfCompactPipe, EfConfirmDialogComponent, EfCurrencyPipe, EfDataCardComponent, EfDatatableActionBarComponent, EfDatatableComponent, EfDatepickerAdvancedComponent, EfDatepickerComponent, EfDetailToolbarComponent, EfDialogComponent, EfEmailMetricsCardComponent, EfEmptyStateComponent, EfFabComponent, EfFieldsetComponent, EfFilterDrawerComponent, EfFilterPillComponent, EfFormGridComponent, EfInputNumberComponent, EfInputTextComponent, EfKpiCardComponent, EfLabelComponent, EfModuleRailComponent, EfModuleSideComponent, EfMultiSelectComponent, EfOrderBuilderComponent, EfOrderSummaryComponent, EfOverflowTooltipDirective, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfProfileMenuComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRadioComponent, EfRankListComponent, EfReadOnlyDirective, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfServerErrorsDirective, EfShortcutsDialogComponent, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
|
|
12092
12169
|
//# sourceMappingURL=elasticias-ui.mjs.map
|