Commit 5c8579b3 by Ooh-Ao

kpi card

parent bc8376ab
...@@ -264,6 +264,10 @@ export class DashboardManagementComponent implements OnInit { ...@@ -264,6 +264,10 @@ export class DashboardManagementComponent implements OnInit {
if (widget.config && typeof widget.config === 'object') { if (widget.config && typeof widget.config === 'object') {
widget.config = JSON.stringify(widget.config); 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 @@ ...@@ -618,7 +618,16 @@
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Icon Color</mat-label> <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> </mat-form-field>
</div> </div>
......
...@@ -54,7 +54,9 @@ export class WidgetConfigGeneratorService { ...@@ -54,7 +54,9 @@ export class WidgetConfigGeneratorService {
newConfig.title = widget.thName; newConfig.title = widget.thName;
newConfig.valueField = col1; newConfig.valueField = col1;
newConfig.icon = 'info-circle-fill'; 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; break;
case 'SlicerWidgetComponent': 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 --> <!-- Header -->
<div class="flex-shrink-0"> <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">
<h4 class="text-md sm:text-lg font-semibold text-gray-500 truncate">{{ title }}</h4> <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> </div>
<!-- Body --> <!-- Body -->
<div class="flex-grow flex justify-center items-center"> <div class="flex-1 flex justify-center items-center p-6">
<!-- Loading State --> <!-- Loading State -->
<div *ngIf="isLoading" class="text-center"> <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> <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-400 mt-2">Loading...</p> <p class="text-gray-500 mt-4 text-lg">Loading Data...</p>
</div> </div>
<!-- Error State --> <!-- Error State -->
<div *ngIf="hasError" class="text-center text-red-500"> <div *ngIf="hasError" class="text-center text-red-500">
<i class="bi bi-exclamation-circle-fill text-4xl"></i> <i class="bi bi-x-octagon-fill text-5xl"></i>
<p class="mt-2 font-semibold">Error</p> <p class="mt-3 text-xl font-semibold">Error Loading</p>
<p class="text-sm text-red-400">{{ errorMessage }}</p> <p class="text-sm text-red-400">{{ errorMessage }}</p>
</div> </div>
<!-- Content --> <!-- Content -->
<div *ngIf="!isLoading && !hasError" class="text-center"> <div *ngIf="!isLoading && !hasError" class="text-center">
<div class="flex justify-center items-center gap-4"> <p class="block font-sans text-7xl font-bold leading-snug tracking-normal text-blue-gray-900 antialiased">
<i *ngIf="icon" [style.color]="color" [class]="'bi bi-' + icon + ' text-5xl sm:text-6xl md:text-7xl'"></i> {{ value }}
<div> </p>
<div class="text-4xl sm:text-5xl md:text-6xl font-extrabold text-gray-900"> <p *ngIf="unit" class="block font-sans text-2xl font-normal leading-relaxed text-blue-gray-600 antialiased">
{{ value }} {{ unit }}
<span *ngIf="unit" class="text-xl sm:text-2xl font-medium text-gray-400 ml-1">{{ unit }}</span> </p>
</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>
</div> </div>
</div> </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'; ...@@ -14,10 +14,10 @@ import { BaseWidgetComponent } from '../base-widget.component';
export class SimpleKpiWidgetComponent extends BaseWidgetComponent { export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
public value: string = '...'; public value: string = '...';
public unit: string = ''; public unit: string = '';
public trend: 'up' | 'down' | 'neutral' = 'neutral';
public trendValue: string = '';
public icon: 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) { constructor(protected override dashboardStateService: DashboardStateService) {
super(dashboardStateService); super(dashboardStateService);
...@@ -26,10 +26,10 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent { ...@@ -26,10 +26,10 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
applyInitialConfig(): void { applyInitialConfig(): void {
this.title = this.config.title || 'KPI'; this.title = this.config.title || 'KPI';
this.unit = this.config.unit || ''; this.unit = this.config.unit || '';
this.trend = this.config.trend || 'neutral';
this.trendValue = this.config.trendValue || '';
this.icon = this.config.icon || 'info'; 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 this.value = '-'; // Initial state before data loads
} }
...@@ -68,7 +68,5 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent { ...@@ -68,7 +68,5 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
this.title = 'KPI (Default)'; this.title = 'KPI (Default)';
this.value = '123,456'; this.value = '123,456';
this.unit = '#'; 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