Commit bcf94449 by Ooh-Ao

ปรับวิดเจ็ท

parent cce1d45e
<div class="p-4 bg-white rounded-lg shadow-md h-full flex flex-col justify-between">
<div>
<h5 class="text-lg font-semibold text-gray-600 mb-2">{{ kpiName }}</h5>
<!-- Loading State -->
<div *ngIf="isLoading" class="flex justify-center items-center h-full">
<div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500"></div>
</div>
<!-- Error State -->
<div *ngIf="hasError" class="flex flex-col justify-center items-center h-full text-red-500">
<i class="bi bi-exclamation-triangle-fill text-4xl"></i>
<p class="mt-2">{{ errorMessage }}</p>
</div>
<!-- Content -->
<div *ngIf="!isLoading && !hasError">
<h5 class="text-lg font-semibold text-gray-600 mb-2">{{ title }}</h5>
<div class="text-4xl font-bold text-gray-800">
{{ kpiData.value }}<span *ngIf="kpiData.unit" class="text-2xl ml-1">{{ kpiData.unit }}</span>
</div>
......@@ -18,4 +31,5 @@
</span>
</div>
</div>
</div>
</div>
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetService } from '../../services/dataset.service';
import { DatasetModel } from '../../models/widgets.model';
import { MockDataService } from '../../common/mock-data.service';
import { DashboardStateService } from '../../services/dashboard-state.service';
import { BaseWidgetComponent } from '../base-widget.component';
@Component({
selector: 'app-kpi-widget',
standalone: true,
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient, MockDataService],
imports: [CommonModule],
templateUrl: './kpi-widget.component.html',
})
export class KpiWidgetComponent implements OnInit, OnChanges {
@Input() kpiName: string = 'New Hires'; // Default KPI
@Input() config: any;
export class KpiWidgetComponent extends BaseWidgetComponent {
public kpiData: any = { value: 0, trend: 'neutral', trendValue: '' };
// kpiData!: { value: number, trend: 'up' | 'down' | 'flat', percentage: number, unit: string, trendValue: string };
kpiData: any
constructor(private mockDataService: MockDataService) { }
ngOnInit(): void {
this.kpiData = this.mockDataService.getKpiData(this.kpiName);
constructor(protected override dashboardStateService: DashboardStateService) {
super(dashboardStateService);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['kpiName']) {
this.kpiData = this.mockDataService.getKpiData(this.kpiName);
onDataUpdate(data: any[]): void {
if (data.length > 0) {
let kpiValue = 0;
if (this.config.aggregation === 'count') {
kpiValue = data.length;
} else if (this.config.aggregation === 'sum') {
kpiValue = data.reduce((sum, item) => sum + (item[this.config.valueField] || 0), 0);
} else {
kpiValue = data[0][this.config.valueField];
}
this.kpiData = {
value: kpiValue.toLocaleString(),
unit: this.config.unit || '',
trend: this.config.trend || 'neutral',
trendValue: this.config.trendValue || ''
};
}
}
onReset(): void {
this.title = 'KPI (Default)';
this.kpiData = {
value: '12,345',
unit: '#',
trend: 'up',
trendValue: '+5%'
};
}
}
<div class="card h-100">
<div class="card-header">
<h5 class="card-title">Quick Links</h5>
<h5 class="card-title">{{ title }}</h5>
</div>
<div class="card-body">
<ul>
<!-- Loading State -->
<div *ngIf="isLoading" class="flex justify-center items-center h-full">
<div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500"></div>
</div>
<!-- Error State -->
<div *ngIf="hasError" class="flex flex-col justify-center items-center h-full text-red-500">
<i class="bi bi-exclamation-triangle-fill text-4xl"></i>
<p class="mt-2">{{ errorMessage }}</p>
</div>
<!-- Content -->
<ul *ngIf="!isLoading && !hasError">
<li *ngFor="let link of quickLinks">
<a [href]="link.url" target="_blank" class="text-blue-500 hover:underline">{{ link.name }}</a>
</li>
<li *ngIf="quickLinks.length === 0">
<span class="text-gray-500">No links available.</span>
</li>
</ul>
</div>
</div>
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MockDataService } from '../../common/mock-data.service';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
import { DashboardStateService } from '../../services/dashboard-state.service';
import { BaseWidgetComponent } from '../base-widget.component';
@Component({
selector: 'app-quick-links-widget',
standalone: true,
imports: [CommonModule, HttpClientModule],
providers: [DatasetService, HttpClient],
imports: [CommonModule],
templateUrl: './quick-links-widget.component.html',
})
export class QuickLinksWidgetComponent implements OnInit, OnChanges {
@Input() links: { name: string, url: string }[] | undefined; // New input for links
@Input() config: any;
quickLinks: { name: string, url: string }[] = [];
export class QuickLinksWidgetComponent extends BaseWidgetComponent {
public quickLinks: { name: string, url: string }[] = [];
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.config || !this.config.datasetId) {
this.quickLinks = [
{ name: 'Google', url: 'https://www.google.com' },
{ name: 'Angular', url: 'https://angular.io' },
];
}
constructor(protected override dashboardStateService: DashboardStateService) {
super(dashboardStateService);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.quickLinks = [
{ name: 'Google', url: 'https://www.google.com' },
{ name: 'Angular', url: 'https://angular.io' },
];
onDataUpdate(data: any[]): void {
if (this.config.nameField && this.config.urlField) {
this.quickLinks = data.map(item => ({
name: item[this.config.nameField],
url: item[this.config.urlField]
}));
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (this.config.nameField && this.config.urlField) {
this.quickLinks = data.map(item => ({ name: item[this.config.nameField], url: item[this.config.urlField] }));
}
});
}
});
}
onReset(): void {
this.title = 'Quick Links (Default)';
this.quickLinks = [
{ name: 'Google', url: 'https://www.google.com' },
{ name: 'Angular', url: 'https://angular.io' },
{ name: 'Syncfusion', url: 'https://www.syncfusion.com' },
];
}
}
<div class="card h-100">
<div class="card-body flex flex-col justify-center items-center">
<h3 class="text-2xl font-bold text-gray-800">{{ welcomeMessage }}</h3>
<!-- Loading State -->
<div *ngIf="isLoading" class="flex justify-center items-center h-full">
<div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500"></div>
</div>
<!-- Error State -->
<div *ngIf="hasError" class="flex flex-col justify-center items-center h-full text-red-500">
<i class="bi bi-exclamation-triangle-fill text-4xl"></i>
<p class="mt-2">{{ errorMessage }}</p>
</div>
<!-- Content -->
<h3 *ngIf="!isLoading && !hasError" class="text-2xl font-bold text-gray-800">{{ welcomeMessage }}</h3>
</div>
</div>
import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MockDataService } from '../../common/mock-data.service';
import { DatasetService } from '../../services/dataset.service';
import { HttpClient } from '@angular/common/http';
import { DatasetModel } from '../../models/widgets.model';
import { DashboardStateService } from '../../services/dashboard-state.service';
import { BaseWidgetComponent } from '../base-widget.component';
@Component({
selector: 'app-welcome-widget',
......@@ -11,40 +9,23 @@ import { DatasetModel } from '../../models/widgets.model';
imports: [CommonModule],
templateUrl: './welcome-widget.component.html',
})
export class WelcomeWidgetComponent implements OnInit {
@Input() config: any;
@Input() userName: string = 'Admin'; // New input property
welcomeMessage: string = '';
export class WelcomeWidgetComponent extends BaseWidgetComponent {
public welcomeMessage: string = '';
constructor(private datasetService: DatasetService, private http: HttpClient) { }
ngOnInit(): void {
if (!this.config || !this.config.datasetId) {
this.welcomeMessage = 'Welcome, Admin!';
}
constructor(protected override dashboardStateService: DashboardStateService) {
super(dashboardStateService);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['config'] && this.config && this.config.datasetId) {
this.loadData();
} else if (changes['config'] && (!this.config || !this.config.datasetId)) {
this.welcomeMessage = 'Welcome, Admin!';
onDataUpdate(data: any[]): void {
if (data.length > 0 && this.config.messageField) {
this.welcomeMessage = data[0][this.config.messageField];
} else {
this.onReset();
}
}
loadData(): void {
if (this.config.datasetId) {
this.datasetService.getDatasetById(this.config.datasetId).subscribe((dataset: DatasetModel | undefined) => {
if (dataset && dataset.url) {
this.http.get<any[]>(dataset.url).subscribe(data => {
if (data.length > 0 && this.config.messageField) {
this.welcomeMessage = data[0][this.config.messageField];
} else {
this.welcomeMessage = 'Welcome, Admin!';
}
});
}
});
}
onReset(): void {
this.title = ''; // Welcome widget might not need a title
this.welcomeMessage = 'Welcome, Admin!';
}
}
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