Commit 5c8579b3 by Ooh-Ao

kpi card

parent bc8376ab
......@@ -264,6 +264,10 @@ export class DashboardManagementComponent implements OnInit {
if (widget.config && typeof widget.config === 'object') {
widget.config = JSON.stringify(widget.config);
}
// Add stringify for perspective
if (widget.perspective && typeof widget.perspective === 'object') {
widget.perspective = JSON.stringify(widget.perspective);
}
});
}
......
......@@ -618,7 +618,16 @@
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Icon Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.color" name="color" class="h-[40px]">
<input matInput type="color" [(ngModel)]="currentConfig.iconColor" name="iconColor" class="h-[40px]">
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Background Color (Header)</mat-label>
<input matInput [(ngModel)]="currentConfig.backgroundColor" name="backgroundColor">
<mat-hint>e.g., 'red', '#FF0000', 'linear-gradient(to right, red, yellow)'</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Color (Card)</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.borderColor" name="borderColor" class="h-[40px]">
</mat-form-field>
</div>
......
......@@ -54,7 +54,9 @@ export class WidgetConfigGeneratorService {
newConfig.title = widget.thName;
newConfig.valueField = col1;
newConfig.icon = 'info-circle-fill';
newConfig.color = '#000000';
newConfig.backgroundColor = 'linear-gradient(to top right, #3366FF, #00CCFF)'; // Default background
newConfig.iconColor = '#FFFFFF'; // Default icon color
newConfig.borderColor = '#FFFFFF'; // Default border color
break;
case 'SlicerWidgetComponent':
......
<div class="bg-white rounded-xl shadow-lg p-4 sm:p-6 flex flex-col h-full">
<!-- simple-kpi-widget.component.html -->
<div [style.border-color]="borderColor" class="relative flex flex-col h-full rounded-xl bg-white bg-clip-border text-gray-700 shadow-md transition-shadow duration-300 ease-in-out hover:shadow-lg hover:shadow-gray-900/10 border-2">
<!-- Header -->
<div class="flex-shrink-0">
<h4 class="text-md sm:text-lg font-semibold text-gray-500 truncate">{{ title }}</h4>
<div [style.background]="backgroundColor" class="relative mx-4 -mt-4 rounded-xl bg-clip-border text-white shadow-lg shadow-blue-500/40 p-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<i *ngIf="icon" [style.color]="iconColor" [class]="'bi bi-' + icon + ' text-4xl'"></i>
<h4 class="text-xl font-semibold truncate">{{ title }}</h4>
</div>
<!-- Removed trendValue display -->
</div>
</div>
<!-- Body -->
<div class="flex-grow flex justify-center items-center">
<div class="flex-1 flex justify-center items-center p-6">
<!-- Loading State -->
<div *ngIf="isLoading" class="text-center">
<div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500 mx-auto"></div>
<p class="text-gray-400 mt-2">Loading...</p>
<div class="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-500 mx-auto"></div>
<p class="text-gray-500 mt-4 text-lg">Loading Data...</p>
</div>
<!-- Error State -->
<div *ngIf="hasError" class="text-center text-red-500">
<i class="bi bi-exclamation-circle-fill text-4xl"></i>
<p class="mt-2 font-semibold">Error</p>
<i class="bi bi-x-octagon-fill text-5xl"></i>
<p class="mt-3 text-xl font-semibold">Error Loading</p>
<p class="text-sm text-red-400">{{ errorMessage }}</p>
</div>
<!-- Content -->
<div *ngIf="!isLoading && !hasError" class="text-center">
<div class="flex justify-center items-center gap-4">
<i *ngIf="icon" [style.color]="color" [class]="'bi bi-' + icon + ' text-5xl sm:text-6xl md:text-7xl'"></i>
<div>
<div class="text-4xl sm:text-5xl md:text-6xl font-extrabold text-gray-900">
{{ value }}
<span *ngIf="unit" class="text-xl sm:text-2xl font-medium text-gray-400 ml-1">{{ unit }}</span>
</div>
<div *ngIf="trendValue" class="flex items-center justify-center text-sm sm:text-base mt-2">
<span *ngIf="trend === 'up'" class="text-green-500 flex items-center font-semibold">
<i class="bi bi-arrow-up-right mr-1"></i>
{{ trendValue }}
</span>
<span *ngIf="trend === 'down'" class="text-red-500 flex items-center font-semibold">
<i class="bi bi-arrow-down-right mr-1"></i>
{{ trendValue }}
</span>
<span *ngIf="trend === 'neutral' && trendValue" class="text-gray-500 font-medium">
{{ trendValue }}
</span>
</div>
</div>
</div>
<p class="block font-sans text-7xl font-bold leading-snug tracking-normal text-blue-gray-900 antialiased">
{{ value }}
</p>
<p *ngIf="unit" class="block font-sans text-2xl font-normal leading-relaxed text-blue-gray-600 antialiased">
{{ unit }}
</p>
</div>
</div>
</div>
.card {
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
......@@ -14,10 +14,10 @@ import { BaseWidgetComponent } from '../base-widget.component';
export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
public value: string = '...';
public unit: string = '';
public trend: 'up' | 'down' | 'neutral' = 'neutral';
public trendValue: string = '';
public icon: string = '';
public color: string = '#000000';
public backgroundColor: string = 'linear-gradient(to top right, #3366FF, #00CCFF)';
public iconColor: string = '#FFFFFF';
public borderColor: string = '#FFFFFF';
constructor(protected override dashboardStateService: DashboardStateService) {
super(dashboardStateService);
......@@ -26,10 +26,10 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
applyInitialConfig(): void {
this.title = this.config.title || 'KPI';
this.unit = this.config.unit || '';
this.trend = this.config.trend || 'neutral';
this.trendValue = this.config.trendValue || '';
this.icon = this.config.icon || 'info';
this.color = this.config.color || '#000000';
this.backgroundColor = this.config.backgroundColor || 'linear-gradient(to top right, #3366FF, #00CCFF)';
this.iconColor = this.config.iconColor || '#FFFFFF';
this.borderColor = this.config.borderColor || '#FFFFFF';
this.value = '-'; // Initial state before data loads
}
......@@ -68,7 +68,5 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
this.title = 'KPI (Default)';
this.value = '123,456';
this.unit = '#';
this.trend = 'neutral';
this.trendValue = '';
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment