@elasticias/ui 1.0.11 → 1.0.14
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 +333 -21
- package/fesm2022/elasticias-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/_patterns.scss +145 -14
- package/types/elasticias-ui.d.ts +216 -10
|
@@ -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';
|
|
@@ -4932,6 +4934,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
4932
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"] }]
|
|
4933
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 }] }] } });
|
|
4934
4936
|
|
|
4937
|
+
/**
|
|
4938
|
+
* The three tiers a shortcut can belong to, outer to inner: a Global
|
|
4939
|
+
* shortcut works anywhere in the app, a Screen shortcut works anywhere on
|
|
4940
|
+
* the current screen, a Row shortcut only while a row's menu is open.
|
|
4941
|
+
* `list()` returns groups in registration order, which is really "whatever
|
|
4942
|
+
* happened to construct first." This fixes the section order so it
|
|
4943
|
+
* always reads outer to inner regardless of what rendered when.
|
|
4944
|
+
*/
|
|
4945
|
+
const GROUP_ORDER = [
|
|
4946
|
+
'shortcut_group_general',
|
|
4947
|
+
'shortcut_group_screen',
|
|
4948
|
+
'shortcut_group_row_actions',
|
|
4949
|
+
];
|
|
4950
|
+
/**
|
|
4951
|
+
* The keyboard-shortcuts reference: every registration currently sitting
|
|
4952
|
+
* in `EfShortcutService`, grouped and rendered with the same `.kbd` chip
|
|
4953
|
+
* `ef-row-actions` and `ef-menu` already use, so a chip means one thing
|
|
4954
|
+
* everywhere it appears.
|
|
4955
|
+
*
|
|
4956
|
+
* Reads `EfShortcutService.list()` directly, so it stays live: open it
|
|
4957
|
+
* while a row menu is on screen and its row-scoped shortcuts are already
|
|
4958
|
+
* listed under "Row actions". Close the row menu and, since a row's
|
|
4959
|
+
* shortcuts unregister with it, they're gone from here too.
|
|
4960
|
+
*
|
|
4961
|
+
* ```html
|
|
4962
|
+
* <ef-shortcuts-dialog [(visible)]="shortcutsOpen" />
|
|
4963
|
+
* ```
|
|
4964
|
+
*/
|
|
4965
|
+
class EfShortcutsDialogComponent {
|
|
4966
|
+
shortcutService = inject(EfShortcutService);
|
|
4967
|
+
/** Two-way open state. */
|
|
4968
|
+
visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
4969
|
+
/** `list()`, reordered Global → Screen → Row. An unrecognised group
|
|
4970
|
+
* (a future tier this component doesn't know about yet) sorts last
|
|
4971
|
+
* rather than being dropped. */
|
|
4972
|
+
groups = computed(() => {
|
|
4973
|
+
const rank = (group) => {
|
|
4974
|
+
const index = GROUP_ORDER.indexOf(group);
|
|
4975
|
+
return index === -1 ? GROUP_ORDER.length : index;
|
|
4976
|
+
};
|
|
4977
|
+
return [...this.shortcutService.list()].sort((a, b) => rank(a.group) - rank(b.group));
|
|
4978
|
+
}, ...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
|
|
4979
|
+
/** Only macOS shows every chip already resolved to its own glyphs.
|
|
4980
|
+
* Everyone else gets a line saying the chips already match their
|
|
4981
|
+
* system, since nothing here prints a Mac glyph for them to decode. */
|
|
4982
|
+
isMacPlatform = isMacPlatform;
|
|
4983
|
+
closeAction = [
|
|
4984
|
+
{ labelKey: 'common_close', severity: 'ghost' },
|
|
4985
|
+
];
|
|
4986
|
+
formatKeys(keys) {
|
|
4987
|
+
return formatShortcut(keys);
|
|
4988
|
+
}
|
|
4989
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfShortcutsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4990
|
+
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:1px;margin:0;padding:6px;list-style:none;background:var(--paper-alt);border:1px solid var(--rule);border-radius:var(--r-xl)}.shortcuts-dialog__item{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0;padding:9px 12px;border-radius:var(--r-md)}.shortcuts-dialog__item .lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:600;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 });
|
|
4991
|
+
}
|
|
4992
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfShortcutsDialogComponent, decorators: [{
|
|
4993
|
+
type: Component,
|
|
4994
|
+
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:1px;margin:0;padding:6px;list-style:none;background:var(--paper-alt);border:1px solid var(--rule);border-radius:var(--r-xl)}.shortcuts-dialog__item{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0;padding:9px 12px;border-radius:var(--r-md)}.shortcuts-dialog__item .lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:600;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"] }]
|
|
4995
|
+
}], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }] } });
|
|
4996
|
+
|
|
4935
4997
|
class EfFieldsetComponent {
|
|
4936
4998
|
/** Direct legend text (not translated) */
|
|
4937
4999
|
legend;
|
|
@@ -6207,6 +6269,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
6207
6269
|
type: Output
|
|
6208
6270
|
}] } });
|
|
6209
6271
|
|
|
6272
|
+
/**
|
|
6273
|
+
* The signed-in user's menu.
|
|
6274
|
+
*
|
|
6275
|
+
* Two renderings of one `items` array. `variant="chip"` (the default) shows
|
|
6276
|
+
* an `ef-profile-chip` that opens a popover, for the side footer on a
|
|
6277
|
+
* desktop. `variant="list"` renders the same rows flat, with no popover,
|
|
6278
|
+
* for the mobile sheet: `ef-app-shell` does not render the side footer on a
|
|
6279
|
+
* phone, and this menu is the only way to sign out, so it cannot live only
|
|
6280
|
+
* there.
|
|
6281
|
+
*
|
|
6282
|
+
* ```html
|
|
6283
|
+
* <ef-profile-menu
|
|
6284
|
+
* side-footer
|
|
6285
|
+
* [name]="userName()"
|
|
6286
|
+
* [secondary]="userEmail()"
|
|
6287
|
+
* [initial]="userInitial()"
|
|
6288
|
+
* [items]="menuItems()"
|
|
6289
|
+
* />
|
|
6290
|
+
* ```
|
|
6291
|
+
*/
|
|
6292
|
+
class EfProfileMenuComponent {
|
|
6293
|
+
/** Display name, shown on the chip and in the panel header. */
|
|
6294
|
+
name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
6295
|
+
/** Second header line. The email, usually. */
|
|
6296
|
+
secondary = input('', ...(ngDevMode ? [{ debugName: "secondary" }] : /* istanbul ignore next */ []));
|
|
6297
|
+
/** Chip subtitle. Falls back to `secondary` when empty. */
|
|
6298
|
+
role = input('', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
|
|
6299
|
+
/** Avatar glyph. Up to two characters; falls back to the first of `name`. */
|
|
6300
|
+
initial = input('', ...(ngDevMode ? [{ debugName: "initial" }] : /* istanbul ignore next */ []));
|
|
6301
|
+
tone = input('tenant', ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
6302
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
6303
|
+
variant = input('chip', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
6304
|
+
itemSelected = output();
|
|
6305
|
+
/** Id of the one expanded group, or null. One at a time: a menu that
|
|
6306
|
+
* grows in two directions at once stops being scannable. */
|
|
6307
|
+
expandedId = signal(null, ...(ngDevMode ? [{ debugName: "expandedId" }] : /* istanbul ignore next */ []));
|
|
6308
|
+
chipRole = computed(() => this.role() || this.secondary(), ...(ngDevMode ? [{ debugName: "chipRole" }] : /* istanbul ignore next */ []));
|
|
6309
|
+
isExpanded(id) {
|
|
6310
|
+
return this.expandedId() === id;
|
|
6311
|
+
}
|
|
6312
|
+
/**
|
|
6313
|
+
* Choose a row. A row with children toggles its group and leaves the
|
|
6314
|
+
* popover open; a leaf runs its command, reports it, and dismisses.
|
|
6315
|
+
*/
|
|
6316
|
+
select(item, popover) {
|
|
6317
|
+
if (item.children?.length) {
|
|
6318
|
+
this.expandedId.update((current) => (current === item.id ? null : item.id));
|
|
6319
|
+
// Reposition once the taller panel has actually rendered. Without this
|
|
6320
|
+
// the panel keeps the top it was placed at and grows downward, which
|
|
6321
|
+
// runs it off the bottom of the screen when the trigger sits in the
|
|
6322
|
+
// side footer. Realigning lets it grow upward from the trigger instead.
|
|
6323
|
+
setTimeout(() => popover?.align?.(), 0);
|
|
6324
|
+
return;
|
|
6325
|
+
}
|
|
6326
|
+
item.command?.();
|
|
6327
|
+
this.itemSelected.emit(item);
|
|
6328
|
+
popover?.hide();
|
|
6329
|
+
}
|
|
6330
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6331
|
+
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 });
|
|
6332
|
+
}
|
|
6333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileMenuComponent, decorators: [{
|
|
6334
|
+
type: Component,
|
|
6335
|
+
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"] }]
|
|
6336
|
+
}], 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"] }] } });
|
|
6337
|
+
|
|
6210
6338
|
class EfBlockUiComponent {
|
|
6211
6339
|
isLoading = false;
|
|
6212
6340
|
contentPanel;
|
|
@@ -8686,7 +8814,7 @@ class EfDatatableComponent {
|
|
|
8686
8814
|
return this.pTable?.filters;
|
|
8687
8815
|
}
|
|
8688
8816
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfDatatableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8689
|
-
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 });
|
|
8817
|
+
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 });
|
|
8690
8818
|
}
|
|
8691
8819
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfDatatableComponent, decorators: [{
|
|
8692
8820
|
type: Component,
|
|
@@ -8815,6 +8943,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8815
8943
|
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" }]
|
|
8816
8944
|
}], 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"] }] } });
|
|
8817
8945
|
|
|
8946
|
+
/** Row-scoped shortcuts, wired once per instance and gated on `open()` so
|
|
8947
|
+
* they're inert until this row's menu is on screen. The action `id` is a
|
|
8948
|
+
* convention shared with `ef-data-card.defaultRowActions()`: an instance
|
|
8949
|
+
* with no matching item is simply a no-op for that key. */
|
|
8950
|
+
const ROW_SHORTCUTS = [
|
|
8951
|
+
{ actionId: 'view', keys: 'enter', labelKey: 'common_view' },
|
|
8952
|
+
{ actionId: 'edit', keys: 'e', labelKey: 'common_edit' },
|
|
8953
|
+
{ actionId: 'duplicate', keys: 'mod+d', labelKey: 'common_duplicate' },
|
|
8954
|
+
];
|
|
8818
8955
|
/**
|
|
8819
8956
|
* Row-actions dropdown — V2 successor to `ef-datatable-actionbar`.
|
|
8820
8957
|
*
|
|
@@ -8823,11 +8960,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8823
8960
|
*
|
|
8824
8961
|
* ```ts
|
|
8825
8962
|
* actions: ReadonlyArray<EfRowAction> = [
|
|
8826
|
-
* { id: 'view', labelKey: 'common_view', icon: 'pi pi-eye', kbd: '
|
|
8963
|
+
* { id: 'view', labelKey: 'common_view', icon: 'pi pi-eye', kbd: formatShortcut('enter'),
|
|
8827
8964
|
* permission: Permissions.Read, command: () => view(row) },
|
|
8828
|
-
* { id: 'edit', labelKey: 'common_edit', icon: 'pi pi-pencil', kbd: '
|
|
8965
|
+
* { id: 'edit', labelKey: 'common_edit', icon: 'pi pi-pencil', kbd: formatShortcut('e'),
|
|
8829
8966
|
* permission: Permissions.Edit, command: () => edit(row) },
|
|
8830
|
-
* { id: 'duplicate', labelKey: 'common_duplicate', icon: 'pi pi-copy',
|
|
8967
|
+
* { id: 'duplicate', labelKey: 'common_duplicate', icon: 'pi pi-copy', kbd: formatShortcut('mod+d'),
|
|
8831
8968
|
* command: () => duplicate(row) },
|
|
8832
8969
|
* { separator: true },
|
|
8833
8970
|
* { id: 'delete', labelKey: 'common_delete', icon: 'pi pi-trash', severity: 'danger',
|
|
@@ -8853,9 +8990,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
8853
8990
|
* Permission filtering: pass `[context]="..."` (a `ScreenContext`); items
|
|
8854
8991
|
* declaring a `permission` are hidden unless that permission is granted.
|
|
8855
8992
|
* Items with no `permission` always show.
|
|
8993
|
+
*
|
|
8994
|
+
* The `kbd` hint is decorative unless it's one of `view` / `edit` /
|
|
8995
|
+
* `duplicate`: this component registers Enter, `E` and `mod+D` against
|
|
8996
|
+
* `EfShortcutService`, gated on `open()`, so they only fire while this
|
|
8997
|
+
* row's menu is on screen. Render `kbd` through `formatShortcut()` (as
|
|
8998
|
+
* above): a hardcoded `'⌘D'` is wrong for a Windows user, which is
|
|
8999
|
+
* exactly the bug this wiring fixes.
|
|
8856
9000
|
*/
|
|
8857
9001
|
class EfRowActionsComponent {
|
|
8858
9002
|
host = inject(ElementRef);
|
|
9003
|
+
shortcuts = inject(EfShortcutService);
|
|
9004
|
+
/** Distinguishes this instance's registrations from every other row's:
|
|
9005
|
+
* each row on screen constructs its own component, and ids must not
|
|
9006
|
+
* collide or one row's disposer (and its `when`) would clobber
|
|
9007
|
+
* another's still-live registration. */
|
|
9008
|
+
static nextInstanceId = 0;
|
|
9009
|
+
instanceId = EfRowActionsComponent.nextInstanceId++;
|
|
9010
|
+
constructor() {
|
|
9011
|
+
for (const { actionId, keys, labelKey } of ROW_SHORTCUTS) {
|
|
9012
|
+
this.shortcuts.register({
|
|
9013
|
+
id: `row-actions.${this.instanceId}.${actionId}`,
|
|
9014
|
+
keys,
|
|
9015
|
+
labelKey,
|
|
9016
|
+
group: 'shortcut_group_row_actions',
|
|
9017
|
+
// Gated on the trigger, not merely on `open()`: once a
|
|
9018
|
+
// keyboard user tabs from the trigger into the menu itself,
|
|
9019
|
+
// Enter is the button's own native activation key for
|
|
9020
|
+
// whichever item has focus. Without this, the `enter`
|
|
9021
|
+
// registration would run "view" from underneath the
|
|
9022
|
+
// focused "delete" button and swallow its click.
|
|
9023
|
+
when: () => this.open() && !this.isFocusInsideMenu(),
|
|
9024
|
+
handler: () => {
|
|
9025
|
+
const action = this.visibleItems().find(a => a.id === actionId);
|
|
9026
|
+
if (!action || action.disabled)
|
|
9027
|
+
return;
|
|
9028
|
+
action.command?.();
|
|
9029
|
+
this.close();
|
|
9030
|
+
},
|
|
9031
|
+
});
|
|
9032
|
+
}
|
|
9033
|
+
}
|
|
9034
|
+
isFocusInsideMenu() {
|
|
9035
|
+
return !!document.activeElement?.closest('.row-actions__menu');
|
|
9036
|
+
}
|
|
8859
9037
|
/** Action descriptors. */
|
|
8860
9038
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
8861
9039
|
/** Optional context — when present, items with a `permission` are
|
|
@@ -9009,7 +9187,7 @@ class EfRowActionsComponent {
|
|
|
9009
9187
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfRowActionsComponent, decorators: [{
|
|
9010
9188
|
type: Component,
|
|
9011
9189
|
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"] }]
|
|
9012
|
-
}], 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: [{
|
|
9190
|
+
}], 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: [{
|
|
9013
9191
|
type: HostListener,
|
|
9014
9192
|
args: ['document:click', ['$event']]
|
|
9015
9193
|
}], onEscape: [{
|
|
@@ -9322,7 +9500,11 @@ class EfDataCardComponent {
|
|
|
9322
9500
|
/** Items array for the auto row-actions cell. Rebuilt per call so
|
|
9323
9501
|
* the ef-row-actions component receives a fresh closure per row.
|
|
9324
9502
|
* Visibility is filtered later by ef-row-actions against
|
|
9325
|
-
* `rowActionsContext` (ScreenContext.isGranted).
|
|
9503
|
+
* `rowActionsContext` (ScreenContext.isGranted).
|
|
9504
|
+
*
|
|
9505
|
+
* `kbd` is rendered through `formatShortcut()`, not a literal glyph:
|
|
9506
|
+
* `ef-row-actions` binds these same keys for real while the row's
|
|
9507
|
+
* menu is open, and a hardcoded `'⌘D'` would lie to a Windows user. */
|
|
9326
9508
|
defaultRowActions(row) {
|
|
9327
9509
|
const items = [];
|
|
9328
9510
|
if (this.showViewAction()) {
|
|
@@ -9330,7 +9512,7 @@ class EfDataCardComponent {
|
|
|
9330
9512
|
id: 'view',
|
|
9331
9513
|
labelKey: 'common_view',
|
|
9332
9514
|
icon: 'pi pi-eye',
|
|
9333
|
-
kbd: '
|
|
9515
|
+
kbd: formatShortcut('enter'),
|
|
9334
9516
|
permission: Permissions.Read,
|
|
9335
9517
|
command: () => this.rowAction.emit({ action: 'view', row }),
|
|
9336
9518
|
});
|
|
@@ -9340,7 +9522,7 @@ class EfDataCardComponent {
|
|
|
9340
9522
|
id: 'edit',
|
|
9341
9523
|
labelKey: 'common_edit',
|
|
9342
9524
|
icon: 'pi pi-pencil',
|
|
9343
|
-
kbd: '
|
|
9525
|
+
kbd: formatShortcut('e'),
|
|
9344
9526
|
permission: Permissions.Edit,
|
|
9345
9527
|
command: () => this.rowAction.emit({ action: 'edit', row }),
|
|
9346
9528
|
});
|
|
@@ -9350,7 +9532,7 @@ class EfDataCardComponent {
|
|
|
9350
9532
|
id: 'duplicate',
|
|
9351
9533
|
labelKey: 'common_duplicate',
|
|
9352
9534
|
icon: 'pi pi-copy',
|
|
9353
|
-
kbd: '
|
|
9535
|
+
kbd: formatShortcut('mod+d'),
|
|
9354
9536
|
permission: Permissions.Duplicate,
|
|
9355
9537
|
command: () => this.rowAction.emit({ action: 'duplicate', row }),
|
|
9356
9538
|
});
|
|
@@ -9723,8 +9905,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9723
9905
|
/**
|
|
9724
9906
|
* Comptoir smart bar — the search/filter card every list screen
|
|
9725
9907
|
* starts with. Composes:
|
|
9726
|
-
* 1. Search input (with
|
|
9727
|
-
* action buttons.
|
|
9908
|
+
* 1. Search input (with an optional keyboard-shortcut hint chip) +
|
|
9909
|
+
* Effacer / Rechercher action buttons.
|
|
9728
9910
|
* 2. A filter-row slot for `[filters]` (pill-group + filter-pill +
|
|
9729
9911
|
* preset-pill + "+ Plus de filtres").
|
|
9730
9912
|
* 3. A drawer slot for `[drawer]` (advanced filters via
|
|
@@ -9734,6 +9916,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9734
9916
|
* for two-way binding, or watch the (search) output for explicit
|
|
9735
9917
|
* Rechercher clicks.
|
|
9736
9918
|
*
|
|
9919
|
+
* `shortcut` defaults to `'mod+k'`: this component registers it with
|
|
9920
|
+
* `EfShortcutService` and focuses the search input when it fires (the
|
|
9921
|
+
* user still has to type and submit; the shortcut only gets them into
|
|
9922
|
+
* the field). Pass `[shortcut]="null"` on a screen with a second smart
|
|
9923
|
+
* bar so only one of them claims the binding.
|
|
9924
|
+
*
|
|
9737
9925
|
* ```html
|
|
9738
9926
|
* <ef-smart-bar
|
|
9739
9927
|
* [(searchText)]="searchQuery"
|
|
@@ -9753,6 +9941,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9753
9941
|
* ```
|
|
9754
9942
|
*/
|
|
9755
9943
|
class EfSmartBarComponent {
|
|
9944
|
+
shortcuts = inject(EfShortcutService);
|
|
9945
|
+
/** Distinguishes this instance's registration from any other
|
|
9946
|
+
* ef-smart-bar on screen, the same convention ef-row-actions uses. */
|
|
9947
|
+
static nextInstanceId = 0;
|
|
9948
|
+
instanceId = EfSmartBarComponent.nextInstanceId++;
|
|
9949
|
+
searchInput = viewChild('searchInput', ...(ngDevMode ? [{ debugName: "searchInput" }] : /* istanbul ignore next */ []));
|
|
9756
9950
|
/** Two-way bound search input. */
|
|
9757
9951
|
searchText = model('', ...(ngDevMode ? [{ debugName: "searchText" }] : /* istanbul ignore next */ []));
|
|
9758
9952
|
placeholderKey = input('', ...(ngDevMode ? [{ debugName: "placeholderKey" }] : /* istanbul ignore next */ []));
|
|
@@ -9764,12 +9958,44 @@ class EfSmartBarComponent {
|
|
|
9764
9958
|
hideClear = input(false, { ...(ngDevMode ? { debugName: "hideClear" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
9765
9959
|
hideSearch = input(false, { ...(ngDevMode ? { debugName: "hideSearch" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
9766
9960
|
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
9961
|
+
/** Keyboard shortcut that focuses the search input. `null` opts out
|
|
9962
|
+
* (a screen with two smart bars registers the binding on only one
|
|
9963
|
+
* of them). Defaults to `'mod+k'`. */
|
|
9964
|
+
shortcut = input('mod+k', ...(ngDevMode ? [{ debugName: "shortcut" }] : /* istanbul ignore next */ []));
|
|
9965
|
+
kbdLabel = computed(() => {
|
|
9966
|
+
const keys = this.shortcut();
|
|
9967
|
+
return keys ? formatShortcut(keys) : '';
|
|
9968
|
+
}, ...(ngDevMode ? [{ debugName: "kbdLabel" }] : /* istanbul ignore next */ []));
|
|
9767
9969
|
// `search` shadows a native DOM event name. Renaming this output would
|
|
9768
9970
|
// churn every consumer template, so the name stays and the rule is
|
|
9769
9971
|
// suppressed here deliberately.
|
|
9770
9972
|
// eslint-disable-next-line @angular-eslint/no-output-native
|
|
9771
9973
|
search = output();
|
|
9772
9974
|
clear = output();
|
|
9975
|
+
constructor() {
|
|
9976
|
+
// An effect, not a constructor-time register(): `shortcut` is an
|
|
9977
|
+
// input, so its bound value isn't readable until after Angular has
|
|
9978
|
+
// finished construction. The effect also re-registers cleanly if a
|
|
9979
|
+
// caller ever changes `shortcut` at runtime, and its `onCleanup`
|
|
9980
|
+
// covers disposal since `EfShortcutService.register()` cannot pick
|
|
9981
|
+
// up a DestroyRef from inside an effect callback.
|
|
9982
|
+
effect(onCleanup => {
|
|
9983
|
+
const keys = this.shortcut();
|
|
9984
|
+
if (!keys)
|
|
9985
|
+
return;
|
|
9986
|
+
const dispose = this.shortcuts.register({
|
|
9987
|
+
id: `smart-bar.${this.instanceId}.focus`,
|
|
9988
|
+
keys,
|
|
9989
|
+
// Not 'common_search': this shortcut focuses the field, it
|
|
9990
|
+
// never submits, and the dialog is where a user learns
|
|
9991
|
+
// what a key actually does.
|
|
9992
|
+
labelKey: 'shortcut_focus_search',
|
|
9993
|
+
group: 'shortcut_group_screen',
|
|
9994
|
+
handler: () => this.searchInput()?.nativeElement.focus(),
|
|
9995
|
+
});
|
|
9996
|
+
onCleanup(dispose);
|
|
9997
|
+
});
|
|
9998
|
+
}
|
|
9773
9999
|
onSubmit() {
|
|
9774
10000
|
this.search.emit(this.searchText());
|
|
9775
10001
|
}
|
|
@@ -9778,19 +10004,20 @@ class EfSmartBarComponent {
|
|
|
9778
10004
|
this.clear.emit();
|
|
9779
10005
|
}
|
|
9780
10006
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfSmartBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9781
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfSmartBarComponent, isStandalone: true, selector: "ef-smart-bar", inputs: { searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null }, placeholderKey: { classPropertyName: "placeholderKey", publicName: "placeholderKey", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, clearLabelKey: { classPropertyName: "clearLabelKey", publicName: "clearLabelKey", isSignal: true, isRequired: false, transformFunction: null }, clearTitleKey: { classPropertyName: "clearTitleKey", publicName: "clearTitleKey", isSignal: true, isRequired: false, transformFunction: null }, searchLabelKey: { classPropertyName: "searchLabelKey", publicName: "searchLabelKey", isSignal: true, isRequired: false, transformFunction: null }, showKbdHint: { classPropertyName: "showKbdHint", publicName: "showKbdHint", isSignal: true, isRequired: false, transformFunction: null }, hideClear: { classPropertyName: "hideClear", publicName: "hideClear", isSignal: true, isRequired: false, transformFunction: null }, hideSearch: { classPropertyName: "hideSearch", publicName: "hideSearch", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchText: "searchTextChange", search: "search", clear: "clear" }, ngImport: i0, template: `
|
|
10007
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfSmartBarComponent, isStandalone: true, selector: "ef-smart-bar", inputs: { searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null }, placeholderKey: { classPropertyName: "placeholderKey", publicName: "placeholderKey", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, clearLabelKey: { classPropertyName: "clearLabelKey", publicName: "clearLabelKey", isSignal: true, isRequired: false, transformFunction: null }, clearTitleKey: { classPropertyName: "clearTitleKey", publicName: "clearTitleKey", isSignal: true, isRequired: false, transformFunction: null }, searchLabelKey: { classPropertyName: "searchLabelKey", publicName: "searchLabelKey", isSignal: true, isRequired: false, transformFunction: null }, showKbdHint: { classPropertyName: "showKbdHint", publicName: "showKbdHint", isSignal: true, isRequired: false, transformFunction: null }, hideClear: { classPropertyName: "hideClear", publicName: "hideClear", isSignal: true, isRequired: false, transformFunction: null }, hideSearch: { classPropertyName: "hideSearch", publicName: "hideSearch", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, shortcut: { classPropertyName: "shortcut", publicName: "shortcut", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchText: "searchTextChange", search: "search", clear: "clear" }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
9782
10008
|
<div class="screen-search">
|
|
9783
10009
|
<div class="smart-bar">
|
|
9784
10010
|
<label class="search">
|
|
9785
10011
|
<input
|
|
10012
|
+
#searchInput
|
|
9786
10013
|
type="text"
|
|
9787
10014
|
[placeholder]="(placeholderKey() ? (placeholderKey() | translate) : placeholder())"
|
|
9788
10015
|
[ngModel]="searchText()"
|
|
9789
10016
|
(ngModelChange)="searchText.set($event)"
|
|
9790
10017
|
(keydown.enter)="onSubmit()"
|
|
9791
10018
|
/>
|
|
9792
|
-
@if (showKbdHint()) {
|
|
9793
|
-
<span class="kbd"
|
|
10019
|
+
@if (showKbdHint() && kbdLabel()) {
|
|
10020
|
+
<span class="kbd">{{ kbdLabel() }}</span>
|
|
9794
10021
|
}
|
|
9795
10022
|
</label>
|
|
9796
10023
|
<div class="actions">
|
|
@@ -9836,14 +10063,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9836
10063
|
<div class="smart-bar">
|
|
9837
10064
|
<label class="search">
|
|
9838
10065
|
<input
|
|
10066
|
+
#searchInput
|
|
9839
10067
|
type="text"
|
|
9840
10068
|
[placeholder]="(placeholderKey() ? (placeholderKey() | translate) : placeholder())"
|
|
9841
10069
|
[ngModel]="searchText()"
|
|
9842
10070
|
(ngModelChange)="searchText.set($event)"
|
|
9843
10071
|
(keydown.enter)="onSubmit()"
|
|
9844
10072
|
/>
|
|
9845
|
-
@if (showKbdHint()) {
|
|
9846
|
-
<span class="kbd"
|
|
10073
|
+
@if (showKbdHint() && kbdLabel()) {
|
|
10074
|
+
<span class="kbd">{{ kbdLabel() }}</span>
|
|
9847
10075
|
}
|
|
9848
10076
|
</label>
|
|
9849
10077
|
<div class="actions">
|
|
@@ -9879,7 +10107,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9879
10107
|
`,
|
|
9880
10108
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
9881
10109
|
}]
|
|
9882
|
-
}], propDecorators: { searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }], placeholderKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholderKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabelKey", required: false }] }], clearTitleKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTitleKey", required: false }] }], searchLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchLabelKey", required: false }] }], showKbdHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "showKbdHint", required: false }] }], hideClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClear", required: false }] }], hideSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSearch", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], search: [{ type: i0.Output, args: ["search"] }], clear: [{ type: i0.Output, args: ["clear"] }] } });
|
|
10110
|
+
}], ctorParameters: () => [], propDecorators: { searchInput: [{ type: i0.ViewChild, args: ['searchInput', { isSignal: true }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }], placeholderKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholderKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabelKey", required: false }] }], clearTitleKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTitleKey", required: false }] }], searchLabelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchLabelKey", required: false }] }], showKbdHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "showKbdHint", required: false }] }], hideClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClear", required: false }] }], hideSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSearch", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], shortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "shortcut", required: false }] }], search: [{ type: i0.Output, args: ["search"] }], clear: [{ type: i0.Output, args: ["clear"] }] } });
|
|
9883
10111
|
|
|
9884
10112
|
/**
|
|
9885
10113
|
* Comptoir filter pill — value-bearing button used in the smart-bar's
|
|
@@ -9956,6 +10184,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
9956
10184
|
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" }]
|
|
9957
10185
|
}], 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"] }] } });
|
|
9958
10186
|
|
|
10187
|
+
/**
|
|
10188
|
+
* Password form, deliberately without an API client.
|
|
10189
|
+
*
|
|
10190
|
+
* `@elasticias/ui` cannot import an app's generated HTTP client, and that
|
|
10191
|
+
* limitation is what makes one component serve two different endpoints: a
|
|
10192
|
+
* user changing their own password proves the old one, an administrator
|
|
10193
|
+
* resetting someone else's does not. The host reads `canSubmit()`, calls
|
|
10194
|
+
* `submit()` from its dialog footer, and listens to `submitted`.
|
|
10195
|
+
*
|
|
10196
|
+
* ```html
|
|
10197
|
+
* <ef-change-password
|
|
10198
|
+
* #form
|
|
10199
|
+
* [requireCurrent]="!userId()"
|
|
10200
|
+
* [busy]="saving()"
|
|
10201
|
+
* [errors]="serverErrors()"
|
|
10202
|
+
* (submitted)="save($event)"
|
|
10203
|
+
* />
|
|
10204
|
+
* ```
|
|
10205
|
+
*
|
|
10206
|
+
* There is no `reset()`: hosts mount it under `@if`, so every open is a
|
|
10207
|
+
* fresh instance.
|
|
10208
|
+
*/
|
|
10209
|
+
class EfChangePasswordComponent {
|
|
10210
|
+
/** Ask for the existing password. False for an administrator reset. */
|
|
10211
|
+
requireCurrent = input(true, { ...(ngDevMode ? { debugName: "requireCurrent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
10212
|
+
/** A request is in flight: the form refuses to submit again. */
|
|
10213
|
+
busy = input(false, { ...(ngDevMode ? { debugName: "busy" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
10214
|
+
/** Already-translated server messages, rendered under the fields. */
|
|
10215
|
+
errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
10216
|
+
/** Minimum length. Kept in step with the backend validator's 8. */
|
|
10217
|
+
minLength = input(8, ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
|
|
10218
|
+
submitted = output();
|
|
10219
|
+
/* The template writes these directly; they are public so a host can
|
|
10220
|
+
drive the component in a test without touching the DOM. */
|
|
10221
|
+
currentPassword = signal('', ...(ngDevMode ? [{ debugName: "currentPassword" }] : /* istanbul ignore next */ []));
|
|
10222
|
+
newPassword = signal('', ...(ngDevMode ? [{ debugName: "newPassword" }] : /* istanbul ignore next */ []));
|
|
10223
|
+
confirmation = signal('', ...(ngDevMode ? [{ debugName: "confirmation" }] : /* istanbul ignore next */ []));
|
|
10224
|
+
/**
|
|
10225
|
+
* Translation keys for every rule the current input breaks. Empty while
|
|
10226
|
+
* the user has typed nothing, so the form does not scold on open.
|
|
10227
|
+
*/
|
|
10228
|
+
validationKeys = computed(() => {
|
|
10229
|
+
const next = this.newPassword();
|
|
10230
|
+
const confirmation = this.confirmation();
|
|
10231
|
+
const keys = [];
|
|
10232
|
+
if (next && next.length < this.minLength()) {
|
|
10233
|
+
keys.push('ef_change_password_too_short');
|
|
10234
|
+
}
|
|
10235
|
+
if (next && !/[A-Z]/.test(next)) {
|
|
10236
|
+
keys.push('ef_change_password_uppercase');
|
|
10237
|
+
}
|
|
10238
|
+
if (next && !/[0-9]/.test(next)) {
|
|
10239
|
+
keys.push('ef_change_password_digit');
|
|
10240
|
+
}
|
|
10241
|
+
if (next && confirmation && next !== confirmation) {
|
|
10242
|
+
keys.push('ef_change_password_mismatch');
|
|
10243
|
+
}
|
|
10244
|
+
return keys;
|
|
10245
|
+
}, ...(ngDevMode ? [{ debugName: "validationKeys" }] : /* istanbul ignore next */ []));
|
|
10246
|
+
canSubmit = computed(() => {
|
|
10247
|
+
if (this.busy())
|
|
10248
|
+
return false;
|
|
10249
|
+
if (this.requireCurrent() && !this.currentPassword())
|
|
10250
|
+
return false;
|
|
10251
|
+
if (!this.newPassword() || !this.confirmation())
|
|
10252
|
+
return false;
|
|
10253
|
+
return this.validationKeys().length === 0;
|
|
10254
|
+
}, ...(ngDevMode ? [{ debugName: "canSubmit" }] : /* istanbul ignore next */ []));
|
|
10255
|
+
submit() {
|
|
10256
|
+
if (!this.canSubmit())
|
|
10257
|
+
return;
|
|
10258
|
+
this.submitted.emit({
|
|
10259
|
+
currentPassword: this.requireCurrent() ? this.currentPassword() : undefined,
|
|
10260
|
+
newPassword: this.newPassword(),
|
|
10261
|
+
});
|
|
10262
|
+
}
|
|
10263
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfChangePasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10264
|
+
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 });
|
|
10265
|
+
}
|
|
10266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfChangePasswordComponent, decorators: [{
|
|
10267
|
+
type: Component,
|
|
10268
|
+
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"] }]
|
|
10269
|
+
}], 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"] }] } });
|
|
10270
|
+
|
|
9959
10271
|
/**
|
|
9960
10272
|
* Native Comptoir textarea — no PrimeNG wrapper. Pairs with the
|
|
9961
10273
|
* `.ef-textarea` rule in `@elasticias/ui/styles/patterns` (focus
|
|
@@ -10788,7 +11100,7 @@ class EfEmailMetricsCardComponent {
|
|
|
10788
11100
|
return 'warn';
|
|
10789
11101
|
}
|
|
10790
11102
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfEmailMetricsCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10791
|
-
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" }] });
|
|
11103
|
+
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" }] });
|
|
10792
11104
|
}
|
|
10793
11105
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfEmailMetricsCardComponent, decorators: [{
|
|
10794
11106
|
type: Component,
|
|
@@ -10811,5 +11123,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
10811
11123
|
* Generated bundle index. Do not edit.
|
|
10812
11124
|
*/
|
|
10813
11125
|
|
|
10814
|
-
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 };
|
|
11126
|
+
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 };
|
|
10815
11127
|
//# sourceMappingURL=elasticias-ui.mjs.map
|