ng-prime-tools 1.0.98 → 1.0.99

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.
@@ -7649,13 +7649,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
7649
7649
  }]
7650
7650
  }] });
7651
7651
 
7652
- // src/lib/components/pt-metric-panel/pt-metric-panel.component.ts
7653
7652
  class PTMetricPanelComponent {
7654
- /**
7655
- * Controlled by the parent component.
7656
- * The parent must set it to false when its request completes,
7657
- * including error cases.
7658
- */
7659
7653
  set loading(value) {
7660
7654
  const previousLoading = this.dashboardLoading;
7661
7655
  this.dashboardLoading = value;
@@ -7674,23 +7668,9 @@ class PTMetricPanelComponent {
7674
7668
  constructor(router) {
7675
7669
  this.router = router;
7676
7670
  this.cardConfig = this.getDefaultCardConfig();
7677
- /**
7678
- * Displays the refresh action in the panel header.
7679
- */
7680
7671
  this.showRefresh = false;
7681
- /**
7682
- * Displays the contextual actions menu in the panel header.
7683
- */
7684
7672
  this.showMenu = false;
7685
- /**
7686
- * Additional menu items supplied by the parent component.
7687
- * "Actualiser" is automatically added when showRefresh is true.
7688
- */
7689
7673
  this.menuItems = [];
7690
- /**
7691
- * Emitted when the user clicks the refresh action.
7692
- * The parent executes the API request.
7693
- */
7694
7674
  this.refresh = new EventEmitter();
7695
7675
  this.actionMenuItems = [];
7696
7676
  this.dashboardLoading = false;
@@ -7737,6 +7717,19 @@ class PTMetricPanelComponent {
7737
7717
  }
7738
7718
  return {};
7739
7719
  }
7720
+ getTitleIconStyles() {
7721
+ if (!this.isTitleObject()) {
7722
+ return {};
7723
+ }
7724
+ const title = this.panelData.title;
7725
+ const icon = title.icon;
7726
+ const iconColor = title.color ||
7727
+ (typeof icon === 'object' && icon !== null ? icon.color : undefined) ||
7728
+ '#6734c9';
7729
+ return {
7730
+ color: iconColor,
7731
+ };
7732
+ }
7740
7733
  getIconClass(icon) {
7741
7734
  return icon || '';
7742
7735
  }
@@ -7823,11 +7816,11 @@ class PTMetricPanelComponent {
7823
7816
  this.actionMenuItems = [...items, ...this.menuItems];
7824
7817
  }
7825
7818
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMetricPanelComponent, deps: [{ token: i1$2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
7826
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTMetricPanelComponent, isStandalone: false, selector: "pt-metric-panel", inputs: { panelData: "panelData", cardConfig: "cardConfig", showRefresh: "showRefresh", showMenu: "showMenu", menuItems: "menuItems", loading: "loading" }, outputs: { refresh: "refresh" }, viewQueries: [{ propertyName: "actionMenu", first: true, predicate: ["actionMenu"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- src/lib/components/pt-metric-panel/pt-metric-panel.component.html -->\n\n<pt-card [config]=\"cardConfig\">\n <div class=\"panel-header\">\n <div class=\"panel-title-container\" [ngStyle]=\"getTitleStyles()\">\n @if (getTitleIcon()) {\n <i\n class=\"panel-title-icon\"\n [ngClass]=\"getIconClass(getTitleIcon())\"\n ></i>\n }\n\n <span class=\"panel-title-text\">\n {{ getTitleText() }}\n </span>\n </div>\n\n @if (showRefresh || shouldShowMenu) {\n <div class=\"panel-actions\">\n @if (showRefresh) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [class.panel-action-button-loading]=\"isLoading\"\n [disabled]=\"isLoading\"\n aria-label=\"Actualiser\"\n title=\"Actualiser\"\n (click)=\"onRefreshClick($event)\"\n >\n <i\n class=\"pi\"\n [ngClass]=\"isLoading ? 'pi-spin pi-spinner' : 'pi-refresh'\"\n ></i>\n </button>\n }\n\n @if (shouldShowMenu) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [disabled]=\"isLoading\"\n aria-label=\"Plus d\u2019actions\"\n title=\"Plus d\u2019actions\"\n (click)=\"toggleMenu($event)\"\n >\n <i class=\"pi pi-ellipsis-v\"></i>\n </button>\n\n <p-menu\n #actionMenu\n [model]=\"actionMenuItems\"\n [popup]=\"true\"\n appendTo=\"body\"\n ></p-menu>\n }\n </div>\n }\n </div>\n\n <div class=\"panel-separator\"></div>\n\n <div class=\"metric-content\">\n @if (isLoading) {\n <div\n class=\"metric-loading-overlay\"\n aria-live=\"polite\"\n aria-label=\"Chargement des donn\u00E9es\"\n >\n <i class=\"pi pi-spinner pi-spin metric-loading-spinner\"></i>\n <span>Chargement des donn\u00E9es...</span>\n </div>\n }\n\n <div\n class=\"metric-list\"\n [class.metric-list-loading]=\"isLoading\"\n [attr.aria-busy]=\"isLoading\"\n >\n @for (item of panelData.indicators; track $index) {\n <div\n class=\"metric-item\"\n [class.metric-item-clickable]=\"!!item.url && !isLoading\"\n [pTooltip]=\"item.tooltip || ''\"\n tooltipPosition=\"top\"\n [tooltipDisabled]=\"!item.tooltip || isLoading\"\n (click)=\"!isLoading && handleClick(item.url)\"\n >\n <div class=\"metric-left\">\n @if (item.icon) {\n <span class=\"metric-icon-wrapper\">\n <i\n [ngClass]=\"getIconClass(item.icon.code)\"\n [ngStyle]=\"getIconStyles(item.icon)\"\n ></i>\n </span>\n }\n\n <span class=\"metric-title\">\n {{ isTitleStyle(item.title) ? item.title.text : item.title }}\n </span>\n </div>\n\n <span\n class=\"metric-value\"\n [class.metric-value-highlighted]=\"item.highlighted && !isLoading\"\n [ngStyle]=\"getValueStyles(item.value)\"\n >\n {{ isTitleStyle(item.value) ? item.value.text : item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n</pt-card>\n", styles: [":host{display:block}.panel-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}.panel-title-container{display:flex;align-items:center;min-width:0;gap:12px;font-weight:800;line-height:1.2}.panel-title-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;min-width:38px;min-height:38px;padding:10px;color:#6734c9;background:#f0e7ff;border-radius:12px;font-size:1.05rem}.panel-title-text{overflow:hidden;color:inherit;text-overflow:ellipsis;white-space:nowrap}.panel-actions{display:flex;align-items:center;flex:0 0 auto;gap:4px}.panel-action-button{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;cursor:pointer;border:1px solid transparent;border-radius:10px;color:#667085;background:transparent;transition:background-color .16s ease,border-color .16s ease,color .16s ease,transform .16s ease}.panel-action-button:hover:not(:disabled){border-color:#e3d8fb;color:#6734c9;background:#f7f3ff}.panel-action-button:active:not(:disabled){transform:scale(.95)}.panel-action-button:disabled{cursor:wait;opacity:.65}.panel-action-button-loading{color:#6734c9}.panel-action-button:focus-visible{outline:2px solid #8b5cf6;outline-offset:2px}.panel-separator{width:100%;height:1px;margin:0 0 16px;background:#e7eaf0}.metric-list{display:flex;flex-direction:column;gap:12px}.metric-item{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:68px;padding:12px 14px;background:#fff;border:1px solid #edf0f5;border-radius:14px;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.metric-item:hover{border-color:#ddd2f8;box-shadow:0 5px 14px #4a209014}.metric-item-clickable{cursor:pointer}.metric-item-clickable:hover{transform:translateY(-1px)}.metric-left{display:flex;align-items:center;min-width:0;gap:12px}.metric-icon-wrapper{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.metric-icon-wrapper i{display:inline-flex!important;align-items:center;justify-content:center;min-width:40px;min-height:40px;box-sizing:border-box}.metric-title{overflow:hidden;color:#344054;font-size:1rem;font-weight:700;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.metric-value{flex:0 0 auto;padding:7px 11px;color:#1f2937;background:#f8f9fc;border:1px solid #e8ebf1;border-radius:10px;font-size:.95rem;font-weight:800;line-height:1;text-align:right;white-space:nowrap}.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;animation:metric-value-flash 1.8s ease-out}@keyframes metric-value-flash{0%{color:#166534;background:#bbf7d0;border-color:#4ade80;transform:scale(1.08)}to{color:#15803d;background:#dcfce7;border-color:#86efac;transform:scale(1)}}@media(max-width:576px){.panel-header,.panel-title-container{gap:8px}.panel-title-icon{min-width:34px;min-height:34px;padding:8px}.panel-action-button{width:32px;height:32px}.metric-item{min-height:60px;padding:10px}.metric-title{font-size:.92rem}.metric-value{padding:6px 8px;font-size:.85rem}}.metric-content{position:relative;min-height:120px}.metric-loading-overlay{position:absolute;z-index:2;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.7rem;min-height:120px;border-radius:14px;color:#6734c9;background:#ffffffd1;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);font-size:.9rem;font-weight:700}.metric-loading-spinner{font-size:1.5rem}.metric-list-loading{pointer-events:none;-webkit-user-select:none;user-select:none;opacity:.42;filter:blur(.4px)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i5$1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }] }); }
7819
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTMetricPanelComponent, isStandalone: false, selector: "pt-metric-panel", inputs: { panelData: "panelData", cardConfig: "cardConfig", showRefresh: "showRefresh", showMenu: "showMenu", menuItems: "menuItems", loading: "loading" }, outputs: { refresh: "refresh" }, viewQueries: [{ propertyName: "actionMenu", first: true, predicate: ["actionMenu"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<pt-card [config]=\"cardConfig\">\n <div class=\"panel-header\">\n <div class=\"panel-title-container\" [ngStyle]=\"getTitleStyles()\">\n @if (getTitleIcon()) {\n <i\n class=\"panel-title-icon\"\n [ngClass]=\"getIconClass(getTitleIcon())\"\n [ngStyle]=\"getTitleIconStyles()\"\n ></i>\n }\n\n <span class=\"panel-title-text\">\n {{ getTitleText() }}\n </span>\n </div>\n\n @if (showRefresh || shouldShowMenu) {\n <div class=\"panel-actions\">\n @if (showRefresh) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [class.panel-action-button-loading]=\"isLoading\"\n [disabled]=\"isLoading\"\n aria-label=\"Actualiser\"\n title=\"Actualiser\"\n (click)=\"onRefreshClick($event)\"\n >\n <i\n class=\"pi\"\n [ngClass]=\"isLoading ? 'pi-spin pi-spinner' : 'pi-refresh'\"\n ></i>\n </button>\n }\n\n @if (shouldShowMenu) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [disabled]=\"isLoading\"\n aria-label=\"Plus d\u2019actions\"\n title=\"Plus d\u2019actions\"\n (click)=\"toggleMenu($event)\"\n >\n <i class=\"pi pi-ellipsis-v\"></i>\n </button>\n\n <p-menu\n #actionMenu\n [model]=\"actionMenuItems\"\n [popup]=\"true\"\n appendTo=\"body\"\n ></p-menu>\n }\n </div>\n }\n </div>\n\n <div class=\"panel-separator\"></div>\n\n <div class=\"metric-content\">\n @if (isLoading) {\n <div\n class=\"metric-loading-overlay\"\n aria-live=\"polite\"\n aria-label=\"Chargement des donn\u00E9es\"\n >\n <i class=\"pi pi-spinner pi-spin metric-loading-spinner\"></i>\n <span>Chargement des donn\u00E9es...</span>\n </div>\n }\n\n <div\n class=\"metric-list\"\n [class.metric-list-loading]=\"isLoading\"\n [attr.aria-busy]=\"isLoading\"\n >\n @for (item of panelData.indicators; track $index) {\n <div\n class=\"metric-item\"\n [class.metric-item-clickable]=\"!!item.url && !isLoading\"\n [pTooltip]=\"item.tooltip || ''\"\n tooltipPosition=\"top\"\n [tooltipDisabled]=\"!item.tooltip || isLoading\"\n (click)=\"!isLoading && handleClick(item.url)\"\n >\n <div class=\"metric-left\">\n @if (item.icon) {\n <span class=\"metric-icon-wrapper\">\n <i\n [ngClass]=\"getIconClass(item.icon.code)\"\n [ngStyle]=\"getIconStyles(item.icon)\"\n ></i>\n </span>\n }\n\n <span class=\"metric-title\">\n {{ isTitleStyle(item.title) ? item.title.text : item.title }}\n </span>\n </div>\n\n <span\n class=\"metric-value\"\n [class.metric-value-highlighted]=\"item.highlighted && !isLoading\"\n [ngStyle]=\"getValueStyles(item.value)\"\n >\n {{ isTitleStyle(item.value) ? item.value.text : item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n</pt-card>\n", styles: [":host{display:block}.panel-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}.panel-title-container{display:flex;align-items:center;min-width:0;gap:12px;font-weight:800;line-height:1.2}.panel-title-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;min-width:38px;min-height:38px;padding:10px;color:#6734c9;background:#f0e7ff;border-radius:12px;font-size:1.05rem}.panel-title-text{overflow:hidden;color:inherit;text-overflow:ellipsis;white-space:nowrap}.panel-actions{display:flex;align-items:center;flex:0 0 auto;gap:4px}.panel-action-button{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;cursor:pointer;border:1px solid transparent;border-radius:10px;color:#667085;background:transparent;transition:background-color .16s ease,border-color .16s ease,color .16s ease,transform .16s ease}.panel-action-button:hover:not(:disabled){border-color:#e3d8fb;color:#6734c9;background:#f7f3ff}.panel-action-button:active:not(:disabled){transform:scale(.95)}.panel-action-button:disabled{cursor:wait;opacity:.65}.panel-action-button-loading{color:#6734c9}.panel-action-button:focus-visible{outline:2px solid #8b5cf6;outline-offset:2px}.panel-separator{width:100%;height:1px;margin:0 0 16px;background:#e7eaf0}.metric-list{display:flex;flex-direction:column;gap:12px}.metric-item{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:68px;padding:12px 14px;background:#fff;border:1px solid #edf0f5;border-radius:14px;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.metric-item:hover{border-color:#ddd2f8;box-shadow:0 5px 14px #4a209014}.metric-item-clickable{cursor:pointer}.metric-item-clickable:hover{transform:translateY(-1px)}.metric-left{display:flex;align-items:center;min-width:0;gap:12px}.metric-icon-wrapper{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.metric-icon-wrapper i{display:inline-flex!important;align-items:center;justify-content:center;min-width:40px;min-height:40px;box-sizing:border-box}.metric-title{overflow:hidden;color:#344054;font-size:1rem;font-weight:700;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.metric-value{flex:0 0 auto;padding:7px 11px;color:#1f2937;background:#f8f9fc;border:1px solid #e8ebf1;border-radius:10px;font-size:.95rem;font-weight:800;line-height:1;text-align:right;white-space:nowrap}.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;animation:metric-value-flash 1.8s ease-out}@keyframes metric-value-flash{0%{color:#166534;background:#bbf7d0;border-color:#4ade80;transform:scale(1.08)}to{color:#15803d;background:#dcfce7;border-color:#86efac;transform:scale(1)}}@media(max-width:576px){.panel-header,.panel-title-container{gap:8px}.panel-title-icon{min-width:34px;min-height:34px;padding:8px}.panel-action-button{width:32px;height:32px}.metric-item{min-height:60px;padding:10px}.metric-title{font-size:.92rem}.metric-value{padding:6px 8px;font-size:.85rem}}.metric-content{position:relative;min-height:120px}.metric-loading-overlay{position:absolute;z-index:2;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.7rem;min-height:120px;border-radius:14px;color:#6734c9;background:#ffffffd1;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);font-size:.9rem;font-weight:700}.metric-loading-spinner{font-size:1.5rem}.metric-list-loading{pointer-events:none;-webkit-user-select:none;user-select:none;opacity:.42;filter:blur(.4px)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i5$1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }] }); }
7827
7820
  }
7828
7821
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMetricPanelComponent, decorators: [{
7829
7822
  type: Component,
7830
- args: [{ selector: 'pt-metric-panel', standalone: false, template: "<!-- src/lib/components/pt-metric-panel/pt-metric-panel.component.html -->\n\n<pt-card [config]=\"cardConfig\">\n <div class=\"panel-header\">\n <div class=\"panel-title-container\" [ngStyle]=\"getTitleStyles()\">\n @if (getTitleIcon()) {\n <i\n class=\"panel-title-icon\"\n [ngClass]=\"getIconClass(getTitleIcon())\"\n ></i>\n }\n\n <span class=\"panel-title-text\">\n {{ getTitleText() }}\n </span>\n </div>\n\n @if (showRefresh || shouldShowMenu) {\n <div class=\"panel-actions\">\n @if (showRefresh) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [class.panel-action-button-loading]=\"isLoading\"\n [disabled]=\"isLoading\"\n aria-label=\"Actualiser\"\n title=\"Actualiser\"\n (click)=\"onRefreshClick($event)\"\n >\n <i\n class=\"pi\"\n [ngClass]=\"isLoading ? 'pi-spin pi-spinner' : 'pi-refresh'\"\n ></i>\n </button>\n }\n\n @if (shouldShowMenu) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [disabled]=\"isLoading\"\n aria-label=\"Plus d\u2019actions\"\n title=\"Plus d\u2019actions\"\n (click)=\"toggleMenu($event)\"\n >\n <i class=\"pi pi-ellipsis-v\"></i>\n </button>\n\n <p-menu\n #actionMenu\n [model]=\"actionMenuItems\"\n [popup]=\"true\"\n appendTo=\"body\"\n ></p-menu>\n }\n </div>\n }\n </div>\n\n <div class=\"panel-separator\"></div>\n\n <div class=\"metric-content\">\n @if (isLoading) {\n <div\n class=\"metric-loading-overlay\"\n aria-live=\"polite\"\n aria-label=\"Chargement des donn\u00E9es\"\n >\n <i class=\"pi pi-spinner pi-spin metric-loading-spinner\"></i>\n <span>Chargement des donn\u00E9es...</span>\n </div>\n }\n\n <div\n class=\"metric-list\"\n [class.metric-list-loading]=\"isLoading\"\n [attr.aria-busy]=\"isLoading\"\n >\n @for (item of panelData.indicators; track $index) {\n <div\n class=\"metric-item\"\n [class.metric-item-clickable]=\"!!item.url && !isLoading\"\n [pTooltip]=\"item.tooltip || ''\"\n tooltipPosition=\"top\"\n [tooltipDisabled]=\"!item.tooltip || isLoading\"\n (click)=\"!isLoading && handleClick(item.url)\"\n >\n <div class=\"metric-left\">\n @if (item.icon) {\n <span class=\"metric-icon-wrapper\">\n <i\n [ngClass]=\"getIconClass(item.icon.code)\"\n [ngStyle]=\"getIconStyles(item.icon)\"\n ></i>\n </span>\n }\n\n <span class=\"metric-title\">\n {{ isTitleStyle(item.title) ? item.title.text : item.title }}\n </span>\n </div>\n\n <span\n class=\"metric-value\"\n [class.metric-value-highlighted]=\"item.highlighted && !isLoading\"\n [ngStyle]=\"getValueStyles(item.value)\"\n >\n {{ isTitleStyle(item.value) ? item.value.text : item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n</pt-card>\n", styles: [":host{display:block}.panel-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}.panel-title-container{display:flex;align-items:center;min-width:0;gap:12px;font-weight:800;line-height:1.2}.panel-title-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;min-width:38px;min-height:38px;padding:10px;color:#6734c9;background:#f0e7ff;border-radius:12px;font-size:1.05rem}.panel-title-text{overflow:hidden;color:inherit;text-overflow:ellipsis;white-space:nowrap}.panel-actions{display:flex;align-items:center;flex:0 0 auto;gap:4px}.panel-action-button{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;cursor:pointer;border:1px solid transparent;border-radius:10px;color:#667085;background:transparent;transition:background-color .16s ease,border-color .16s ease,color .16s ease,transform .16s ease}.panel-action-button:hover:not(:disabled){border-color:#e3d8fb;color:#6734c9;background:#f7f3ff}.panel-action-button:active:not(:disabled){transform:scale(.95)}.panel-action-button:disabled{cursor:wait;opacity:.65}.panel-action-button-loading{color:#6734c9}.panel-action-button:focus-visible{outline:2px solid #8b5cf6;outline-offset:2px}.panel-separator{width:100%;height:1px;margin:0 0 16px;background:#e7eaf0}.metric-list{display:flex;flex-direction:column;gap:12px}.metric-item{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:68px;padding:12px 14px;background:#fff;border:1px solid #edf0f5;border-radius:14px;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.metric-item:hover{border-color:#ddd2f8;box-shadow:0 5px 14px #4a209014}.metric-item-clickable{cursor:pointer}.metric-item-clickable:hover{transform:translateY(-1px)}.metric-left{display:flex;align-items:center;min-width:0;gap:12px}.metric-icon-wrapper{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.metric-icon-wrapper i{display:inline-flex!important;align-items:center;justify-content:center;min-width:40px;min-height:40px;box-sizing:border-box}.metric-title{overflow:hidden;color:#344054;font-size:1rem;font-weight:700;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.metric-value{flex:0 0 auto;padding:7px 11px;color:#1f2937;background:#f8f9fc;border:1px solid #e8ebf1;border-radius:10px;font-size:.95rem;font-weight:800;line-height:1;text-align:right;white-space:nowrap}.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;animation:metric-value-flash 1.8s ease-out}@keyframes metric-value-flash{0%{color:#166534;background:#bbf7d0;border-color:#4ade80;transform:scale(1.08)}to{color:#15803d;background:#dcfce7;border-color:#86efac;transform:scale(1)}}@media(max-width:576px){.panel-header,.panel-title-container{gap:8px}.panel-title-icon{min-width:34px;min-height:34px;padding:8px}.panel-action-button{width:32px;height:32px}.metric-item{min-height:60px;padding:10px}.metric-title{font-size:.92rem}.metric-value{padding:6px 8px;font-size:.85rem}}.metric-content{position:relative;min-height:120px}.metric-loading-overlay{position:absolute;z-index:2;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.7rem;min-height:120px;border-radius:14px;color:#6734c9;background:#ffffffd1;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);font-size:.9rem;font-weight:700}.metric-loading-spinner{font-size:1.5rem}.metric-list-loading{pointer-events:none;-webkit-user-select:none;user-select:none;opacity:.42;filter:blur(.4px)}\n"] }]
7823
+ args: [{ selector: 'pt-metric-panel', standalone: false, template: "<pt-card [config]=\"cardConfig\">\n <div class=\"panel-header\">\n <div class=\"panel-title-container\" [ngStyle]=\"getTitleStyles()\">\n @if (getTitleIcon()) {\n <i\n class=\"panel-title-icon\"\n [ngClass]=\"getIconClass(getTitleIcon())\"\n [ngStyle]=\"getTitleIconStyles()\"\n ></i>\n }\n\n <span class=\"panel-title-text\">\n {{ getTitleText() }}\n </span>\n </div>\n\n @if (showRefresh || shouldShowMenu) {\n <div class=\"panel-actions\">\n @if (showRefresh) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [class.panel-action-button-loading]=\"isLoading\"\n [disabled]=\"isLoading\"\n aria-label=\"Actualiser\"\n title=\"Actualiser\"\n (click)=\"onRefreshClick($event)\"\n >\n <i\n class=\"pi\"\n [ngClass]=\"isLoading ? 'pi-spin pi-spinner' : 'pi-refresh'\"\n ></i>\n </button>\n }\n\n @if (shouldShowMenu) {\n <button\n type=\"button\"\n class=\"panel-action-button\"\n [disabled]=\"isLoading\"\n aria-label=\"Plus d\u2019actions\"\n title=\"Plus d\u2019actions\"\n (click)=\"toggleMenu($event)\"\n >\n <i class=\"pi pi-ellipsis-v\"></i>\n </button>\n\n <p-menu\n #actionMenu\n [model]=\"actionMenuItems\"\n [popup]=\"true\"\n appendTo=\"body\"\n ></p-menu>\n }\n </div>\n }\n </div>\n\n <div class=\"panel-separator\"></div>\n\n <div class=\"metric-content\">\n @if (isLoading) {\n <div\n class=\"metric-loading-overlay\"\n aria-live=\"polite\"\n aria-label=\"Chargement des donn\u00E9es\"\n >\n <i class=\"pi pi-spinner pi-spin metric-loading-spinner\"></i>\n <span>Chargement des donn\u00E9es...</span>\n </div>\n }\n\n <div\n class=\"metric-list\"\n [class.metric-list-loading]=\"isLoading\"\n [attr.aria-busy]=\"isLoading\"\n >\n @for (item of panelData.indicators; track $index) {\n <div\n class=\"metric-item\"\n [class.metric-item-clickable]=\"!!item.url && !isLoading\"\n [pTooltip]=\"item.tooltip || ''\"\n tooltipPosition=\"top\"\n [tooltipDisabled]=\"!item.tooltip || isLoading\"\n (click)=\"!isLoading && handleClick(item.url)\"\n >\n <div class=\"metric-left\">\n @if (item.icon) {\n <span class=\"metric-icon-wrapper\">\n <i\n [ngClass]=\"getIconClass(item.icon.code)\"\n [ngStyle]=\"getIconStyles(item.icon)\"\n ></i>\n </span>\n }\n\n <span class=\"metric-title\">\n {{ isTitleStyle(item.title) ? item.title.text : item.title }}\n </span>\n </div>\n\n <span\n class=\"metric-value\"\n [class.metric-value-highlighted]=\"item.highlighted && !isLoading\"\n [ngStyle]=\"getValueStyles(item.value)\"\n >\n {{ isTitleStyle(item.value) ? item.value.text : item.value }}\n </span>\n </div>\n }\n </div>\n </div>\n</pt-card>\n", styles: [":host{display:block}.panel-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}.panel-title-container{display:flex;align-items:center;min-width:0;gap:12px;font-weight:800;line-height:1.2}.panel-title-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;min-width:38px;min-height:38px;padding:10px;color:#6734c9;background:#f0e7ff;border-radius:12px;font-size:1.05rem}.panel-title-text{overflow:hidden;color:inherit;text-overflow:ellipsis;white-space:nowrap}.panel-actions{display:flex;align-items:center;flex:0 0 auto;gap:4px}.panel-action-button{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;cursor:pointer;border:1px solid transparent;border-radius:10px;color:#667085;background:transparent;transition:background-color .16s ease,border-color .16s ease,color .16s ease,transform .16s ease}.panel-action-button:hover:not(:disabled){border-color:#e3d8fb;color:#6734c9;background:#f7f3ff}.panel-action-button:active:not(:disabled){transform:scale(.95)}.panel-action-button:disabled{cursor:wait;opacity:.65}.panel-action-button-loading{color:#6734c9}.panel-action-button:focus-visible{outline:2px solid #8b5cf6;outline-offset:2px}.panel-separator{width:100%;height:1px;margin:0 0 16px;background:#e7eaf0}.metric-list{display:flex;flex-direction:column;gap:12px}.metric-item{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:68px;padding:12px 14px;background:#fff;border:1px solid #edf0f5;border-radius:14px;transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}.metric-item:hover{border-color:#ddd2f8;box-shadow:0 5px 14px #4a209014}.metric-item-clickable{cursor:pointer}.metric-item-clickable:hover{transform:translateY(-1px)}.metric-left{display:flex;align-items:center;min-width:0;gap:12px}.metric-icon-wrapper{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.metric-icon-wrapper i{display:inline-flex!important;align-items:center;justify-content:center;min-width:40px;min-height:40px;box-sizing:border-box}.metric-title{overflow:hidden;color:#344054;font-size:1rem;font-weight:700;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.metric-value{flex:0 0 auto;padding:7px 11px;color:#1f2937;background:#f8f9fc;border:1px solid #e8ebf1;border-radius:10px;font-size:.95rem;font-weight:800;line-height:1;text-align:right;white-space:nowrap}.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;animation:metric-value-flash 1.8s ease-out}@keyframes metric-value-flash{0%{color:#166534;background:#bbf7d0;border-color:#4ade80;transform:scale(1.08)}to{color:#15803d;background:#dcfce7;border-color:#86efac;transform:scale(1)}}@media(max-width:576px){.panel-header,.panel-title-container{gap:8px}.panel-title-icon{min-width:34px;min-height:34px;padding:8px}.panel-action-button{width:32px;height:32px}.metric-item{min-height:60px;padding:10px}.metric-title{font-size:.92rem}.metric-value{padding:6px 8px;font-size:.85rem}}.metric-content{position:relative;min-height:120px}.metric-loading-overlay{position:absolute;z-index:2;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.7rem;min-height:120px;border-radius:14px;color:#6734c9;background:#ffffffd1;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);font-size:.9rem;font-weight:700}.metric-loading-spinner{font-size:1.5rem}.metric-list-loading{pointer-events:none;-webkit-user-select:none;user-select:none;opacity:.42;filter:blur(.4px)}\n"] }]
7831
7824
  }], ctorParameters: () => [{ type: i1$2.Router }], propDecorators: { panelData: [{
7832
7825
  type: Input
7833
7826
  }], cardConfig: [{