ng-prime-tools 1.1.28 → 1.1.30
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.
|
@@ -300,6 +300,21 @@ class PTAdvancedPrimeTableComponent {
|
|
|
300
300
|
const incomingData = (dataChange.currentValue ?? []);
|
|
301
301
|
if (this.isPendingReorderEcho(incomingData)) {
|
|
302
302
|
this.data = incomingData;
|
|
303
|
+
/*
|
|
304
|
+
* The consumer commonly returns cloned rows after a reorder (for
|
|
305
|
+
* example to update an order/rank property). Keep the current visual
|
|
306
|
+
* order, but replace the internal row references with the latest input
|
|
307
|
+
* objects. Otherwise, the next reorder compares objects originating
|
|
308
|
+
* from two different array instances and cannot merge the movement.
|
|
309
|
+
*/
|
|
310
|
+
this.tableData = this.reconcileRowsByIdentity(this.tableData, incomingData);
|
|
311
|
+
if (this.dt) {
|
|
312
|
+
this.dt.value = this.tableData;
|
|
313
|
+
if (Array.isArray(this.dt.filteredValue)) {
|
|
314
|
+
this.dt.filteredValue = this.reconcileRowsByIdentity(this.dt.filteredValue, incomingData);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
this.refreshReorderIndexes();
|
|
303
318
|
this.pendingReorderSignature = null;
|
|
304
319
|
return;
|
|
305
320
|
}
|
|
@@ -556,10 +571,10 @@ class PTAdvancedPrimeTableComponent {
|
|
|
556
571
|
return reorderedRows;
|
|
557
572
|
}
|
|
558
573
|
mergeReorderedRows(sourceRows, activeRows, reorderedActiveRows) {
|
|
559
|
-
const
|
|
574
|
+
const activeRowIdentities = new Set(activeRows.map((row) => this.getRowIdentity(row)));
|
|
560
575
|
let activeRowIndex = 0;
|
|
561
576
|
return (sourceRows ?? []).map((row) => {
|
|
562
|
-
if (!
|
|
577
|
+
if (!activeRowIdentities.has(this.getRowIdentity(row))) {
|
|
563
578
|
return row;
|
|
564
579
|
}
|
|
565
580
|
const reorderedRow = reorderedActiveRows[activeRowIndex];
|
|
@@ -567,6 +582,13 @@ class PTAdvancedPrimeTableComponent {
|
|
|
567
582
|
return reorderedRow;
|
|
568
583
|
});
|
|
569
584
|
}
|
|
585
|
+
reconcileRowsByIdentity(orderedRows, incomingRows) {
|
|
586
|
+
const incomingByIdentity = new Map();
|
|
587
|
+
(incomingRows ?? []).forEach((row) => {
|
|
588
|
+
incomingByIdentity.set(this.getRowIdentity(row), row);
|
|
589
|
+
});
|
|
590
|
+
return (orderedRows ?? []).map((row) => incomingByIdentity.get(this.getRowIdentity(row)) ?? row);
|
|
591
|
+
}
|
|
570
592
|
reorderRows(oldIndex, newIndex) {
|
|
571
593
|
const activeRows = this.activeRowsForReorder;
|
|
572
594
|
if (oldIndex < 0 ||
|
|
@@ -10327,7 +10349,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
10327
10349
|
}]
|
|
10328
10350
|
}] });
|
|
10329
10351
|
|
|
10330
|
-
// src/lib/components/pt-metric-panel/pt-metric-panel.component.ts
|
|
10331
10352
|
class PTMetricPanelComponent {
|
|
10332
10353
|
set loading(value) {
|
|
10333
10354
|
const previousLoading = this.dashboardLoading;
|
|
@@ -10449,6 +10470,98 @@ class PTMetricPanelComponent {
|
|
|
10449
10470
|
}
|
|
10450
10471
|
return {};
|
|
10451
10472
|
}
|
|
10473
|
+
hasMultipleValues(item) {
|
|
10474
|
+
return Array.isArray(item.values) && item.values.length > 0;
|
|
10475
|
+
}
|
|
10476
|
+
getVisibleValues(item) {
|
|
10477
|
+
return (item.values || []).filter((part) => part.visible !== false);
|
|
10478
|
+
}
|
|
10479
|
+
getTrendDirection(part) {
|
|
10480
|
+
if (part.trend?.direction) {
|
|
10481
|
+
return part.trend.direction;
|
|
10482
|
+
}
|
|
10483
|
+
if (typeof part.value !== 'number' ||
|
|
10484
|
+
typeof part.trend?.previousValue !== 'number') {
|
|
10485
|
+
return 'none';
|
|
10486
|
+
}
|
|
10487
|
+
if (part.value > part.trend.previousValue) {
|
|
10488
|
+
return 'up';
|
|
10489
|
+
}
|
|
10490
|
+
if (part.value < part.trend.previousValue) {
|
|
10491
|
+
return 'down';
|
|
10492
|
+
}
|
|
10493
|
+
return 'stable';
|
|
10494
|
+
}
|
|
10495
|
+
shouldShowTrendArrow(part) {
|
|
10496
|
+
return (part.trend?.showArrow !== false && this.getTrendDirection(part) !== 'none');
|
|
10497
|
+
}
|
|
10498
|
+
getTrendIcon(part) {
|
|
10499
|
+
const direction = this.getTrendDirection(part);
|
|
10500
|
+
switch (direction) {
|
|
10501
|
+
case 'up':
|
|
10502
|
+
return part.trend?.upIcon || 'pi pi-arrow-up';
|
|
10503
|
+
case 'down':
|
|
10504
|
+
return part.trend?.downIcon || 'pi pi-arrow-down';
|
|
10505
|
+
case 'stable':
|
|
10506
|
+
return part.trend?.stableIcon || 'pi pi-minus';
|
|
10507
|
+
default:
|
|
10508
|
+
return '';
|
|
10509
|
+
}
|
|
10510
|
+
}
|
|
10511
|
+
getTrendIconStyles(part) {
|
|
10512
|
+
const direction = this.getTrendDirection(part);
|
|
10513
|
+
switch (direction) {
|
|
10514
|
+
case 'up':
|
|
10515
|
+
return {
|
|
10516
|
+
color: part.trend?.upColor || '#15803D',
|
|
10517
|
+
};
|
|
10518
|
+
case 'down':
|
|
10519
|
+
return {
|
|
10520
|
+
color: part.trend?.downColor || '#DC2626',
|
|
10521
|
+
};
|
|
10522
|
+
case 'stable':
|
|
10523
|
+
return {
|
|
10524
|
+
color: part.trend?.stableColor || '#64748B',
|
|
10525
|
+
};
|
|
10526
|
+
default:
|
|
10527
|
+
return {};
|
|
10528
|
+
}
|
|
10529
|
+
}
|
|
10530
|
+
getValuePartStyles(part) {
|
|
10531
|
+
const direction = this.getTrendDirection(part);
|
|
10532
|
+
const titleStyle = this.isTitleStyle(part.value) ? part.value : undefined;
|
|
10533
|
+
let trendColor;
|
|
10534
|
+
let trendBackgroundColor;
|
|
10535
|
+
let trendBorderColor;
|
|
10536
|
+
switch (direction) {
|
|
10537
|
+
case 'up':
|
|
10538
|
+
trendColor = part.trend?.upColor || '#15803D';
|
|
10539
|
+
trendBackgroundColor = part.trend?.upBackgroundColor || '#DCFCE7';
|
|
10540
|
+
trendBorderColor = part.trend?.upBorderColor || '#86EFAC';
|
|
10541
|
+
break;
|
|
10542
|
+
case 'down':
|
|
10543
|
+
trendColor = part.trend?.downColor || '#DC2626';
|
|
10544
|
+
trendBackgroundColor = part.trend?.downBackgroundColor || '#FEE2E2';
|
|
10545
|
+
trendBorderColor = part.trend?.downBorderColor || '#FCA5A5';
|
|
10546
|
+
break;
|
|
10547
|
+
case 'stable':
|
|
10548
|
+
trendColor = part.trend?.stableColor || '#475569';
|
|
10549
|
+
trendBackgroundColor = part.trend?.stableBackgroundColor || '#F1F5F9';
|
|
10550
|
+
trendBorderColor = part.trend?.stableBorderColor || '#CBD5E1';
|
|
10551
|
+
break;
|
|
10552
|
+
default:
|
|
10553
|
+
break;
|
|
10554
|
+
}
|
|
10555
|
+
return {
|
|
10556
|
+
color: part.color || titleStyle?.color || trendColor || '#1F2937',
|
|
10557
|
+
backgroundColor: part.backgroundColor || trendBackgroundColor || '#F8F9FC',
|
|
10558
|
+
borderColor: part.borderColor || trendBorderColor || '#E8EBF1',
|
|
10559
|
+
fontSize: part.fontSize || titleStyle?.fontSize || '0.95rem',
|
|
10560
|
+
fontWeight: part.fontWeight || titleStyle?.fontWeight || '800',
|
|
10561
|
+
padding: part.padding || '7px 10px',
|
|
10562
|
+
borderRadius: part.borderRadius || '10px',
|
|
10563
|
+
};
|
|
10564
|
+
}
|
|
10452
10565
|
isTitleObject() {
|
|
10453
10566
|
return typeof this.panelData.title === 'object';
|
|
10454
10567
|
}
|
|
@@ -10506,11 +10619,11 @@ class PTMetricPanelComponent {
|
|
|
10506
10619
|
this.actionMenuItems = [...items, ...this.menuItems];
|
|
10507
10620
|
}
|
|
10508
10621
|
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 }); }
|
|
10509
|
-
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: i13.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"] }] }); }
|
|
10622
|
+
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\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-multiple]=\"hasMultipleValues(item)\"\n [class.metric-item-single-part]=\"\n hasMultipleValues(item) && getVisibleValues(item).length === 1\n \"\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 @if (hasMultipleValues(item)) {\n <div\n class=\"metric-values\"\n role=\"group\"\n aria-label=\"Valeurs de l\u2019indicateur\"\n >\n @for (part of getVisibleValues(item); track part.key) {\n <span\n class=\"metric-value metric-value-part\"\n [class.metric-value-highlighted]=\"\n part.highlighted && !isLoading\n \"\n [class.metric-value-up]=\"getTrendDirection(part) === 'up'\"\n [class.metric-value-down]=\"getTrendDirection(part) === 'down'\"\n [class.metric-value-stable]=\"\n getTrendDirection(part) === 'stable'\n \"\n [ngStyle]=\"getValuePartStyles(part)\"\n [pTooltip]=\"part.tooltip || ''\"\n tooltipPosition=\"top\"\n [tooltipDisabled]=\"!part.tooltip || isLoading\"\n >\n @if (shouldShowTrendArrow(part)) {\n <i\n class=\"metric-trend-icon\"\n [ngClass]=\"getTrendIcon(part)\"\n [ngStyle]=\"getTrendIconStyles(part)\"\n aria-hidden=\"true\"\n ></i>\n }\n\n @if (part.label) {\n <span class=\"metric-value-label\">\n {{ part.label }}\n </span>\n }\n\n <span class=\"metric-value-text\">\n {{\n isTitleStyle(part.value) ? part.value.text : part.value\n }}\n </span>\n\n @if (part.suffix) {\n <span class=\"metric-value-suffix\">\n {{ part.suffix }}\n </span>\n }\n </span>\n }\n </div>\n } @else {\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 }\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-content{position:relative;min-height:120px}.metric-list{display:flex;flex-direction:column;gap:12px}.metric-item{display:flex;align-items:center;justify-content:space-between;gap:16px;min-width:0;min-height:68px;padding:12px 14px;box-sizing:border-box;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;min-width:0;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;box-sizing:border-box;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-item-multiple{display:grid;grid-template-columns:minmax(0,1fr);align-items:stretch;gap:12px}.metric-item-multiple .metric-left{width:100%}.metric-item-multiple .metric-title{white-space:normal}.metric-values{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));align-items:stretch;width:100%;min-width:0;gap:8px}.metric-value-part{display:inline-flex;align-items:center;justify-content:center;width:100%;min-width:0;gap:5px;overflow:hidden;transition:color .18s ease,background-color .18s ease,border-color .18s ease,box-shadow .18s ease,transform .18s ease}.metric-value-label{flex:0 0 auto;font-size:.72em;font-weight:700;line-height:1;opacity:.72;text-transform:uppercase}.metric-value-text{overflow:hidden;min-width:0;font:inherit;line-height:inherit;text-overflow:ellipsis}.metric-value-suffix{flex:0 0 auto;font-size:.85em;font-weight:inherit;line-height:1;opacity:.85}.metric-trend-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;font-size:.78em;font-weight:800;line-height:1}.metric-item-single-part{grid-template-columns:minmax(0,1fr) auto;align-items:center}.metric-item-single-part .metric-left{width:auto}.metric-item-single-part .metric-values{display:flex;align-items:center;justify-content:flex-end;width:auto}.metric-item-single-part .metric-value-part{width:auto;min-width:120px}.metric-value-up{color:#15803d;background:#dcfce7;border-color:#86efac}.metric-value-down{color:#dc2626;background:#fee2e2;border-color:#fca5a5}.metric-value-stable{color:#475569;background:#f1f5f9;border-color:#cbd5e1}.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;animation:metric-value-flash 1.8s ease-out}.metric-value-part.metric-value-highlighted{animation:metric-part-flash 1.8s ease-out}.metric-value-part.metric-value-up.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;box-shadow:0 0 0 3px #22c55e24}.metric-value-part.metric-value-down.metric-value-highlighted{color:#dc2626!important;background:#fee2e2!important;border-color:#fca5a5!important;box-shadow:0 0 0 3px #ef444424}.metric-value-part.metric-value-stable.metric-value-highlighted{color:#475569!important;background:#f1f5f9!important;border-color:#cbd5e1!important;box-shadow:0 0 0 3px #64748b1f}.metric-value-part.metric-value-highlighted:not(.metric-value-up):not(.metric-value-down):not(.metric-value-stable){color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;box-shadow:0 0 0 3px #22c55e24}@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)}}@keyframes metric-part-flash{0%{transform:scale(1.08)}45%{transform:scale(1.04)}to{transform:scale(1)}}.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)}@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;gap:10px}.metric-left{gap:8px}.metric-title{font-size:.92rem}.metric-value{padding:6px 8px;font-size:.85rem}.metric-item-multiple,.metric-item-single-part{grid-template-columns:minmax(0,1fr);align-items:stretch}.metric-values,.metric-item-single-part .metric-values{display:grid;grid-template-columns:minmax(0,1fr);width:100%;max-width:none;gap:6px}.metric-value-part,.metric-item-single-part .metric-value-part{justify-content:flex-start;width:100%;min-width:0;padding:7px 9px!important;font-size:.82rem!important}.metric-value-label{display:inline}.metric-trend-icon{font-size:.75em}}@media(max-width:400px){.metric-item:not(.metric-item-multiple){align-items:flex-start;flex-direction:column}.metric-item:not(.metric-item-multiple) .metric-left{width:100%}.metric-item:not(.metric-item-multiple)>.metric-value{align-self:flex-end}}@media(prefers-reduced-motion:reduce){.panel-action-button,.metric-item,.metric-value-part{transition:none}.metric-value-highlighted,.metric-value-part.metric-value-highlighted{animation:none}}\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: i13.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"] }] }); }
|
|
10510
10623
|
}
|
|
10511
10624
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMetricPanelComponent, decorators: [{
|
|
10512
10625
|
type: Component,
|
|
10513
|
-
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"] }]
|
|
10626
|
+
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\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-multiple]=\"hasMultipleValues(item)\"\n [class.metric-item-single-part]=\"\n hasMultipleValues(item) && getVisibleValues(item).length === 1\n \"\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 @if (hasMultipleValues(item)) {\n <div\n class=\"metric-values\"\n role=\"group\"\n aria-label=\"Valeurs de l\u2019indicateur\"\n >\n @for (part of getVisibleValues(item); track part.key) {\n <span\n class=\"metric-value metric-value-part\"\n [class.metric-value-highlighted]=\"\n part.highlighted && !isLoading\n \"\n [class.metric-value-up]=\"getTrendDirection(part) === 'up'\"\n [class.metric-value-down]=\"getTrendDirection(part) === 'down'\"\n [class.metric-value-stable]=\"\n getTrendDirection(part) === 'stable'\n \"\n [ngStyle]=\"getValuePartStyles(part)\"\n [pTooltip]=\"part.tooltip || ''\"\n tooltipPosition=\"top\"\n [tooltipDisabled]=\"!part.tooltip || isLoading\"\n >\n @if (shouldShowTrendArrow(part)) {\n <i\n class=\"metric-trend-icon\"\n [ngClass]=\"getTrendIcon(part)\"\n [ngStyle]=\"getTrendIconStyles(part)\"\n aria-hidden=\"true\"\n ></i>\n }\n\n @if (part.label) {\n <span class=\"metric-value-label\">\n {{ part.label }}\n </span>\n }\n\n <span class=\"metric-value-text\">\n {{\n isTitleStyle(part.value) ? part.value.text : part.value\n }}\n </span>\n\n @if (part.suffix) {\n <span class=\"metric-value-suffix\">\n {{ part.suffix }}\n </span>\n }\n </span>\n }\n </div>\n } @else {\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 }\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-content{position:relative;min-height:120px}.metric-list{display:flex;flex-direction:column;gap:12px}.metric-item{display:flex;align-items:center;justify-content:space-between;gap:16px;min-width:0;min-height:68px;padding:12px 14px;box-sizing:border-box;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;min-width:0;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;box-sizing:border-box;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-item-multiple{display:grid;grid-template-columns:minmax(0,1fr);align-items:stretch;gap:12px}.metric-item-multiple .metric-left{width:100%}.metric-item-multiple .metric-title{white-space:normal}.metric-values{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));align-items:stretch;width:100%;min-width:0;gap:8px}.metric-value-part{display:inline-flex;align-items:center;justify-content:center;width:100%;min-width:0;gap:5px;overflow:hidden;transition:color .18s ease,background-color .18s ease,border-color .18s ease,box-shadow .18s ease,transform .18s ease}.metric-value-label{flex:0 0 auto;font-size:.72em;font-weight:700;line-height:1;opacity:.72;text-transform:uppercase}.metric-value-text{overflow:hidden;min-width:0;font:inherit;line-height:inherit;text-overflow:ellipsis}.metric-value-suffix{flex:0 0 auto;font-size:.85em;font-weight:inherit;line-height:1;opacity:.85}.metric-trend-icon{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;font-size:.78em;font-weight:800;line-height:1}.metric-item-single-part{grid-template-columns:minmax(0,1fr) auto;align-items:center}.metric-item-single-part .metric-left{width:auto}.metric-item-single-part .metric-values{display:flex;align-items:center;justify-content:flex-end;width:auto}.metric-item-single-part .metric-value-part{width:auto;min-width:120px}.metric-value-up{color:#15803d;background:#dcfce7;border-color:#86efac}.metric-value-down{color:#dc2626;background:#fee2e2;border-color:#fca5a5}.metric-value-stable{color:#475569;background:#f1f5f9;border-color:#cbd5e1}.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;animation:metric-value-flash 1.8s ease-out}.metric-value-part.metric-value-highlighted{animation:metric-part-flash 1.8s ease-out}.metric-value-part.metric-value-up.metric-value-highlighted{color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;box-shadow:0 0 0 3px #22c55e24}.metric-value-part.metric-value-down.metric-value-highlighted{color:#dc2626!important;background:#fee2e2!important;border-color:#fca5a5!important;box-shadow:0 0 0 3px #ef444424}.metric-value-part.metric-value-stable.metric-value-highlighted{color:#475569!important;background:#f1f5f9!important;border-color:#cbd5e1!important;box-shadow:0 0 0 3px #64748b1f}.metric-value-part.metric-value-highlighted:not(.metric-value-up):not(.metric-value-down):not(.metric-value-stable){color:#15803d!important;background:#dcfce7!important;border-color:#86efac!important;box-shadow:0 0 0 3px #22c55e24}@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)}}@keyframes metric-part-flash{0%{transform:scale(1.08)}45%{transform:scale(1.04)}to{transform:scale(1)}}.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)}@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;gap:10px}.metric-left{gap:8px}.metric-title{font-size:.92rem}.metric-value{padding:6px 8px;font-size:.85rem}.metric-item-multiple,.metric-item-single-part{grid-template-columns:minmax(0,1fr);align-items:stretch}.metric-values,.metric-item-single-part .metric-values{display:grid;grid-template-columns:minmax(0,1fr);width:100%;max-width:none;gap:6px}.metric-value-part,.metric-item-single-part .metric-value-part{justify-content:flex-start;width:100%;min-width:0;padding:7px 9px!important;font-size:.82rem!important}.metric-value-label{display:inline}.metric-trend-icon{font-size:.75em}}@media(max-width:400px){.metric-item:not(.metric-item-multiple){align-items:flex-start;flex-direction:column}.metric-item:not(.metric-item-multiple) .metric-left{width:100%}.metric-item:not(.metric-item-multiple)>.metric-value{align-self:flex-end}}@media(prefers-reduced-motion:reduce){.panel-action-button,.metric-item,.metric-value-part{transition:none}.metric-value-highlighted,.metric-value-part.metric-value-highlighted{animation:none}}\n"] }]
|
|
10514
10627
|
}], ctorParameters: () => [{ type: i1$2.Router }], propDecorators: { panelData: [{
|
|
10515
10628
|
type: Input
|
|
10516
10629
|
}], cardConfig: [{
|