@elasticias/ui 1.0.10 → 1.0.13
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 +284 -23
- package/fesm2022/elasticias-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/_patterns.scss +137 -10
- package/types/elasticias-ui.d.ts +221 -7
|
@@ -42,7 +42,7 @@ import { MenuModule } from 'primeng/menu';
|
|
|
42
42
|
import * as i2$3 from 'primeng/api';
|
|
43
43
|
import * as i1$8 from 'primeng/confirmdialog';
|
|
44
44
|
import { ConfirmDialogModule } from 'primeng/confirmdialog';
|
|
45
|
-
import { EfThemeConfigService, EF_BUILD_INFO, EfPermissionService, EfActiveModuleService, EF_SESSION, EfViewportService, EfToastService } from '@elasticias/core';
|
|
45
|
+
import { EfThemeConfigService, EF_BUILD_INFO, EfShortcutService, isMacPlatform, formatShortcut, EfPermissionService, EfActiveModuleService, EF_SESSION, EfViewportService, EfToastService } from '@elasticias/core';
|
|
46
46
|
import * as i1$9 from 'primeng/buttongroup';
|
|
47
47
|
import { ButtonGroupModule } from 'primeng/buttongroup';
|
|
48
48
|
import * as i1$a from 'primeng/toolbar';
|
|
@@ -50,6 +50,8 @@ import { ToolbarModule } from 'primeng/toolbar';
|
|
|
50
50
|
import { ScreenStateEnum, SCREEN_REF_DATA_SERVICE } from '@elasticias/screens';
|
|
51
51
|
import { Router, RouterLink, RouterLinkActive } from '@angular/router';
|
|
52
52
|
import { Permissions } from '@elasticias/types';
|
|
53
|
+
import * as i2$4 from 'primeng/popover';
|
|
54
|
+
import { PopoverModule } from 'primeng/popover';
|
|
53
55
|
import * as i1$b from 'primeng/blockui';
|
|
54
56
|
import { BlockUIModule } from 'primeng/blockui';
|
|
55
57
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
@@ -62,7 +64,7 @@ import * as i1$e from 'primeng/password';
|
|
|
62
64
|
import { PasswordModule } from 'primeng/password';
|
|
63
65
|
import * as i1$f from 'primeng/selectbutton';
|
|
64
66
|
import { SelectButtonModule, SelectButton } from 'primeng/selectbutton';
|
|
65
|
-
import * as i2$
|
|
67
|
+
import * as i2$5 from 'primeng/table';
|
|
66
68
|
import { TableModule } from 'primeng/table';
|
|
67
69
|
import { updatePreset, updateSurfacePalette, $t } from '@primeng/themes';
|
|
68
70
|
import Aura from '@primeng/themes/aura';
|
|
@@ -4876,6 +4878,14 @@ class EfAboutDialogComponent {
|
|
|
4876
4878
|
product = input('', ...(ngDevMode ? [{ debugName: "product" }] : /* istanbul ignore next */ []));
|
|
4877
4879
|
/** One muted line under the product — a tenant, a plan, an edition. */
|
|
4878
4880
|
edition = input('', ...(ngDevMode ? [{ debugName: "edition" }] : /* istanbul ignore next */ []));
|
|
4881
|
+
/** Which organisation this deployment serves, as a labelled row. */
|
|
4882
|
+
organisation = input('', ...(ngDevMode ? [{ debugName: "organisation" }] : /* istanbul ignore next */ []));
|
|
4883
|
+
/** What the API reports about itself. Leave empty to hide the group. */
|
|
4884
|
+
server = input({}, ...(ngDevMode ? [{ debugName: "server" }] : /* istanbul ignore next */ []));
|
|
4885
|
+
/** Outbound link, already carrying whatever query the app wants on it. */
|
|
4886
|
+
websiteUrl = input('', ...(ngDevMode ? [{ debugName: "websiteUrl" }] : /* istanbul ignore next */ []));
|
|
4887
|
+
/** What the link reads as — a domain, not a sentence. */
|
|
4888
|
+
websiteLabel = input('', ...(ngDevMode ? [{ debugName: "websiteLabel" }] : /* istanbul ignore next */ []));
|
|
4879
4889
|
/** Brand mark. A logo wins over the initial when both are set; empty
|
|
4880
4890
|
* means "none", the same way `edition` and `initial` read. */
|
|
4881
4891
|
logoUrl = input('', ...(ngDevMode ? [{ debugName: "logoUrl" }] : /* istanbul ignore next */ []));
|
|
@@ -4892,27 +4902,74 @@ class EfAboutDialogComponent {
|
|
|
4892
4902
|
*/
|
|
4893
4903
|
rows = computed(() => {
|
|
4894
4904
|
const i = this.info;
|
|
4895
|
-
if (!i)
|
|
4896
|
-
return [];
|
|
4897
4905
|
return [
|
|
4898
|
-
{ labelKey: '
|
|
4899
|
-
{ labelKey: '
|
|
4900
|
-
{ labelKey: '
|
|
4901
|
-
{ labelKey: '
|
|
4902
|
-
{ labelKey: '
|
|
4906
|
+
{ labelKey: 'common_about_organisation', value: this.organisation() },
|
|
4907
|
+
{ labelKey: 'common_about_version', value: i?.version ? `v${i.version}` : '' },
|
|
4908
|
+
{ labelKey: 'common_about_environment', value: i?.environment ?? '' },
|
|
4909
|
+
{ labelKey: 'common_about_branch', value: i?.branch ?? '' },
|
|
4910
|
+
{ labelKey: 'common_about_commit', value: i?.commit ?? '' },
|
|
4911
|
+
{ labelKey: 'common_about_date', value: i?.date ?? '' },
|
|
4903
4912
|
].filter(row => !!row.value);
|
|
4904
4913
|
}, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
4914
|
+
/** The API's own identity, above the assemblies it loaded. */
|
|
4915
|
+
serverRows = computed(() => {
|
|
4916
|
+
const s = this.server();
|
|
4917
|
+
return [
|
|
4918
|
+
{ labelKey: 'common_about_environment', value: s.environment ?? '' },
|
|
4919
|
+
{ labelKey: 'common_about_runtime', value: s.runtime ?? '' },
|
|
4920
|
+
{ labelKey: 'common_about_version', value: s.version ?? '' },
|
|
4921
|
+
].filter(row => !!row.value);
|
|
4922
|
+
}, ...(ngDevMode ? [{ debugName: "serverRows" }] : /* istanbul ignore next */ []));
|
|
4923
|
+
serverPackages = computed(() => this.server().packages ?? [], ...(ngDevMode ? [{ debugName: "serverPackages" }] : /* istanbul ignore next */ []));
|
|
4924
|
+
hasServer = computed(() => this.serverRows().length > 0 || this.serverPackages().length > 0, ...(ngDevMode ? [{ debugName: "hasServer" }] : /* istanbul ignore next */ []));
|
|
4905
4925
|
/** A footer button, not only the header ✕: a thumb needs a real target. */
|
|
4906
4926
|
closeAction = [
|
|
4907
4927
|
{ labelKey: 'common_close', severity: 'ghost' },
|
|
4908
4928
|
];
|
|
4909
4929
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfAboutDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4910
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfAboutDialogComponent, isStandalone: true, selector: "ef-about-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, edition: { classPropertyName: "edition", publicName: "edition", isSignal: true, isRequired: false, transformFunction: null }, logoUrl: { classPropertyName: "logoUrl", publicName: "logoUrl", isSignal: true, isRequired: false, transformFunction: null }, initial: { classPropertyName: "initial", publicName: "initial", isSignal: true, isRequired: false, transformFunction: null }, owner: { classPropertyName: "owner", publicName: "owner", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, ngImport: i0, template: "<!-- appendTo=\"body\": ef-app-main is `overflow: hidden`, so a dialog left in\n place inside the content column is clipped by it. -->\n<ef-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n headerKey=\"common_about\"\n size=\"sm\"\n appendTo=\"body\"\n dismissableMask\n [actions]=\"closeAction\"\n>\n <div class=\"ef-about\">\n <span class=\"ef-about__mark\" aria-hidden=\"true\">\n @if (logoUrl()) {\n <img [src]=\"logoUrl()\" alt=\"\" />\n } @else {\n {{ initial() }}\n }\n </span>\n\n <p class=\"ef-about__product\">{{ product() }}</p>\n @if (edition()) {\n <p class=\"ef-about__edition\">{{ edition() }}</p>\n }\n\n @if (rows().length) {\n <dl class=\"ef-about__rows\">\n @for (row of rows(); track row.labelKey) {\n <div class=\"ef-about__row\">\n <dt>{{ row.labelKey | translate }}</dt>\n <dd>{{ row.value }}</dd>\n </div>\n }\n </dl>\n }\n\n @if (packages().length) {\n <h3 class=\"ef-about__group\">{{ 'common_about_packages' | translate }}</h3>\n <dl class=\"ef-about__rows ef-about__rows--
|
|
4930
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfAboutDialogComponent, isStandalone: true, selector: "ef-about-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, edition: { classPropertyName: "edition", publicName: "edition", isSignal: true, isRequired: false, transformFunction: null }, organisation: { classPropertyName: "organisation", publicName: "organisation", isSignal: true, isRequired: false, transformFunction: null }, server: { classPropertyName: "server", publicName: "server", isSignal: true, isRequired: false, transformFunction: null }, websiteUrl: { classPropertyName: "websiteUrl", publicName: "websiteUrl", isSignal: true, isRequired: false, transformFunction: null }, websiteLabel: { classPropertyName: "websiteLabel", publicName: "websiteLabel", isSignal: true, isRequired: false, transformFunction: null }, logoUrl: { classPropertyName: "logoUrl", publicName: "logoUrl", isSignal: true, isRequired: false, transformFunction: null }, initial: { classPropertyName: "initial", publicName: "initial", isSignal: true, isRequired: false, transformFunction: null }, owner: { classPropertyName: "owner", publicName: "owner", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, ngImport: i0, template: "<!-- appendTo=\"body\": ef-app-main is `overflow: hidden`, so a dialog left in\n place inside the content column is clipped by it. -->\n<ef-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n headerKey=\"common_about\"\n size=\"sm\"\n appendTo=\"body\"\n dismissableMask\n [actions]=\"closeAction\"\n>\n <div class=\"ef-about\">\n <span class=\"ef-about__mark\" aria-hidden=\"true\">\n @if (logoUrl()) {\n <img [src]=\"logoUrl()\" alt=\"\" />\n } @else {\n {{ initial() }}\n }\n </span>\n\n <p class=\"ef-about__product\">{{ product() }}</p>\n @if (edition()) {\n <p class=\"ef-about__edition\">{{ edition() }}</p>\n }\n\n @if (rows().length) {\n <dl class=\"ef-about__rows\">\n @for (row of rows(); track row.labelKey) {\n <div class=\"ef-about__row\">\n <dt>{{ row.labelKey | translate }}</dt>\n <dd>{{ row.value }}</dd>\n </div>\n }\n </dl>\n }\n\n @if (packages().length) {\n <h3 class=\"ef-about__group\">{{ 'common_about_packages' | translate }}</h3>\n <dl class=\"ef-about__rows ef-about__rows--tight\">\n @for (pkg of packages(); track pkg.name) {\n <div class=\"ef-about__row\">\n <dt>{{ pkg.name }}</dt>\n <dd>{{ pkg.version }}</dd>\n </div>\n }\n </dl>\n }\n\n <!-- The API's half of the answer. An app that exposes no such endpoint\n passes no [server] and this whole block collapses. -->\n @if (hasServer()) {\n <h3 class=\"ef-about__group\">{{ 'common_about_server' | translate }}</h3>\n <dl class=\"ef-about__rows ef-about__rows--tight\">\n @for (row of serverRows(); track row.labelKey) {\n <div class=\"ef-about__row\">\n <dt>{{ row.labelKey | translate }}</dt>\n <dd>{{ row.value }}</dd>\n </div>\n }\n @for (pkg of serverPackages(); track pkg.name) {\n <div class=\"ef-about__row\">\n <dt>{{ pkg.name }}</dt>\n <dd>{{ pkg.version }}</dd>\n </div>\n }\n </dl>\n }\n\n @if (websiteUrl()) {\n <a\n class=\"ef-about__link\"\n [href]=\"websiteUrl()\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span>{{ websiteLabel() || websiteUrl() }}</span>\n <i class=\"pi pi-external-link\" aria-hidden=\"true\"></i>\n </a>\n }\n\n <p class=\"ef-about__owner\">\u00A9 {{ year }} {{ owner() }}</p>\n </div>\n</ef-dialog>\n", styles: ["@charset \"UTF-8\";:host{display:contents}.ef-about{display:grid;justify-items:center;gap:10px;text-align:center}.ef-about__mark{display:grid;place-items:center;width:56px;height:56px;border-radius:var(--r-pill, 999px);background:var(--tenant-500);color:#fff;font-family:Bricolage Grotesque,system-ui,sans-serif;font-variation-settings:\"opsz\" 12,\"wght\" 700,\"wdth\" 80;font-size:22px;line-height:1;overflow:hidden}.ef-about__mark img{width:100%;height:100%;object-fit:cover}.ef-about__product{margin:2px 0 0;font-family:Bricolage Grotesque,system-ui,sans-serif;font-variation-settings:\"opsz\" 14,\"wght\" 700,\"wdth\" 90;font-size:20px;letter-spacing:-.02em;color:var(--text)}.ef-about__edition{margin:-6px 0 0;max-width:100%;font-size:12px;color:var(--text-mute);overflow-wrap:anywhere}.ef-about__rows{width:100%;min-width:0;margin:0;padding:12px 0 0;display:grid;gap:7px;border-top:1px solid var(--rule);text-align:start}.ef-about__row{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:baseline}.ef-about__row dt{min-width:0;font-size:12px;color:var(--text-mute);overflow-wrap:anywhere}.ef-about__row dd{min-width:0;margin:0;font-family:JetBrains Mono,ui-monospace,monospace;font-size:11.5px;color:var(--text);text-align:end;overflow-wrap:anywhere}.ef-about__rows--tight{padding-top:0;border-top:0}.ef-about__group{width:100%;margin:4px 0 0;padding-top:12px;border-top:1px solid var(--rule);font-family:JetBrains Mono,ui-monospace,monospace;font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.22em;color:var(--text-soft);text-align:start}.ef-about__link{display:inline-flex;align-items:center;gap:6px;min-height:40px;margin-top:2px;padding:0 10px;border-radius:var(--r-pill, 999px);color:var(--tenant-600, var(--tenant-500));font-size:12.5px;font-weight:700;text-decoration:none}.ef-about__link i{font-size:11px;opacity:.75}.ef-about__link:hover{background:color-mix(in srgb,var(--tenant-500) 10%,transparent);text-decoration:underline}.ef-about__link:focus-visible{outline:2px solid var(--tenant-400);outline-offset:2px}.ef-about__owner{margin:6px 0 0;font-size:11px;color:var(--text-soft)}@media(max-width:767px){.ef-about__mark{width:48px;height:48px;font-size:19px}.ef-about__link{min-height:var(--hit-touch, 48px)}}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfDialogComponent, selector: "ef-dialog", inputs: ["header", "headerKey", "subtitle", "subtitleKey", "visible", "modal", "closable", "draggable", "resizable", "dismissableMask", "closeOnEscape", "severity", "icon", "size", "style", "styleClass", "position", "appendTo", "variant", "actions", "defaultActions", "saveLabelKey", "cancelLabelKey", "saveLabel", "cancelLabel", "saveIcon", "cancelIcon", "saveDisabled", "saveStyleClass", "cancelStyleClass", "saveSeverity", "cancelSeverity"], outputs: ["visibleChange", "showEvent", "hideEvent", "saveAction", "cancelAction", "actionClick"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4911
4931
|
}
|
|
4912
4932
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfAboutDialogComponent, decorators: [{
|
|
4913
4933
|
type: Component,
|
|
4914
|
-
args: [{ selector: 'ef-about-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslateModule, EfDialogComponent], template: "<!-- appendTo=\"body\": ef-app-main is `overflow: hidden`, so a dialog left in\n place inside the content column is clipped by it. -->\n<ef-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n headerKey=\"common_about\"\n size=\"sm\"\n appendTo=\"body\"\n dismissableMask\n [actions]=\"closeAction\"\n>\n <div class=\"ef-about\">\n <span class=\"ef-about__mark\" aria-hidden=\"true\">\n @if (logoUrl()) {\n <img [src]=\"logoUrl()\" alt=\"\" />\n } @else {\n {{ initial() }}\n }\n </span>\n\n <p class=\"ef-about__product\">{{ product() }}</p>\n @if (edition()) {\n <p class=\"ef-about__edition\">{{ edition() }}</p>\n }\n\n @if (rows().length) {\n <dl class=\"ef-about__rows\">\n @for (row of rows(); track row.labelKey) {\n <div class=\"ef-about__row\">\n <dt>{{ row.labelKey | translate }}</dt>\n <dd>{{ row.value }}</dd>\n </div>\n }\n </dl>\n }\n\n @if (packages().length) {\n <h3 class=\"ef-about__group\">{{ 'common_about_packages' | translate }}</h3>\n <dl class=\"ef-about__rows ef-about__rows--
|
|
4915
|
-
}], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], product: [{ type: i0.Input, args: [{ isSignal: true, alias: "product", required: false }] }], edition: [{ type: i0.Input, args: [{ isSignal: true, alias: "edition", required: false }] }], logoUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoUrl", required: false }] }], initial: [{ type: i0.Input, args: [{ isSignal: true, alias: "initial", required: false }] }], owner: [{ type: i0.Input, args: [{ isSignal: true, alias: "owner", required: false }] }] } });
|
|
4934
|
+
args: [{ selector: 'ef-about-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslateModule, EfDialogComponent], template: "<!-- appendTo=\"body\": ef-app-main is `overflow: hidden`, so a dialog left in\n place inside the content column is clipped by it. -->\n<ef-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n headerKey=\"common_about\"\n size=\"sm\"\n appendTo=\"body\"\n dismissableMask\n [actions]=\"closeAction\"\n>\n <div class=\"ef-about\">\n <span class=\"ef-about__mark\" aria-hidden=\"true\">\n @if (logoUrl()) {\n <img [src]=\"logoUrl()\" alt=\"\" />\n } @else {\n {{ initial() }}\n }\n </span>\n\n <p class=\"ef-about__product\">{{ product() }}</p>\n @if (edition()) {\n <p class=\"ef-about__edition\">{{ edition() }}</p>\n }\n\n @if (rows().length) {\n <dl class=\"ef-about__rows\">\n @for (row of rows(); track row.labelKey) {\n <div class=\"ef-about__row\">\n <dt>{{ row.labelKey | translate }}</dt>\n <dd>{{ row.value }}</dd>\n </div>\n }\n </dl>\n }\n\n @if (packages().length) {\n <h3 class=\"ef-about__group\">{{ 'common_about_packages' | translate }}</h3>\n <dl class=\"ef-about__rows ef-about__rows--tight\">\n @for (pkg of packages(); track pkg.name) {\n <div class=\"ef-about__row\">\n <dt>{{ pkg.name }}</dt>\n <dd>{{ pkg.version }}</dd>\n </div>\n }\n </dl>\n }\n\n <!-- The API's half of the answer. An app that exposes no such endpoint\n passes no [server] and this whole block collapses. -->\n @if (hasServer()) {\n <h3 class=\"ef-about__group\">{{ 'common_about_server' | translate }}</h3>\n <dl class=\"ef-about__rows ef-about__rows--tight\">\n @for (row of serverRows(); track row.labelKey) {\n <div class=\"ef-about__row\">\n <dt>{{ row.labelKey | translate }}</dt>\n <dd>{{ row.value }}</dd>\n </div>\n }\n @for (pkg of serverPackages(); track pkg.name) {\n <div class=\"ef-about__row\">\n <dt>{{ pkg.name }}</dt>\n <dd>{{ pkg.version }}</dd>\n </div>\n }\n </dl>\n }\n\n @if (websiteUrl()) {\n <a\n class=\"ef-about__link\"\n [href]=\"websiteUrl()\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span>{{ websiteLabel() || websiteUrl() }}</span>\n <i class=\"pi pi-external-link\" aria-hidden=\"true\"></i>\n </a>\n }\n\n <p class=\"ef-about__owner\">\u00A9 {{ year }} {{ owner() }}</p>\n </div>\n</ef-dialog>\n", styles: ["@charset \"UTF-8\";:host{display:contents}.ef-about{display:grid;justify-items:center;gap:10px;text-align:center}.ef-about__mark{display:grid;place-items:center;width:56px;height:56px;border-radius:var(--r-pill, 999px);background:var(--tenant-500);color:#fff;font-family:Bricolage Grotesque,system-ui,sans-serif;font-variation-settings:\"opsz\" 12,\"wght\" 700,\"wdth\" 80;font-size:22px;line-height:1;overflow:hidden}.ef-about__mark img{width:100%;height:100%;object-fit:cover}.ef-about__product{margin:2px 0 0;font-family:Bricolage Grotesque,system-ui,sans-serif;font-variation-settings:\"opsz\" 14,\"wght\" 700,\"wdth\" 90;font-size:20px;letter-spacing:-.02em;color:var(--text)}.ef-about__edition{margin:-6px 0 0;max-width:100%;font-size:12px;color:var(--text-mute);overflow-wrap:anywhere}.ef-about__rows{width:100%;min-width:0;margin:0;padding:12px 0 0;display:grid;gap:7px;border-top:1px solid var(--rule);text-align:start}.ef-about__row{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:baseline}.ef-about__row dt{min-width:0;font-size:12px;color:var(--text-mute);overflow-wrap:anywhere}.ef-about__row dd{min-width:0;margin:0;font-family:JetBrains Mono,ui-monospace,monospace;font-size:11.5px;color:var(--text);text-align:end;overflow-wrap:anywhere}.ef-about__rows--tight{padding-top:0;border-top:0}.ef-about__group{width:100%;margin:4px 0 0;padding-top:12px;border-top:1px solid var(--rule);font-family:JetBrains Mono,ui-monospace,monospace;font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.22em;color:var(--text-soft);text-align:start}.ef-about__link{display:inline-flex;align-items:center;gap:6px;min-height:40px;margin-top:2px;padding:0 10px;border-radius:var(--r-pill, 999px);color:var(--tenant-600, var(--tenant-500));font-size:12.5px;font-weight:700;text-decoration:none}.ef-about__link i{font-size:11px;opacity:.75}.ef-about__link:hover{background:color-mix(in srgb,var(--tenant-500) 10%,transparent);text-decoration:underline}.ef-about__link:focus-visible{outline:2px solid var(--tenant-400);outline-offset:2px}.ef-about__owner{margin:6px 0 0;font-size:11px;color:var(--text-soft)}@media(max-width:767px){.ef-about__mark{width:48px;height:48px;font-size:19px}.ef-about__link{min-height:var(--hit-touch, 48px)}}\n"] }]
|
|
4935
|
+
}], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], product: [{ type: i0.Input, args: [{ isSignal: true, alias: "product", required: false }] }], edition: [{ type: i0.Input, args: [{ isSignal: true, alias: "edition", required: false }] }], organisation: [{ type: i0.Input, args: [{ isSignal: true, alias: "organisation", required: false }] }], server: [{ type: i0.Input, args: [{ isSignal: true, alias: "server", required: false }] }], websiteUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "websiteUrl", required: false }] }], websiteLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "websiteLabel", required: false }] }], logoUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoUrl", required: false }] }], initial: [{ type: i0.Input, args: [{ isSignal: true, alias: "initial", required: false }] }], owner: [{ type: i0.Input, args: [{ isSignal: true, alias: "owner", required: false }] }] } });
|
|
4936
|
+
|
|
4937
|
+
/**
|
|
4938
|
+
* The keyboard-shortcuts reference: every registration currently sitting
|
|
4939
|
+
* in `EfShortcutService`, grouped and rendered with the same `.kbd` chip
|
|
4940
|
+
* `ef-row-actions` and `ef-menu` already use, so a chip means one thing
|
|
4941
|
+
* everywhere it appears.
|
|
4942
|
+
*
|
|
4943
|
+
* Reads `EfShortcutService.list()` directly, so it stays live: open it
|
|
4944
|
+
* while a row menu is on screen and its row-scoped shortcuts are already
|
|
4945
|
+
* listed under "Row actions". Close the row menu and, since a row's
|
|
4946
|
+
* shortcuts unregister with it, they're gone from here too.
|
|
4947
|
+
*
|
|
4948
|
+
* ```html
|
|
4949
|
+
* <ef-shortcuts-dialog [(visible)]="shortcutsOpen" />
|
|
4950
|
+
* ```
|
|
4951
|
+
*/
|
|
4952
|
+
class EfShortcutsDialogComponent {
|
|
4953
|
+
shortcutService = inject(EfShortcutService);
|
|
4954
|
+
/** Two-way open state. */
|
|
4955
|
+
visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
4956
|
+
groups = this.shortcutService.list;
|
|
4957
|
+
/** Only macOS reads `⌘` at a glance. Everyone else needs the line
|
|
4958
|
+
* spelling out that it means Ctrl. */
|
|
4959
|
+
isMacPlatform = isMacPlatform;
|
|
4960
|
+
closeAction = [
|
|
4961
|
+
{ labelKey: 'common_close', severity: 'ghost' },
|
|
4962
|
+
];
|
|
4963
|
+
formatKeys(keys) {
|
|
4964
|
+
return formatShortcut(keys);
|
|
4965
|
+
}
|
|
4966
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfShortcutsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4967
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfShortcutsDialogComponent, isStandalone: true, selector: "ef-shortcuts-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, ngImport: i0, template: "<!-- appendTo=\"body\": a dialog left inside the content column can be clipped\n by an ancestor's overflow rule (see ef-about-dialog). -->\n<ef-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n headerKey=\"shortcuts_dialog_title\"\n size=\"sm\"\n appendTo=\"body\"\n dismissableMask\n [actions]=\"closeAction\"\n>\n <div class=\"shortcuts-dialog\">\n @if (!isMacPlatform) {\n <p class=\"shortcuts-dialog__hint\">{{ 'shortcuts_dialog_mod_hint' | translate }}</p>\n }\n\n @if (groups().length) {\n @for (group of groups(); track group.group) {\n <section class=\"shortcuts-dialog__group\">\n <h3 class=\"shortcuts-dialog__group-title\">{{ group.group | translate }}</h3>\n <ul class=\"shortcuts-dialog__list\">\n @for (shortcut of group.shortcuts; track shortcut.id) {\n <li class=\"shortcuts-dialog__item\">\n <span class=\"lbl\">{{ shortcut.labelKey | translate }}</span>\n <!-- Not aria-hidden here: the key IS the content this\n dialog exists to say. Hiding it would leave a\n screen-reader user hearing the action names and\n never the shortcut that triggers them. -->\n <span class=\"kbd\">{{ formatKeys(shortcut.keys) }}</span>\n </li>\n }\n </ul>\n </section>\n }\n } @else {\n <p class=\"shortcuts-dialog__empty\">{{ 'shortcuts_dialog_empty' | translate }}</p>\n }\n </div>\n</ef-dialog>\n", styles: [":host{display:contents}.shortcuts-dialog{display:grid;gap:16px}.shortcuts-dialog__hint{margin:0;padding:8px 10px;border-radius:8px;background:var(--paper-soft, var(--paper));border:1px solid var(--rule);font-size:12px;color:var(--text-mute)}.shortcuts-dialog__empty{margin:0;padding:12px 0;font-size:13px;color:var(--text-mute);text-align:center}.shortcuts-dialog__group+.shortcuts-dialog__group{padding-top:12px;border-top:1px solid var(--rule)}.shortcuts-dialog__group-title{margin:0 0 8px;font-family:JetBrains Mono,ui-monospace,monospace;font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.22em;color:var(--text-soft)}.shortcuts-dialog__list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.shortcuts-dialog__item{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}.shortcuts-dialog__item .lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;color:var(--text)}.shortcuts-dialog__item .kbd{flex:none;font-family:JetBrains Mono,monospace;font-size:10px;font-weight:600;color:var(--text-mute);background:var(--paper);border:1px solid var(--rule);border-radius:6px;padding:2px 6px;line-height:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfDialogComponent, selector: "ef-dialog", inputs: ["header", "headerKey", "subtitle", "subtitleKey", "visible", "modal", "closable", "draggable", "resizable", "dismissableMask", "closeOnEscape", "severity", "icon", "size", "style", "styleClass", "position", "appendTo", "variant", "actions", "defaultActions", "saveLabelKey", "cancelLabelKey", "saveLabel", "cancelLabel", "saveIcon", "cancelIcon", "saveDisabled", "saveStyleClass", "cancelStyleClass", "saveSeverity", "cancelSeverity"], outputs: ["visibleChange", "showEvent", "hideEvent", "saveAction", "cancelAction", "actionClick"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4968
|
+
}
|
|
4969
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfShortcutsDialogComponent, decorators: [{
|
|
4970
|
+
type: Component,
|
|
4971
|
+
args: [{ selector: 'ef-shortcuts-dialog', standalone: true, imports: [CommonModule, TranslateModule, EfDialogComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- appendTo=\"body\": a dialog left inside the content column can be clipped\n by an ancestor's overflow rule (see ef-about-dialog). -->\n<ef-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visible.set($event)\"\n headerKey=\"shortcuts_dialog_title\"\n size=\"sm\"\n appendTo=\"body\"\n dismissableMask\n [actions]=\"closeAction\"\n>\n <div class=\"shortcuts-dialog\">\n @if (!isMacPlatform) {\n <p class=\"shortcuts-dialog__hint\">{{ 'shortcuts_dialog_mod_hint' | translate }}</p>\n }\n\n @if (groups().length) {\n @for (group of groups(); track group.group) {\n <section class=\"shortcuts-dialog__group\">\n <h3 class=\"shortcuts-dialog__group-title\">{{ group.group | translate }}</h3>\n <ul class=\"shortcuts-dialog__list\">\n @for (shortcut of group.shortcuts; track shortcut.id) {\n <li class=\"shortcuts-dialog__item\">\n <span class=\"lbl\">{{ shortcut.labelKey | translate }}</span>\n <!-- Not aria-hidden here: the key IS the content this\n dialog exists to say. Hiding it would leave a\n screen-reader user hearing the action names and\n never the shortcut that triggers them. -->\n <span class=\"kbd\">{{ formatKeys(shortcut.keys) }}</span>\n </li>\n }\n </ul>\n </section>\n }\n } @else {\n <p class=\"shortcuts-dialog__empty\">{{ 'shortcuts_dialog_empty' | translate }}</p>\n }\n </div>\n</ef-dialog>\n", styles: [":host{display:contents}.shortcuts-dialog{display:grid;gap:16px}.shortcuts-dialog__hint{margin:0;padding:8px 10px;border-radius:8px;background:var(--paper-soft, var(--paper));border:1px solid var(--rule);font-size:12px;color:var(--text-mute)}.shortcuts-dialog__empty{margin:0;padding:12px 0;font-size:13px;color:var(--text-mute);text-align:center}.shortcuts-dialog__group+.shortcuts-dialog__group{padding-top:12px;border-top:1px solid var(--rule)}.shortcuts-dialog__group-title{margin:0 0 8px;font-family:JetBrains Mono,ui-monospace,monospace;font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.22em;color:var(--text-soft)}.shortcuts-dialog__list{display:grid;gap:6px;margin:0;padding:0;list-style:none}.shortcuts-dialog__item{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}.shortcuts-dialog__item .lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;color:var(--text)}.shortcuts-dialog__item .kbd{flex:none;font-family:JetBrains Mono,monospace;font-size:10px;font-weight:600;color:var(--text-mute);background:var(--paper);border:1px solid var(--rule);border-radius:6px;padding:2px 6px;line-height:1}\n"] }]
|
|
4972
|
+
}], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }] } });
|
|
4916
4973
|
|
|
4917
4974
|
class EfFieldsetComponent {
|
|
4918
4975
|
/** Direct legend text (not translated) */
|
|
@@ -6189,6 +6246,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
6189
6246
|
type: Output
|
|
6190
6247
|
}] } });
|
|
6191
6248
|
|
|
6249
|
+
/**
|
|
6250
|
+
* The signed-in user's menu.
|
|
6251
|
+
*
|
|
6252
|
+
* Two renderings of one `items` array. `variant="chip"` (the default) shows
|
|
6253
|
+
* an `ef-profile-chip` that opens a popover, for the side footer on a
|
|
6254
|
+
* desktop. `variant="list"` renders the same rows flat, with no popover,
|
|
6255
|
+
* for the mobile sheet: `ef-app-shell` does not render the side footer on a
|
|
6256
|
+
* phone, and this menu is the only way to sign out, so it cannot live only
|
|
6257
|
+
* there.
|
|
6258
|
+
*
|
|
6259
|
+
* ```html
|
|
6260
|
+
* <ef-profile-menu
|
|
6261
|
+
* side-footer
|
|
6262
|
+
* [name]="userName()"
|
|
6263
|
+
* [secondary]="userEmail()"
|
|
6264
|
+
* [initial]="userInitial()"
|
|
6265
|
+
* [items]="menuItems()"
|
|
6266
|
+
* />
|
|
6267
|
+
* ```
|
|
6268
|
+
*/
|
|
6269
|
+
class EfProfileMenuComponent {
|
|
6270
|
+
/** Display name, shown on the chip and in the panel header. */
|
|
6271
|
+
name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
6272
|
+
/** Second header line. The email, usually. */
|
|
6273
|
+
secondary = input('', ...(ngDevMode ? [{ debugName: "secondary" }] : /* istanbul ignore next */ []));
|
|
6274
|
+
/** Chip subtitle. Falls back to `secondary` when empty. */
|
|
6275
|
+
role = input('', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
|
|
6276
|
+
/** Avatar glyph. Up to two characters; falls back to the first of `name`. */
|
|
6277
|
+
initial = input('', ...(ngDevMode ? [{ debugName: "initial" }] : /* istanbul ignore next */ []));
|
|
6278
|
+
tone = input('tenant', ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
6279
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
6280
|
+
variant = input('chip', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
6281
|
+
itemSelected = output();
|
|
6282
|
+
/** Id of the one expanded group, or null. One at a time: a menu that
|
|
6283
|
+
* grows in two directions at once stops being scannable. */
|
|
6284
|
+
expandedId = signal(null, ...(ngDevMode ? [{ debugName: "expandedId" }] : /* istanbul ignore next */ []));
|
|
6285
|
+
chipRole = computed(() => this.role() || this.secondary(), ...(ngDevMode ? [{ debugName: "chipRole" }] : /* istanbul ignore next */ []));
|
|
6286
|
+
isExpanded(id) {
|
|
6287
|
+
return this.expandedId() === id;
|
|
6288
|
+
}
|
|
6289
|
+
/**
|
|
6290
|
+
* Choose a row. A row with children toggles its group and leaves the
|
|
6291
|
+
* popover open; a leaf runs its command, reports it, and dismisses.
|
|
6292
|
+
*/
|
|
6293
|
+
select(item, popover) {
|
|
6294
|
+
if (item.children?.length) {
|
|
6295
|
+
this.expandedId.update((current) => (current === item.id ? null : item.id));
|
|
6296
|
+
// Reposition once the taller panel has actually rendered. Without this
|
|
6297
|
+
// the panel keeps the top it was placed at and grows downward, which
|
|
6298
|
+
// runs it off the bottom of the screen when the trigger sits in the
|
|
6299
|
+
// side footer. Realigning lets it grow upward from the trigger instead.
|
|
6300
|
+
setTimeout(() => popover?.align?.(), 0);
|
|
6301
|
+
return;
|
|
6302
|
+
}
|
|
6303
|
+
item.command?.();
|
|
6304
|
+
this.itemSelected.emit(item);
|
|
6305
|
+
popover?.hide();
|
|
6306
|
+
}
|
|
6307
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6308
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfProfileMenuComponent, isStandalone: true, selector: "ef-profile-menu", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, secondary: { classPropertyName: "secondary", publicName: "secondary", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, initial: { classPropertyName: "initial", publicName: "initial", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, ngImport: i0, template: "@if (variant() === 'chip') {\n <ef-profile-chip\n [name]=\"name()\"\n [role]=\"chipRole()\"\n [initial]=\"initial()\"\n [tone]=\"tone()\"\n (clickEvent)=\"op.toggle($event)\"\n />\n <!-- The popover is reduced to a placement mechanism: `.ef-menu` inside it\n draws the surface, so `ef-menu-popover` strips PrimeNG's own panel and\n arrow rather than letting two panels stack. -->\n <p-popover #op styleClass=\"ef-menu-popover\" appendTo=\"body\">\n <ng-container *ngTemplateOutlet=\"panel; context: { $implicit: op }\" />\n </p-popover>\n} @else {\n <ng-container *ngTemplateOutlet=\"panel\" />\n}\n\n<ng-template #panel let-op>\n <div class=\"ef-menu\" role=\"menu\" [attr.aria-label]=\"name() || null\">\n @if (name() || secondary()) {\n <div class=\"ef-menu__head\">\n @if (name()) {\n <span class=\"ef-menu__head-name\">{{ name() }}</span>\n }\n @if (secondary()) {\n <span class=\"ef-menu__head-sub\">{{ secondary() }}</span>\n }\n </div>\n }\n\n @for (item of items(); track item.id) {\n @if (item.groupStart) {\n <div class=\"ef-menu__divider\" role=\"separator\"></div>\n }\n\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n [class.danger]=\"item.severity === 'danger'\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"select(item, op)\"\n >\n @if (item.icon) {\n <i [class]=\"'ico ' + item.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-menu__badge\">{{ item.badge }}</span>\n }\n @if (item.children?.length) {\n <i\n class=\"ef-menu__caret pi\"\n [class.pi-chevron-down]=\"!isExpanded(item.id)\"\n [class.pi-chevron-up]=\"isExpanded(item.id)\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <div class=\"ef-menu__sublist\" role=\"group\">\n @for (child of item.children; track child.id) {\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n (click)=\"select(child, op)\"\n >\n @if (child.icon) {\n <i [class]=\"'ico ' + child.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ child.labelKey | translate }}</span>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-width:0}.ef-menu{min-width:232px;max-width:288px;max-height:calc(100vh - 32px);overflow-y:auto}@media(max-width:767px){.ef-menu{min-width:0}.ef-menu__item{min-height:var(--hit-touch);padding-block:0;font-size:14px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: EfProfileChipComponent, selector: "ef-profile-chip", inputs: ["name", "role", "roleKey", "initial", "tone", "readonly"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6309
|
+
}
|
|
6310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileMenuComponent, decorators: [{
|
|
6311
|
+
type: Component,
|
|
6312
|
+
args: [{ selector: 'ef-profile-menu', standalone: true, imports: [CommonModule, TranslateModule, PopoverModule, EfProfileChipComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (variant() === 'chip') {\n <ef-profile-chip\n [name]=\"name()\"\n [role]=\"chipRole()\"\n [initial]=\"initial()\"\n [tone]=\"tone()\"\n (clickEvent)=\"op.toggle($event)\"\n />\n <!-- The popover is reduced to a placement mechanism: `.ef-menu` inside it\n draws the surface, so `ef-menu-popover` strips PrimeNG's own panel and\n arrow rather than letting two panels stack. -->\n <p-popover #op styleClass=\"ef-menu-popover\" appendTo=\"body\">\n <ng-container *ngTemplateOutlet=\"panel; context: { $implicit: op }\" />\n </p-popover>\n} @else {\n <ng-container *ngTemplateOutlet=\"panel\" />\n}\n\n<ng-template #panel let-op>\n <div class=\"ef-menu\" role=\"menu\" [attr.aria-label]=\"name() || null\">\n @if (name() || secondary()) {\n <div class=\"ef-menu__head\">\n @if (name()) {\n <span class=\"ef-menu__head-name\">{{ name() }}</span>\n }\n @if (secondary()) {\n <span class=\"ef-menu__head-sub\">{{ secondary() }}</span>\n }\n </div>\n }\n\n @for (item of items(); track item.id) {\n @if (item.groupStart) {\n <div class=\"ef-menu__divider\" role=\"separator\"></div>\n }\n\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n [class.danger]=\"item.severity === 'danger'\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"select(item, op)\"\n >\n @if (item.icon) {\n <i [class]=\"'ico ' + item.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-menu__badge\">{{ item.badge }}</span>\n }\n @if (item.children?.length) {\n <i\n class=\"ef-menu__caret pi\"\n [class.pi-chevron-down]=\"!isExpanded(item.id)\"\n [class.pi-chevron-up]=\"isExpanded(item.id)\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <div class=\"ef-menu__sublist\" role=\"group\">\n @for (child of item.children; track child.id) {\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n (click)=\"select(child, op)\"\n >\n @if (child.icon) {\n <i [class]=\"'ico ' + child.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ child.labelKey | translate }}</span>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-width:0}.ef-menu{min-width:232px;max-width:288px;max-height:calc(100vh - 32px);overflow-y:auto}@media(max-width:767px){.ef-menu{min-width:0}.ef-menu__item{min-height:var(--hit-touch);padding-block:0;font-size:14px}}\n"] }]
|
|
6313
|
+
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], secondary: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondary", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], initial: [{ type: i0.Input, args: [{ isSignal: true, alias: "initial", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
|
|
6314
|
+
|
|
6192
6315
|
class EfBlockUiComponent {
|
|
6193
6316
|
isLoading = false;
|
|
6194
6317
|
contentPanel;
|
|
@@ -8668,7 +8791,7 @@ class EfDatatableComponent {
|
|
|
8668
8791
|
return this.pTable?.filters;
|
|
8669
8792
|
}
|
|
8670
8793
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfDatatableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8671
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfDatatableComponent, isStandalone: true, selector: "ef-datatable", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, searchEntity: { classPropertyName: "searchEntity", publicName: "searchEntity", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, pt: { classPropertyName: "pt", publicName: "pt", isSignal: true, isRequired: false, transformFunction: null }, screenStateKey: { classPropertyName: "screenStateKey", publicName: "screenStateKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editRow: "editRow", deleteRow: "deleteRow", duplicateRow: "duplicateRow", lazyLoad: "lazyLoad", rowSelect: "rowSelect" }, viewQueries: [{ propertyName: "pTable", first: true, predicate: ["pTable"], descendants: true }], ngImport: i0, template: "<p-table #pTable\n [value]=\"searchEntity()?.items || []\"\n [columns]=\"processedColumns()\"\n [dataKey]=\"mergedConfig.dataKey\"\n\n [lazy]=\"mergedConfig.lazy\"\n (onLazyLoad)=\"handleLazyLoad($event)\"\n\n [paginator]=\"mergedConfig.paginator\"\n [rows]=\"searchEntity()?.pagination?.pageSize || mergedConfig.rows\"\n [rowsPerPageOptions]=\"mergedConfig.rowsPerPageOptions\"\n [totalRecords]=\"searchEntity()?.totalCount || 0\"\n [first]=\"searchEntity()?.pagination ? (searchEntity()!.pagination!.pageNumber - 1) * searchEntity()!.pagination!.pageSize : 0\"\n\n [scrollable]=\"mergedConfig.scrollable\"\n [scrollHeight]=\"mergedConfig.scrollHeight\"\n\n [resizableColumns]=\"mergedConfig.resizableColumns\"\n [columnResizeMode]=\"mergedConfig.columnResizeMode\"\n\n [stateStorage]=\"mergedConfig.stateStorage\"\n [stateKey]=\"mergedConfig.stateKey\"\n\n [size]=\"mergedConfig.size\"\n [class]=\"mergedConfig.styleClass\"\n [tableStyle]=\"mergedConfig.tableStyle\"\n\n [currentPageReportTemplate]=\"searchEntity()?.totalCount ? 'Affichage de {first} a {last} sur {totalRecords} entrees' : mergedConfig.emptyMessage\"\n [showCurrentPageReport]=\"true\"\n [sortField]=\"sortField()\"\n [sortOrder]=\"sortOrder()\"\n [loading]=\"loading()\"\n\n [pt]=\"pt()\"\n\n selectionMode=\"single\" [(selection)]=\"selectedItem\">\n\n <!-- Header Template -->\n <ng-template #header>\n <tr>\n <!-- Action column at start if configured -->\n @if (mergedActions.show && mergedActions.position === 'start') {\n <th [class]=\"mergedActions.width\"></th>\n }\n\n <!-- Data columns -->\n @for (column of processedColumns(); track column.field) {\n @if (column.sortable && column.resizable) {\n <th\n [pSortableColumn]=\"column.field\"\n pResizableColumn\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n <p-sortIcon [field]=\"column.field\" />\n }\n </th>\n } @else if (column.sortable) {\n <th\n [pSortableColumn]=\"column.field\"\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n <p-sortIcon [field]=\"column.field\" />\n }\n </th>\n } @else if (column.resizable) {\n <th\n pResizableColumn\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n }\n </th>\n } @else {\n <th\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n }\n </th>\n }\n }\n\n <!-- Action column at end if configured -->\n @if (mergedActions.show && mergedActions.position === 'end') {\n <th [class]=\"mergedActions.width\"></th>\n }\n </tr>\n </ng-template>\n\n <!-- Body Template -->\n <ng-template #body let-rowData let-rowIndex=\"rowIndex\">\n <tr (dblclick)=\"handleEdit(rowData)\" style=\"cursor: pointer\"\n [pSelectableRow]=\"rowData\" [pSelectableRowIndex]=\"rowIndex\">\n <!-- Action column at start if configured -->\n @if (mergedActions.show && mergedActions.position === 'start') {\n <td>\n <ef-datatable-actionbar\n [context]=\"context()\"\n (edit)=\"handleEdit(rowData)\"\n (delete)=\"handleDelete(rowData)\"\n (duplicate)=\"handleDuplicate(rowData)\">\n </ef-datatable-actionbar>\n </td>\n }\n\n <!-- Data columns -->\n @for (column of processedColumns(); track column.field) {\n <td [ngClass]=\"getAlignmentClass(column.align)\">\n @if (column.template) {\n <ng-container *ngTemplateOutlet=\"column.template; context: { $implicit: rowData, column: column }\"></ng-container>\n } @else {\n {{ formatCellValue(rowData, column) }}\n }\n </td>\n }\n\n <!-- Action column at end if configured -->\n @if (mergedActions.show && mergedActions.position === 'end') {\n <td>\n <ef-datatable-actionbar\n [context]=\"context()\"\n (edit)=\"handleEdit(rowData)\"\n (delete)=\"handleDelete(rowData)\"\n (duplicate)=\"handleDuplicate(rowData)\">\n </ef-datatable-actionbar>\n </td>\n }\n </tr>\n </ng-template>\n</p-table>\n", styles: [":host{display:block}:host ::ng-deep .text-end{text-align:right!important}:host ::ng-deep .text-center{text-align:center!important}:host ::ng-deep .text-start{text-align:left!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2$4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$4.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i2$4.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "directive", type: i2$4.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "component", type: i2$4.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfDatatableActionBarComponent, selector: "ef-datatable-actionbar", inputs: ["context", "state", "duplicateButton", "editButton", "deleteButton"], outputs: ["duplicate", "edit", "delete"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8794
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfDatatableComponent, isStandalone: true, selector: "ef-datatable", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, searchEntity: { classPropertyName: "searchEntity", publicName: "searchEntity", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, pt: { classPropertyName: "pt", publicName: "pt", isSignal: true, isRequired: false, transformFunction: null }, screenStateKey: { classPropertyName: "screenStateKey", publicName: "screenStateKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editRow: "editRow", deleteRow: "deleteRow", duplicateRow: "duplicateRow", lazyLoad: "lazyLoad", rowSelect: "rowSelect" }, viewQueries: [{ propertyName: "pTable", first: true, predicate: ["pTable"], descendants: true }], ngImport: i0, template: "<p-table #pTable\n [value]=\"searchEntity()?.items || []\"\n [columns]=\"processedColumns()\"\n [dataKey]=\"mergedConfig.dataKey\"\n\n [lazy]=\"mergedConfig.lazy\"\n (onLazyLoad)=\"handleLazyLoad($event)\"\n\n [paginator]=\"mergedConfig.paginator\"\n [rows]=\"searchEntity()?.pagination?.pageSize || mergedConfig.rows\"\n [rowsPerPageOptions]=\"mergedConfig.rowsPerPageOptions\"\n [totalRecords]=\"searchEntity()?.totalCount || 0\"\n [first]=\"searchEntity()?.pagination ? (searchEntity()!.pagination!.pageNumber - 1) * searchEntity()!.pagination!.pageSize : 0\"\n\n [scrollable]=\"mergedConfig.scrollable\"\n [scrollHeight]=\"mergedConfig.scrollHeight\"\n\n [resizableColumns]=\"mergedConfig.resizableColumns\"\n [columnResizeMode]=\"mergedConfig.columnResizeMode\"\n\n [stateStorage]=\"mergedConfig.stateStorage\"\n [stateKey]=\"mergedConfig.stateKey\"\n\n [size]=\"mergedConfig.size\"\n [class]=\"mergedConfig.styleClass\"\n [tableStyle]=\"mergedConfig.tableStyle\"\n\n [currentPageReportTemplate]=\"searchEntity()?.totalCount ? 'Affichage de {first} a {last} sur {totalRecords} entrees' : mergedConfig.emptyMessage\"\n [showCurrentPageReport]=\"true\"\n [sortField]=\"sortField()\"\n [sortOrder]=\"sortOrder()\"\n [loading]=\"loading()\"\n\n [pt]=\"pt()\"\n\n selectionMode=\"single\" [(selection)]=\"selectedItem\">\n\n <!-- Header Template -->\n <ng-template #header>\n <tr>\n <!-- Action column at start if configured -->\n @if (mergedActions.show && mergedActions.position === 'start') {\n <th [class]=\"mergedActions.width\"></th>\n }\n\n <!-- Data columns -->\n @for (column of processedColumns(); track column.field) {\n @if (column.sortable && column.resizable) {\n <th\n [pSortableColumn]=\"column.field\"\n pResizableColumn\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n <p-sortIcon [field]=\"column.field\" />\n }\n </th>\n } @else if (column.sortable) {\n <th\n [pSortableColumn]=\"column.field\"\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n <p-sortIcon [field]=\"column.field\" />\n }\n </th>\n } @else if (column.resizable) {\n <th\n pResizableColumn\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n }\n </th>\n } @else {\n <th\n [class]=\"column.width || ''\"\n [ngClass]=\"column.styleClass\">\n\n @if (column.headerTemplate) {\n <ng-container *ngTemplateOutlet=\"column.headerTemplate; context: { $implicit: column }\"></ng-container>\n } @else {\n {{ column.header | translate }}\n }\n </th>\n }\n }\n\n <!-- Action column at end if configured -->\n @if (mergedActions.show && mergedActions.position === 'end') {\n <th [class]=\"mergedActions.width\"></th>\n }\n </tr>\n </ng-template>\n\n <!-- Body Template -->\n <ng-template #body let-rowData let-rowIndex=\"rowIndex\">\n <tr (dblclick)=\"handleEdit(rowData)\" style=\"cursor: pointer\"\n [pSelectableRow]=\"rowData\" [pSelectableRowIndex]=\"rowIndex\">\n <!-- Action column at start if configured -->\n @if (mergedActions.show && mergedActions.position === 'start') {\n <td>\n <ef-datatable-actionbar\n [context]=\"context()\"\n (edit)=\"handleEdit(rowData)\"\n (delete)=\"handleDelete(rowData)\"\n (duplicate)=\"handleDuplicate(rowData)\">\n </ef-datatable-actionbar>\n </td>\n }\n\n <!-- Data columns -->\n @for (column of processedColumns(); track column.field) {\n <td [ngClass]=\"getAlignmentClass(column.align)\">\n @if (column.template) {\n <ng-container *ngTemplateOutlet=\"column.template; context: { $implicit: rowData, column: column }\"></ng-container>\n } @else {\n {{ formatCellValue(rowData, column) }}\n }\n </td>\n }\n\n <!-- Action column at end if configured -->\n @if (mergedActions.show && mergedActions.position === 'end') {\n <td>\n <ef-datatable-actionbar\n [context]=\"context()\"\n (edit)=\"handleEdit(rowData)\"\n (delete)=\"handleDelete(rowData)\"\n (duplicate)=\"handleDuplicate(rowData)\">\n </ef-datatable-actionbar>\n </td>\n }\n </tr>\n </ng-template>\n</p-table>\n", styles: [":host{display:block}:host ::ng-deep .text-end{text-align:right!important}:host ::ng-deep .text-center{text-align:center!important}:host ::ng-deep .text-start{text-align:left!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2$5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$5.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i2$5.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "directive", type: i2$5.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "component", type: i2$5.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfDatatableActionBarComponent, selector: "ef-datatable-actionbar", inputs: ["context", "state", "duplicateButton", "editButton", "deleteButton"], outputs: ["duplicate", "edit", "delete"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8672
8795
|
}
|
|
8673
8796
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfDatatableComponent, decorators: [{
|
|
8674
8797
|
type: Component,
|
|
@@ -8797,6 +8920,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8797
8920
|
args: [{ selector: 'ef-pager', standalone: true, imports: [CommonModule, TranslateModule, EfSelectComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"pager\">\n @if (!hideSize()) {\n <div class=\"size\">\n <span>{{ linesPerPageLabelKey() | translate }}</span>\n <ef-select\n size=\"small\"\n appendTo=\"body\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [options]=\"sizeOptions()\"\n [value]=\"pageSize()\"\n [ariaLabelKey]=\"linesPerPageLabelKey()\"\n [showClear]=\"false\"\n (selectionChangeEvent)=\"onSizeChange($event)\"\n />\n @if (totalCount() > 0) {\n <span>\u00B7 {{ range().start }}\u2013{{ range().end }} {{ ofLabelKey() | translate }} {{ totalCount() }}</span>\n }\n </div>\n } @else {\n <span></span>\n }\n\n <div class=\"pages\">\n <button\n class=\"pg\"\n type=\"button\"\n [disabled]=\"pageNumber() <= 1\"\n [attr.aria-label]=\"prevLabelKey() | translate\"\n (click)=\"goToPage(pageNumber() - 1)\"\n >\u2039</button>\n\n @for (btn of pageButtons(); track trackBtn($index, btn)) {\n @if (btn.kind === 'page') {\n <button\n class=\"pg\"\n type=\"button\"\n [class.active]=\"btn.value === pageNumber()\"\n (click)=\"goToPage(btn.value)\"\n >{{ btn.value }}</button>\n } @else {\n <span class=\"pg\" aria-hidden=\"true\" style=\"cursor: default;\">\u2026</span>\n }\n }\n\n <button\n class=\"pg\"\n type=\"button\"\n [disabled]=\"pageNumber() >= totalPages()\"\n [attr.aria-label]=\"nextLabelKey() | translate\"\n (click)=\"goToPage(pageNumber() + 1)\"\n >\u203A</button>\n </div>\n</div>\n" }]
|
|
8798
8921
|
}], propDecorators: { pageNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageNumber", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], totalCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalCount", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], linesPerPageLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "linesPerPageLabelKey", required: false }] }], ofLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "ofLabelKey", required: false }] }], prevLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevLabelKey", required: false }] }], nextLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabelKey", required: false }] }], hideSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSize", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }] } });
|
|
8799
8922
|
|
|
8923
|
+
/** Row-scoped shortcuts, wired once per instance and gated on `open()` so
|
|
8924
|
+
* they're inert until this row's menu is on screen. The action `id` is a
|
|
8925
|
+
* convention shared with `ef-data-card.defaultRowActions()`: an instance
|
|
8926
|
+
* with no matching item is simply a no-op for that key. */
|
|
8927
|
+
const ROW_SHORTCUTS = [
|
|
8928
|
+
{ actionId: 'view', keys: 'enter', labelKey: 'common_view' },
|
|
8929
|
+
{ actionId: 'edit', keys: 'e', labelKey: 'common_edit' },
|
|
8930
|
+
{ actionId: 'duplicate', keys: 'mod+d', labelKey: 'common_duplicate' },
|
|
8931
|
+
];
|
|
8800
8932
|
/**
|
|
8801
8933
|
* Row-actions dropdown — V2 successor to `ef-datatable-actionbar`.
|
|
8802
8934
|
*
|
|
@@ -8805,11 +8937,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8805
8937
|
*
|
|
8806
8938
|
* ```ts
|
|
8807
8939
|
* actions: ReadonlyArray<EfRowAction> = [
|
|
8808
|
-
* { id: 'view', labelKey: 'common_view', icon: 'pi pi-eye', kbd: '
|
|
8940
|
+
* { id: 'view', labelKey: 'common_view', icon: 'pi pi-eye', kbd: formatShortcut('enter'),
|
|
8809
8941
|
* permission: Permissions.Read, command: () => view(row) },
|
|
8810
|
-
* { id: 'edit', labelKey: 'common_edit', icon: 'pi pi-pencil', kbd: '
|
|
8942
|
+
* { id: 'edit', labelKey: 'common_edit', icon: 'pi pi-pencil', kbd: formatShortcut('e'),
|
|
8811
8943
|
* permission: Permissions.Edit, command: () => edit(row) },
|
|
8812
|
-
* { id: 'duplicate', labelKey: 'common_duplicate', icon: 'pi pi-copy',
|
|
8944
|
+
* { id: 'duplicate', labelKey: 'common_duplicate', icon: 'pi pi-copy', kbd: formatShortcut('mod+d'),
|
|
8813
8945
|
* command: () => duplicate(row) },
|
|
8814
8946
|
* { separator: true },
|
|
8815
8947
|
* { id: 'delete', labelKey: 'common_delete', icon: 'pi pi-trash', severity: 'danger',
|
|
@@ -8835,9 +8967,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8835
8967
|
* Permission filtering: pass `[context]="..."` (a `ScreenContext`); items
|
|
8836
8968
|
* declaring a `permission` are hidden unless that permission is granted.
|
|
8837
8969
|
* Items with no `permission` always show.
|
|
8970
|
+
*
|
|
8971
|
+
* The `kbd` hint is decorative unless it's one of `view` / `edit` /
|
|
8972
|
+
* `duplicate`: this component registers Enter, `E` and `mod+D` against
|
|
8973
|
+
* `EfShortcutService`, gated on `open()`, so they only fire while this
|
|
8974
|
+
* row's menu is on screen. Render `kbd` through `formatShortcut()` (as
|
|
8975
|
+
* above): a hardcoded `'⌘D'` is wrong for a Windows user, which is
|
|
8976
|
+
* exactly the bug this wiring fixes.
|
|
8838
8977
|
*/
|
|
8839
8978
|
class EfRowActionsComponent {
|
|
8840
8979
|
host = inject(ElementRef);
|
|
8980
|
+
shortcuts = inject(EfShortcutService);
|
|
8981
|
+
/** Distinguishes this instance's registrations from every other row's:
|
|
8982
|
+
* each row on screen constructs its own component, and ids must not
|
|
8983
|
+
* collide or one row's disposer (and its `when`) would clobber
|
|
8984
|
+
* another's still-live registration. */
|
|
8985
|
+
static nextInstanceId = 0;
|
|
8986
|
+
instanceId = EfRowActionsComponent.nextInstanceId++;
|
|
8987
|
+
constructor() {
|
|
8988
|
+
for (const { actionId, keys, labelKey } of ROW_SHORTCUTS) {
|
|
8989
|
+
this.shortcuts.register({
|
|
8990
|
+
id: `row-actions.${this.instanceId}.${actionId}`,
|
|
8991
|
+
keys,
|
|
8992
|
+
labelKey,
|
|
8993
|
+
group: 'shortcut_group_row_actions',
|
|
8994
|
+
// Gated on the trigger, not merely on `open()`: once a
|
|
8995
|
+
// keyboard user tabs from the trigger into the menu itself,
|
|
8996
|
+
// Enter is the button's own native activation key for
|
|
8997
|
+
// whichever item has focus. Without this, the `enter`
|
|
8998
|
+
// registration would run "view" from underneath the
|
|
8999
|
+
// focused "delete" button and swallow its click.
|
|
9000
|
+
when: () => this.open() && !this.isFocusInsideMenu(),
|
|
9001
|
+
handler: () => {
|
|
9002
|
+
const action = this.visibleItems().find(a => a.id === actionId);
|
|
9003
|
+
if (!action || action.disabled)
|
|
9004
|
+
return;
|
|
9005
|
+
action.command?.();
|
|
9006
|
+
this.close();
|
|
9007
|
+
},
|
|
9008
|
+
});
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
isFocusInsideMenu() {
|
|
9012
|
+
return !!document.activeElement?.closest('.row-actions__menu');
|
|
9013
|
+
}
|
|
8841
9014
|
/** Action descriptors. */
|
|
8842
9015
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
8843
9016
|
/** Optional context — when present, items with a `permission` are
|
|
@@ -8991,7 +9164,7 @@ class EfRowActionsComponent {
|
|
|
8991
9164
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfRowActionsComponent, decorators: [{
|
|
8992
9165
|
type: Component,
|
|
8993
9166
|
args: [{ selector: 'ef-row-actions', standalone: true, imports: [CommonModule, TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"row-actions\">\n <button\n type=\"button\"\n class=\"row-actions__trigger\"\n [class.open]=\"open()\"\n [disabled]=\"disabled() || visibleItems().length === 0\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-label]=\"triggerAriaKey() | translate\"\n (click)=\"toggle($event)\"\n (dblclick)=\"onDblClick($event)\"\n >\n <i [class]=\"triggerIcon()\" aria-hidden=\"true\"></i>\n </button>\n\n @if (open()) {\n <div\n class=\"row-actions__menu open\"\n [class.left]=\"menuLeft()\"\n [class.up]=\"dropUp()\"\n role=\"menu\"\n [attr.aria-label]=\"triggerAriaKey() | translate\"\n (dblclick)=\"onDblClick($event)\"\n >\n @for (action of visibleItems(); track trackByItem($index, action)) {\n @if (action.separator) {\n <div class=\"row-actions__divider\" role=\"separator\"></div>\n } @else {\n <button\n type=\"button\"\n class=\"row-actions__item\"\n [class.danger]=\"action.severity === 'danger'\"\n [disabled]=\"action.disabled\"\n role=\"menuitem\"\n (click)=\"runCommand(action, $event)\"\n >\n @if (action.icon) {\n <i class=\"ico\" [class]=\"'ico ' + action.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"lbl\">\n {{ action.labelKey ? (action.labelKey | translate) : action.label }}\n </span>\n @if (action.kbd) {\n <span class=\"kbd\" aria-hidden=\"true\">{{ action.kbd }}</span>\n }\n </button>\n }\n }\n </div>\n }\n</div>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:flex-end}\n"] }]
|
|
8994
|
-
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], triggerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerIcon", required: false }] }], triggerAriaKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerAriaKey", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], menuLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuLeft", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], onDocumentClick: [{
|
|
9167
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], triggerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerIcon", required: false }] }], triggerAriaKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerAriaKey", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], menuLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuLeft", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], onDocumentClick: [{
|
|
8995
9168
|
type: HostListener,
|
|
8996
9169
|
args: ['document:click', ['$event']]
|
|
8997
9170
|
}], onEscape: [{
|
|
@@ -9304,7 +9477,11 @@ class EfDataCardComponent {
|
|
|
9304
9477
|
/** Items array for the auto row-actions cell. Rebuilt per call so
|
|
9305
9478
|
* the ef-row-actions component receives a fresh closure per row.
|
|
9306
9479
|
* Visibility is filtered later by ef-row-actions against
|
|
9307
|
-
* `rowActionsContext` (ScreenContext.isGranted).
|
|
9480
|
+
* `rowActionsContext` (ScreenContext.isGranted).
|
|
9481
|
+
*
|
|
9482
|
+
* `kbd` is rendered through `formatShortcut()`, not a literal glyph:
|
|
9483
|
+
* `ef-row-actions` binds these same keys for real while the row's
|
|
9484
|
+
* menu is open, and a hardcoded `'⌘D'` would lie to a Windows user. */
|
|
9308
9485
|
defaultRowActions(row) {
|
|
9309
9486
|
const items = [];
|
|
9310
9487
|
if (this.showViewAction()) {
|
|
@@ -9312,7 +9489,7 @@ class EfDataCardComponent {
|
|
|
9312
9489
|
id: 'view',
|
|
9313
9490
|
labelKey: 'common_view',
|
|
9314
9491
|
icon: 'pi pi-eye',
|
|
9315
|
-
kbd: '
|
|
9492
|
+
kbd: formatShortcut('enter'),
|
|
9316
9493
|
permission: Permissions.Read,
|
|
9317
9494
|
command: () => this.rowAction.emit({ action: 'view', row }),
|
|
9318
9495
|
});
|
|
@@ -9322,7 +9499,7 @@ class EfDataCardComponent {
|
|
|
9322
9499
|
id: 'edit',
|
|
9323
9500
|
labelKey: 'common_edit',
|
|
9324
9501
|
icon: 'pi pi-pencil',
|
|
9325
|
-
kbd: '
|
|
9502
|
+
kbd: formatShortcut('e'),
|
|
9326
9503
|
permission: Permissions.Edit,
|
|
9327
9504
|
command: () => this.rowAction.emit({ action: 'edit', row }),
|
|
9328
9505
|
});
|
|
@@ -9332,7 +9509,7 @@ class EfDataCardComponent {
|
|
|
9332
9509
|
id: 'duplicate',
|
|
9333
9510
|
labelKey: 'common_duplicate',
|
|
9334
9511
|
icon: 'pi pi-copy',
|
|
9335
|
-
kbd: '
|
|
9512
|
+
kbd: formatShortcut('mod+d'),
|
|
9336
9513
|
permission: Permissions.Duplicate,
|
|
9337
9514
|
command: () => this.rowAction.emit({ action: 'duplicate', row }),
|
|
9338
9515
|
});
|
|
@@ -9938,6 +10115,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9938
10115
|
args: [{ selector: 'ef-filter-pill', standalone: true, imports: [CommonModule, TranslateModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n class=\"f-pill\"\n [class.active]=\"tone() === 'active'\"\n [class.tenant]=\"tone() === 'tenant'\"\n [class.has-pop]=\"hasPopover()\"\n [attr.aria-haspopup]=\"hasPopover() ? 'listbox' : null\"\n [attr.aria-expanded]=\"hasPopover() ? popoverOpen() : null\"\n (click)=\"onPillClick()\"\n>\n @if (icon()) {\n <i class=\"ico\" [class]=\"icon()\" aria-hidden=\"true\"></i>\n }\n\n @if (labelKey() || label()) {\n <span class=\"lbl\">\n {{ labelKey() ? (labelKey() | translate) : label() }}\n </span>\n }\n\n @if (value()) {\n <span class=\"val\">{{ value() }}</span>\n }\n\n @if (hasClear()) {\n <span\n class=\"clear\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"clearAriaKey() | translate\"\n (click)=\"onClearClick($event)\"\n (keydown.enter)=\"onClearClick($event)\"\n (keydown.space)=\"onClearClick($event)\"\n >\n <i class=\"pi pi-times\" aria-hidden=\"true\" style=\"font-size: 8px;\"></i>\n </span>\n } @else if (hasPopover()) {\n <i class=\"caret pi pi-chevron-down\" aria-hidden=\"true\"></i>\n }\n\n @if (hasPopover()) {\n <div class=\"popover\" [class.open]=\"popoverOpen()\" role=\"listbox\">\n <ng-content select=\"[popover]\"></ng-content>\n </div>\n }\n</button>\n" }]
|
|
9939
10116
|
}], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], labelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelKey", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], hasClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasClear", required: false }] }], hasPopover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasPopover", required: false }] }], popoverOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverOpen", required: false }] }], clearAriaKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearAriaKey", required: false }] }], pillClick: [{ type: i0.Output, args: ["pillClick"] }], clearClick: [{ type: i0.Output, args: ["clearClick"] }] } });
|
|
9940
10117
|
|
|
10118
|
+
/**
|
|
10119
|
+
* Password form, deliberately without an API client.
|
|
10120
|
+
*
|
|
10121
|
+
* `@elasticias/ui` cannot import an app's generated HTTP client, and that
|
|
10122
|
+
* limitation is what makes one component serve two different endpoints: a
|
|
10123
|
+
* user changing their own password proves the old one, an administrator
|
|
10124
|
+
* resetting someone else's does not. The host reads `canSubmit()`, calls
|
|
10125
|
+
* `submit()` from its dialog footer, and listens to `submitted`.
|
|
10126
|
+
*
|
|
10127
|
+
* ```html
|
|
10128
|
+
* <ef-change-password
|
|
10129
|
+
* #form
|
|
10130
|
+
* [requireCurrent]="!userId()"
|
|
10131
|
+
* [busy]="saving()"
|
|
10132
|
+
* [errors]="serverErrors()"
|
|
10133
|
+
* (submitted)="save($event)"
|
|
10134
|
+
* />
|
|
10135
|
+
* ```
|
|
10136
|
+
*
|
|
10137
|
+
* There is no `reset()`: hosts mount it under `@if`, so every open is a
|
|
10138
|
+
* fresh instance.
|
|
10139
|
+
*/
|
|
10140
|
+
class EfChangePasswordComponent {
|
|
10141
|
+
/** Ask for the existing password. False for an administrator reset. */
|
|
10142
|
+
requireCurrent = input(true, { ...(ngDevMode ? { debugName: "requireCurrent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
10143
|
+
/** A request is in flight: the form refuses to submit again. */
|
|
10144
|
+
busy = input(false, { ...(ngDevMode ? { debugName: "busy" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
10145
|
+
/** Already-translated server messages, rendered under the fields. */
|
|
10146
|
+
errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
10147
|
+
/** Minimum length. Kept in step with the backend validator's 8. */
|
|
10148
|
+
minLength = input(8, ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
|
|
10149
|
+
submitted = output();
|
|
10150
|
+
/* The template writes these directly; they are public so a host can
|
|
10151
|
+
drive the component in a test without touching the DOM. */
|
|
10152
|
+
currentPassword = signal('', ...(ngDevMode ? [{ debugName: "currentPassword" }] : /* istanbul ignore next */ []));
|
|
10153
|
+
newPassword = signal('', ...(ngDevMode ? [{ debugName: "newPassword" }] : /* istanbul ignore next */ []));
|
|
10154
|
+
confirmation = signal('', ...(ngDevMode ? [{ debugName: "confirmation" }] : /* istanbul ignore next */ []));
|
|
10155
|
+
/**
|
|
10156
|
+
* Translation keys for every rule the current input breaks. Empty while
|
|
10157
|
+
* the user has typed nothing, so the form does not scold on open.
|
|
10158
|
+
*/
|
|
10159
|
+
validationKeys = computed(() => {
|
|
10160
|
+
const next = this.newPassword();
|
|
10161
|
+
const confirmation = this.confirmation();
|
|
10162
|
+
const keys = [];
|
|
10163
|
+
if (next && next.length < this.minLength()) {
|
|
10164
|
+
keys.push('ef_change_password_too_short');
|
|
10165
|
+
}
|
|
10166
|
+
if (next && !/[A-Z]/.test(next)) {
|
|
10167
|
+
keys.push('ef_change_password_uppercase');
|
|
10168
|
+
}
|
|
10169
|
+
if (next && !/[0-9]/.test(next)) {
|
|
10170
|
+
keys.push('ef_change_password_digit');
|
|
10171
|
+
}
|
|
10172
|
+
if (next && confirmation && next !== confirmation) {
|
|
10173
|
+
keys.push('ef_change_password_mismatch');
|
|
10174
|
+
}
|
|
10175
|
+
return keys;
|
|
10176
|
+
}, ...(ngDevMode ? [{ debugName: "validationKeys" }] : /* istanbul ignore next */ []));
|
|
10177
|
+
canSubmit = computed(() => {
|
|
10178
|
+
if (this.busy())
|
|
10179
|
+
return false;
|
|
10180
|
+
if (this.requireCurrent() && !this.currentPassword())
|
|
10181
|
+
return false;
|
|
10182
|
+
if (!this.newPassword() || !this.confirmation())
|
|
10183
|
+
return false;
|
|
10184
|
+
return this.validationKeys().length === 0;
|
|
10185
|
+
}, ...(ngDevMode ? [{ debugName: "canSubmit" }] : /* istanbul ignore next */ []));
|
|
10186
|
+
submit() {
|
|
10187
|
+
if (!this.canSubmit())
|
|
10188
|
+
return;
|
|
10189
|
+
this.submitted.emit({
|
|
10190
|
+
currentPassword: this.requireCurrent() ? this.currentPassword() : undefined,
|
|
10191
|
+
newPassword: this.newPassword(),
|
|
10192
|
+
});
|
|
10193
|
+
}
|
|
10194
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfChangePasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10195
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfChangePasswordComponent, isStandalone: true, selector: "ef-change-password", inputs: { requireCurrent: { classPropertyName: "requireCurrent", publicName: "requireCurrent", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted" }, ngImport: i0, template: "<ef-form-grid>\n @if (requireCurrent()) {\n <ef-password\n class=\"col-12\"\n name=\"currentPassword\"\n labelKey=\"ef_change_password_current\"\n autocomplete=\"current-password\"\n required\n (valueChangeEvent)=\"currentPassword.set($event)\"\n />\n }\n <ef-password\n class=\"col-6\"\n name=\"newPassword\"\n labelKey=\"ef_change_password_new\"\n autocomplete=\"new-password\"\n required\n (valueChangeEvent)=\"newPassword.set($event)\"\n />\n <ef-password\n class=\"col-6\"\n name=\"newPasswordConfirmation\"\n labelKey=\"ef_change_password_confirm\"\n autocomplete=\"new-password\"\n required\n (valueChangeEvent)=\"confirmation.set($event)\"\n />\n</ef-form-grid>\n\n@if (validationKeys().length || errors().length) {\n <ul class=\"ef-change-password__errors\">\n @for (key of validationKeys(); track $index) {\n <li>{{ key | translate }}</li>\n }\n <!-- Server messages arrive already translated (Identity returns prose,\n not keys), so they are printed verbatim. -->\n @for (error of errors(); track $index) {\n <li>{{ error }}</li>\n }\n </ul>\n}\n", styles: [":host{display:grid;gap:var(--s-2, 8px);min-width:0}.ef-change-password__errors{display:grid;gap:4px;margin:0;padding:0;list-style:none;min-width:0;font-size:12px;line-height:1.4;color:var(--st-cancelled-fg, #b42318)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: EfPasswordComponent, selector: "ef-password", inputs: ["size", "fluid", "inline", "toggleMask", "feedback", "autocomplete"], outputs: ["valueChangeEvent"] }, { kind: "component", type: EfFormGridComponent, selector: "ef-form-grid" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10196
|
+
}
|
|
10197
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfChangePasswordComponent, decorators: [{
|
|
10198
|
+
type: Component,
|
|
10199
|
+
args: [{ selector: 'ef-change-password', standalone: true, imports: [CommonModule, TranslateModule, EfPasswordComponent, EfFormGridComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ef-form-grid>\n @if (requireCurrent()) {\n <ef-password\n class=\"col-12\"\n name=\"currentPassword\"\n labelKey=\"ef_change_password_current\"\n autocomplete=\"current-password\"\n required\n (valueChangeEvent)=\"currentPassword.set($event)\"\n />\n }\n <ef-password\n class=\"col-6\"\n name=\"newPassword\"\n labelKey=\"ef_change_password_new\"\n autocomplete=\"new-password\"\n required\n (valueChangeEvent)=\"newPassword.set($event)\"\n />\n <ef-password\n class=\"col-6\"\n name=\"newPasswordConfirmation\"\n labelKey=\"ef_change_password_confirm\"\n autocomplete=\"new-password\"\n required\n (valueChangeEvent)=\"confirmation.set($event)\"\n />\n</ef-form-grid>\n\n@if (validationKeys().length || errors().length) {\n <ul class=\"ef-change-password__errors\">\n @for (key of validationKeys(); track $index) {\n <li>{{ key | translate }}</li>\n }\n <!-- Server messages arrive already translated (Identity returns prose,\n not keys), so they are printed verbatim. -->\n @for (error of errors(); track $index) {\n <li>{{ error }}</li>\n }\n </ul>\n}\n", styles: [":host{display:grid;gap:var(--s-2, 8px);min-width:0}.ef-change-password__errors{display:grid;gap:4px;margin:0;padding:0;list-style:none;min-width:0;font-size:12px;line-height:1.4;color:var(--st-cancelled-fg, #b42318)}\n"] }]
|
|
10200
|
+
}], propDecorators: { requireCurrent: [{ type: i0.Input, args: [{ isSignal: true, alias: "requireCurrent", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }] } });
|
|
10201
|
+
|
|
9941
10202
|
/**
|
|
9942
10203
|
* Native Comptoir textarea — no PrimeNG wrapper. Pairs with the
|
|
9943
10204
|
* `.ef-textarea` rule in `@elasticias/ui/styles/patterns` (focus
|
|
@@ -10770,7 +11031,7 @@ class EfEmailMetricsCardComponent {
|
|
|
10770
11031
|
return 'warn';
|
|
10771
11032
|
}
|
|
10772
11033
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfEmailMetricsCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10773
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfEmailMetricsCardComponent, isStandalone: true, selector: "ef-email-metrics-card", inputs: { metrics: { classPropertyName: "metrics", publicName: "metrics", isSignal: true, isRequired: false, transformFunction: null }, recentEvents: { classPropertyName: "recentEvents", publicName: "recentEvents", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange" }, ngImport: i0, template: "<p-card styleClass=\"ef-email-metrics-card\">\n <ng-template pTemplate=\"header\">\n <div class=\"ef-email-metrics-card__header\">\n <div>\n <h3 class=\"ef-email-metrics-card__title\">{{ title() }}</h3>\n @if (metrics(); as m) {\n <p class=\"ef-email-metrics-card__subtitle\">\n {{ m.from | date: 'dd MMM' }} \u2013 {{ m.to | date: 'dd MMM yyyy' }}\n </p>\n }\n </div>\n <p-selectButton\n [options]=\"rangeOptions\"\n [(ngModel)]=\"selectedRange\"\n optionLabel=\"label\"\n optionValue=\"value\"\n styleClass=\"ef-email-metrics-card__range\"\n (onChange)=\"onRangeChange($event.value)\"\n />\n </div>\n </ng-template>\n\n @if (metrics(); as m) {\n <div class=\"ef-email-metrics-card__kpis\">\n @for (kpi of kpis(); track kpi.label) {\n <div class=\"ef-email-metrics-card__kpi\" [attr.data-tone]=\"kpi.tone\">\n <span class=\"ef-email-metrics-card__kpi-label\">{{ kpi.label }}</span>\n <span class=\"ef-email-metrics-card__kpi-value\">\n @if (kpi.rate) {\n {{ kpi.value | number: '1.1-1' : 'fr' }}\n <span class=\"ef-email-metrics-card__kpi-unit\">%</span>\n } @else {\n {{ kpi.value | number: '1.0-0' : 'fr' }}\n }\n </span>\n </div>\n }\n </div>\n\n @if (m.categories.length > 0) {\n <div class=\"ef-email-metrics-card__section\">\n <h4 class=\"ef-email-metrics-card__section-title\">Par cat\u00E9gorie</h4>\n <p-table [value]=\"m.categories\" styleClass=\"ef-email-metrics-card__table\" [scrollable]=\"true\" scrollHeight=\"180px\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Cat\u00E9gorie</th>\n <th class=\"ef-email-metrics-card__num\">Envoy\u00E9s</th>\n <th class=\"ef-email-metrics-card__num\">Ouverts</th>\n <th class=\"ef-email-metrics-card__num\">Cliqu\u00E9s</th>\n <th class=\"ef-email-metrics-card__num\">Rebonds</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td class=\"ef-email-metrics-card__category\">{{ row.category }}</td>\n <td class=\"ef-email-metrics-card__num\">{{ row.sent }}</td>\n <td class=\"ef-email-metrics-card__num\">{{ row.opened }}</td>\n <td class=\"ef-email-metrics-card__num\">{{ row.clicked }}</td>\n <td class=\"ef-email-metrics-card__num\" [class.ef-email-metrics-card__num--danger]=\"row.bounced > 0\">{{ row.bounced }}</td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n }\n\n @if (recentEvents().length > 0) {\n <div class=\"ef-email-metrics-card__section\">\n <h4 class=\"ef-email-metrics-card__section-title\">\u00C9v\u00E9nements r\u00E9cents</h4>\n <p-table [value]=\"recentEvents()\" styleClass=\"ef-email-metrics-card__table\" [scrollable]=\"true\" scrollHeight=\"240px\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Quand</th>\n <th>Destinataire</th>\n <th>Cat\u00E9gorie</th>\n <th>Type</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td class=\"ef-email-metrics-card__when\">{{ row.occurredAt | date: 'dd/MM HH:mm' }}</td>\n <td class=\"ef-email-metrics-card__recipient\">{{ row.recipient }}</td>\n <td>{{ row.category || '\u2014' }}</td>\n <td>\n <p-tag [severity]=\"kindSeverity(row.kind)\" [value]=\"row.kind\" styleClass=\"ef-email-metrics-card__kind\" />\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n }\n } @else {\n <div class=\"ef-email-metrics-card__empty\">\n <p-button label=\"Aucune donn\u00E9e encore\" [text]=\"true\" icon=\"pi pi-envelope\" [disabled]=\"true\" />\n </div>\n }\n</p-card>\n", styles: [":host{display:block}.ef-email-metrics-card__header{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:1rem 1.25rem 0;flex-wrap:wrap}.ef-email-metrics-card__title{margin:0;font-size:1rem;font-weight:600;letter-spacing:-.01em;color:var(--p-text-color)}.ef-email-metrics-card__subtitle{margin:.15rem 0 0;font-size:.8125rem;color:var(--p-text-muted-color)}.ef-email-metrics-card__range :global(.p-selectbutton){border-radius:999px}.ef-email-metrics-card__range :global(.p-selectbutton .p-button){border-radius:999px;padding:.25rem .75rem;font-size:.75rem}.ef-email-metrics-card__kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.75rem;padding:1rem 0}.ef-email-metrics-card__kpi{display:flex;flex-direction:column;gap:.25rem;padding:.85rem 1rem;border-radius:12px;background:var(--p-surface-50, #f8fafc);border:1px solid var(--p-surface-200, #e2e8f0)}.ef-email-metrics-card__kpi[data-tone=good]{background:color-mix(in srgb,var(--p-green-500, #10b981) 8%,transparent);border-color:color-mix(in srgb,var(--p-green-500, #10b981) 25%,transparent)}.ef-email-metrics-card__kpi[data-tone=warn]{background:color-mix(in srgb,var(--p-orange-500, #f97316) 8%,transparent);border-color:color-mix(in srgb,var(--p-orange-500, #f97316) 25%,transparent)}.ef-email-metrics-card__kpi-label{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--p-text-muted-color)}.ef-email-metrics-card__kpi-value{font-size:1.5rem;font-weight:700;letter-spacing:-.02em;color:var(--p-text-color)}.ef-email-metrics-card__kpi-unit{font-size:.875rem;font-weight:500;margin-left:.125rem;color:var(--p-text-muted-color)}.ef-email-metrics-card__section{margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--p-surface-200, #e2e8f0)}.ef-email-metrics-card__section-title{margin:0 0 .5rem;font-size:.8125rem;font-weight:600;color:var(--p-text-color)}.ef-email-metrics-card__table{font-size:.8125rem}.ef-email-metrics-card__num{text-align:right;font-variant-numeric:tabular-nums}.ef-email-metrics-card__num--danger{color:var(--p-red-600, #dc2626);font-weight:600}.ef-email-metrics-card__category{text-transform:capitalize;font-weight:500}.ef-email-metrics-card__recipient{font-family:JetBrains Mono,ui-monospace,monospace;font-size:.75rem;color:var(--p-text-muted-color)}.ef-email-metrics-card__when{font-variant-numeric:tabular-nums;white-space:nowrap;font-size:.75rem}.ef-email-metrics-card__kind{border-radius:999px;padding:.1rem .6rem;font-size:.7rem;letter-spacing:.02em}.ef-email-metrics-card__empty{padding:2rem 1.25rem;text-align:center;color:var(--p-text-muted-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: CardModule }, { kind: "component", type: i5$1.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2$4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i5$2.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i1$f.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "pipe", type: i1$3.DecimalPipe, name: "number" }, { kind: "pipe", type: i1$3.DatePipe, name: "date" }] });
|
|
11034
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfEmailMetricsCardComponent, isStandalone: true, selector: "ef-email-metrics-card", inputs: { metrics: { classPropertyName: "metrics", publicName: "metrics", isSignal: true, isRequired: false, transformFunction: null }, recentEvents: { classPropertyName: "recentEvents", publicName: "recentEvents", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange" }, ngImport: i0, template: "<p-card styleClass=\"ef-email-metrics-card\">\n <ng-template pTemplate=\"header\">\n <div class=\"ef-email-metrics-card__header\">\n <div>\n <h3 class=\"ef-email-metrics-card__title\">{{ title() }}</h3>\n @if (metrics(); as m) {\n <p class=\"ef-email-metrics-card__subtitle\">\n {{ m.from | date: 'dd MMM' }} \u2013 {{ m.to | date: 'dd MMM yyyy' }}\n </p>\n }\n </div>\n <p-selectButton\n [options]=\"rangeOptions\"\n [(ngModel)]=\"selectedRange\"\n optionLabel=\"label\"\n optionValue=\"value\"\n styleClass=\"ef-email-metrics-card__range\"\n (onChange)=\"onRangeChange($event.value)\"\n />\n </div>\n </ng-template>\n\n @if (metrics(); as m) {\n <div class=\"ef-email-metrics-card__kpis\">\n @for (kpi of kpis(); track kpi.label) {\n <div class=\"ef-email-metrics-card__kpi\" [attr.data-tone]=\"kpi.tone\">\n <span class=\"ef-email-metrics-card__kpi-label\">{{ kpi.label }}</span>\n <span class=\"ef-email-metrics-card__kpi-value\">\n @if (kpi.rate) {\n {{ kpi.value | number: '1.1-1' : 'fr' }}\n <span class=\"ef-email-metrics-card__kpi-unit\">%</span>\n } @else {\n {{ kpi.value | number: '1.0-0' : 'fr' }}\n }\n </span>\n </div>\n }\n </div>\n\n @if (m.categories.length > 0) {\n <div class=\"ef-email-metrics-card__section\">\n <h4 class=\"ef-email-metrics-card__section-title\">Par cat\u00E9gorie</h4>\n <p-table [value]=\"m.categories\" styleClass=\"ef-email-metrics-card__table\" [scrollable]=\"true\" scrollHeight=\"180px\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Cat\u00E9gorie</th>\n <th class=\"ef-email-metrics-card__num\">Envoy\u00E9s</th>\n <th class=\"ef-email-metrics-card__num\">Ouverts</th>\n <th class=\"ef-email-metrics-card__num\">Cliqu\u00E9s</th>\n <th class=\"ef-email-metrics-card__num\">Rebonds</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td class=\"ef-email-metrics-card__category\">{{ row.category }}</td>\n <td class=\"ef-email-metrics-card__num\">{{ row.sent }}</td>\n <td class=\"ef-email-metrics-card__num\">{{ row.opened }}</td>\n <td class=\"ef-email-metrics-card__num\">{{ row.clicked }}</td>\n <td class=\"ef-email-metrics-card__num\" [class.ef-email-metrics-card__num--danger]=\"row.bounced > 0\">{{ row.bounced }}</td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n }\n\n @if (recentEvents().length > 0) {\n <div class=\"ef-email-metrics-card__section\">\n <h4 class=\"ef-email-metrics-card__section-title\">\u00C9v\u00E9nements r\u00E9cents</h4>\n <p-table [value]=\"recentEvents()\" styleClass=\"ef-email-metrics-card__table\" [scrollable]=\"true\" scrollHeight=\"240px\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Quand</th>\n <th>Destinataire</th>\n <th>Cat\u00E9gorie</th>\n <th>Type</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td class=\"ef-email-metrics-card__when\">{{ row.occurredAt | date: 'dd/MM HH:mm' }}</td>\n <td class=\"ef-email-metrics-card__recipient\">{{ row.recipient }}</td>\n <td>{{ row.category || '\u2014' }}</td>\n <td>\n <p-tag [severity]=\"kindSeverity(row.kind)\" [value]=\"row.kind\" styleClass=\"ef-email-metrics-card__kind\" />\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n }\n } @else {\n <div class=\"ef-email-metrics-card__empty\">\n <p-button label=\"Aucune donn\u00E9e encore\" [text]=\"true\" icon=\"pi pi-envelope\" [disabled]=\"true\" />\n </div>\n }\n</p-card>\n", styles: [":host{display:block}.ef-email-metrics-card__header{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:1rem 1.25rem 0;flex-wrap:wrap}.ef-email-metrics-card__title{margin:0;font-size:1rem;font-weight:600;letter-spacing:-.01em;color:var(--p-text-color)}.ef-email-metrics-card__subtitle{margin:.15rem 0 0;font-size:.8125rem;color:var(--p-text-muted-color)}.ef-email-metrics-card__range :global(.p-selectbutton){border-radius:999px}.ef-email-metrics-card__range :global(.p-selectbutton .p-button){border-radius:999px;padding:.25rem .75rem;font-size:.75rem}.ef-email-metrics-card__kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.75rem;padding:1rem 0}.ef-email-metrics-card__kpi{display:flex;flex-direction:column;gap:.25rem;padding:.85rem 1rem;border-radius:12px;background:var(--p-surface-50, #f8fafc);border:1px solid var(--p-surface-200, #e2e8f0)}.ef-email-metrics-card__kpi[data-tone=good]{background:color-mix(in srgb,var(--p-green-500, #10b981) 8%,transparent);border-color:color-mix(in srgb,var(--p-green-500, #10b981) 25%,transparent)}.ef-email-metrics-card__kpi[data-tone=warn]{background:color-mix(in srgb,var(--p-orange-500, #f97316) 8%,transparent);border-color:color-mix(in srgb,var(--p-orange-500, #f97316) 25%,transparent)}.ef-email-metrics-card__kpi-label{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--p-text-muted-color)}.ef-email-metrics-card__kpi-value{font-size:1.5rem;font-weight:700;letter-spacing:-.02em;color:var(--p-text-color)}.ef-email-metrics-card__kpi-unit{font-size:.875rem;font-weight:500;margin-left:.125rem;color:var(--p-text-muted-color)}.ef-email-metrics-card__section{margin-top:.75rem;padding-top:.75rem;border-top:1px solid var(--p-surface-200, #e2e8f0)}.ef-email-metrics-card__section-title{margin:0 0 .5rem;font-size:.8125rem;font-weight:600;color:var(--p-text-color)}.ef-email-metrics-card__table{font-size:.8125rem}.ef-email-metrics-card__num{text-align:right;font-variant-numeric:tabular-nums}.ef-email-metrics-card__num--danger{color:var(--p-red-600, #dc2626);font-weight:600}.ef-email-metrics-card__category{text-transform:capitalize;font-weight:500}.ef-email-metrics-card__recipient{font-family:JetBrains Mono,ui-monospace,monospace;font-size:.75rem;color:var(--p-text-muted-color)}.ef-email-metrics-card__when{font-variant-numeric:tabular-nums;white-space:nowrap;font-size:.75rem}.ef-email-metrics-card__kind{border-radius:999px;padding:.1rem .6rem;font-size:.7rem;letter-spacing:.02em}.ef-email-metrics-card__empty{padding:2rem 1.25rem;text-align:center;color:var(--p-text-muted-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: CardModule }, { kind: "component", type: i5$1.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2$5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i5$2.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i1$f.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "pipe", type: i1$3.DecimalPipe, name: "number" }, { kind: "pipe", type: i1$3.DatePipe, name: "date" }] });
|
|
10774
11035
|
}
|
|
10775
11036
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfEmailMetricsCardComponent, decorators: [{
|
|
10776
11037
|
type: Component,
|
|
@@ -10793,5 +11054,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
10793
11054
|
* Generated bundle index. Do not edit.
|
|
10794
11055
|
*/
|
|
10795
11056
|
|
|
10796
|
-
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, 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, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRankListComponent, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfServerErrorsDirective, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
|
|
11057
|
+
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, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfProfileMenuComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, 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 };
|
|
10797
11058
|
//# sourceMappingURL=elasticias-ui.mjs.map
|