Commit 2739dc53 by Ooh-Ao

s

parent 21fe2147
...@@ -3,6 +3,8 @@ import { SimpleKpiConfigComponent } from '../../widgets/configs/simple-kpi-confi ...@@ -3,6 +3,8 @@ import { SimpleKpiConfigComponent } from '../../widgets/configs/simple-kpi-confi
import { SyncfusionDatagridConfigComponent } from '../../widgets/configs/syncfusion-datagrid-config/syncfusion-datagrid-config.component'; import { SyncfusionDatagridConfigComponent } from '../../widgets/configs/syncfusion-datagrid-config/syncfusion-datagrid-config.component';
import { SyncfusionPivotConfigComponent } from '../../widgets/configs/syncfusion-pivot-config/syncfusion-pivot-config.component'; import { SyncfusionPivotConfigComponent } from '../../widgets/configs/syncfusion-pivot-config/syncfusion-pivot-config.component';
import { ChartConfigComponent } from '../../widgets/configs/chart-config/chart-config.component'; import { ChartConfigComponent } from '../../widgets/configs/chart-config/chart-config.component';
import { TableConfigComponent } from '../../widgets/configs/table-config/table-config.component';
import { CardConfigComponent } from '../../widgets/configs/card-config/card-config.component';
import { CompanyInfoConfigComponent } from '../../widgets/configs/company-info-config/company-info-config.component'; import { CompanyInfoConfigComponent } from '../../widgets/configs/company-info-config/company-info-config.component';
import { AttendanceConfigComponent } from '../../widgets/configs/attendance-config/attendance-config.component'; import { AttendanceConfigComponent } from '../../widgets/configs/attendance-config/attendance-config.component';
import { PayrollConfigComponent } from '../../widgets/configs/payroll-config/payroll-config.component'; import { PayrollConfigComponent } from '../../widgets/configs/payroll-config/payroll-config.component';
...@@ -48,10 +50,21 @@ export class WidgetConfigRegistryService { ...@@ -48,10 +50,21 @@ export class WidgetConfigRegistryService {
this.registerConfig('DoughnutChartWidgetComponent', ChartConfigComponent); this.registerConfig('DoughnutChartWidgetComponent', ChartConfigComponent);
this.registerConfig('FunnelChartWidgetComponent', ChartConfigComponent); this.registerConfig('FunnelChartWidgetComponent', ChartConfigComponent);
this.registerConfig('ScatterBubbleChartWidgetComponent', ChartConfigComponent); this.registerConfig('ScatterBubbleChartWidgetComponent', ChartConfigComponent);
this.registerConfig('WaterfallChartWidgetComponent', ChartConfigComponent);
this.registerConfig('ComboChartWidgetComponent', ChartConfigComponent);
this.registerConfig('GaugeChartWidgetComponent', ChartConfigComponent); this.registerConfig('GaugeChartWidgetComponent', ChartConfigComponent);
this.registerConfig('TreemapWidgetComponent', ChartConfigComponent); this.registerConfig('TreemapWidgetComponent', ChartConfigComponent);
this.registerConfig('WaterfallChartWidgetComponent', ChartConfigComponent);
this.registerConfig('ComboChartWidgetComponent', ChartConfigComponent);
// Register table widgets with TableConfigComponent
this.registerConfig('DataTableWidgetComponent', TableConfigComponent);
this.registerConfig('SimpleTableWidgetComponent', TableConfigComponent);
this.registerConfig('SyncfusionDatagridWidgetComponent', TableConfigComponent);
// Register card widgets with CardConfigComponent
this.registerConfig('MultiRowCardWidgetComponent', CardConfigComponent);
this.registerConfig('NotificationWidgetComponent', CardConfigComponent);
this.registerConfig('WelcomeWidgetComponent', CardConfigComponent);
this.registerConfig('QuickLinksWidgetComponent', CardConfigComponent);
} }
registerConfig(widgetType: string, configComponent: Type<WidgetConfigComponent>): void { registerConfig(widgetType: string, configComponent: Type<WidgetConfigComponent>): void {
......
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTabsModule } from '@angular/material/tabs';
import { BaseConfigComponent } from '../../../widget-config/base-config/base-config.component';
@Component({
selector: 'app-card-config',
standalone: true,
imports: [
CommonModule,
FormsModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatCheckboxModule,
MatButtonModule,
MatIconModule,
MatTabsModule
],
template: `
<div class="config-container">
<mat-tab-group class="config-tabs" dynamicHeight>
<!-- Basic Configuration Tab -->
<mat-tab label="Basic">
<div class="config-section">
<h3 class="section-title text-blue-600">Basic Configuration</h3>
<mat-form-field appearance="fill" class="w-full">
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title" aria-label="Card title">
<mat-hint>Card title displayed in header</mat-hint>
</mat-form-field>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Card Type</mat-label>
<mat-select [(ngModel)]="currentConfig.cardType" name="cardType">
<mat-option value="simple">Simple Card</mat-option>
<mat-option value="multi-row">Multi-Row Card</mat-option>
<mat-option value="company-info">Company Info</mat-option>
<mat-option value="notification">Notification</mat-option>
<mat-option value="welcome">Welcome Card</mat-option>
</mat-select>
<mat-hint>Type of card to display</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Data Source</mat-label>
<mat-select [(ngModel)]="currentConfig.dataSource" name="dataSource">
<mat-option value="static">Static Data</mat-option>
<mat-option value="api">API Endpoint</mat-option>
<mat-option value="dataset">Dataset</mat-option>
</mat-select>
<mat-hint>Source of the data</mat-hint>
</mat-form-field>
</div>
<mat-form-field *ngIf="currentConfig.dataSource === 'api'" appearance="fill" class="w-full">
<mat-label>API Endpoint</mat-label>
<input matInput [(ngModel)]="currentConfig.apiEndpoint" name="apiEndpoint" placeholder="https://api.example.com/card-data">
<mat-hint>API endpoint URL</mat-hint>
</mat-form-field>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Icon</mat-label>
<input matInput [(ngModel)]="currentConfig.icon" name="icon" placeholder="e.g., person-fill, building">
<mat-hint>Bootstrap icon name</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Icon Position</mat-label>
<mat-select [(ngModel)]="currentConfig.iconPosition" name="iconPosition">
<mat-option value="left">Left</mat-option>
<mat-option value="right">Right</mat-option>
<mat-option value="top">Top</mat-option>
<mat-option value="center">Center</mat-option>
</mat-select>
<mat-hint>Position of the icon</mat-hint>
</mat-form-field>
</div>
<mat-form-field appearance="fill" class="w-full">
<mat-label>Description</mat-label>
<textarea matInput [(ngModel)]="currentConfig.description" name="description" rows="3" placeholder="Card description or subtitle"></textarea>
<mat-hint>Optional description text</mat-hint>
</mat-form-field>
</div>
</mat-tab>
<!-- Content Tab -->
<mat-tab label="Content">
<div class="config-section">
<h3 class="section-title text-green-600">Content Configuration</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Primary Field</mat-label>
<mat-select [(ngModel)]="currentConfig.primaryField" name="primaryField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Main data field to display</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Secondary Field</mat-label>
<mat-select [(ngModel)]="currentConfig.secondaryField" name="secondaryField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Secondary data field</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Value Field</mat-label>
<mat-select [(ngModel)]="currentConfig.valueField" name="valueField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field containing the main value</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Label Field</mat-label>
<mat-select [(ngModel)]="currentConfig.labelField" name="labelField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field containing the label</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.showAvatar" name="showAvatar">
Show Avatar
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.showBadge" name="showBadge">
Show Badge
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.showActions" name="showActions">
Show Actions
</mat-checkbox>
</div>
<div *ngIf="currentConfig.showBadge" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Badge Text</mat-label>
<input matInput [(ngModel)]="currentConfig.badgeText" name="badgeText" placeholder="New">
<mat-hint>Badge text to display</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Badge Color</mat-label>
<mat-select [(ngModel)]="currentConfig.badgeColor" name="badgeColor">
<mat-option value="primary">Primary</mat-option>
<mat-option value="secondary">Secondary</mat-option>
<mat-option value="success">Success</mat-option>
<mat-option value="danger">Danger</mat-option>
<mat-option value="warning">Warning</mat-option>
<mat-option value="info">Info</mat-option>
</mat-select>
<mat-hint>Badge color theme</mat-hint>
</mat-form-field>
</div>
</div>
</mat-tab>
<!-- Styling Tab -->
<mat-tab label="Styling">
<div class="config-section">
<h3 class="section-title text-purple-600">Card Styling</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Background Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.backgroundColor" name="backgroundColor">
<mat-hint>Card background color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Text Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.textColor" name="textColor">
<mat-hint>Text color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Header Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.headerColor" name="headerColor">
<mat-hint>Header background color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.borderColor" name="borderColor">
<mat-hint>Card border color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<mat-form-field appearance="fill">
<mat-label>Font Size (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.fontSize" name="fontSize" min="10" max="24">
<mat-hint>Base font size</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Title Size (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.titleSize" name="titleSize" min="12" max="32">
<mat-hint>Title font size</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Icon Size (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.iconSize" name="iconSize" min="16" max="64">
<mat-hint>Icon size</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Padding (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.padding" name="padding" min="0" max="50">
<mat-hint>Internal spacing</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Radius (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.borderRadius" name="borderRadius" min="0" max="20">
<mat-hint>Corner roundness</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.elevated" name="elevated">
Elevated Card
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.outlined" name="outlined">
Outlined Card
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.flat" name="flat">
Flat Card
</mat-checkbox>
</div>
</div>
</mat-tab>
<!-- Layout Tab -->
<mat-tab label="Layout">
<div class="config-section">
<h3 class="section-title text-teal-600">Layout Settings</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Width (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.width" name="width" min="200" max="600">
<mat-hint>Card width</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Height (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.height" name="height" min="150" max="500">
<mat-hint>Card height</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Min Width (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.minWidth" name="minWidth" min="150" max="400">
<mat-hint>Minimum card width</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Max Width (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.maxWidth" name="maxWidth" min="300" max="800">
<mat-hint>Maximum card width</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Margin (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.margin" name="margin" min="0" max="30">
<mat-hint>Card margin</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Shadow</mat-label>
<mat-select [(ngModel)]="currentConfig.shadow" name="shadow">
<mat-option value="none">None</mat-option>
<mat-option value="small">Small</mat-option>
<mat-option value="medium">Medium</mat-option>
<mat-option value="large">Large</mat-option>
</mat-select>
<mat-hint>Card shadow effect</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.responsive" name="responsive">
Responsive Layout
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.fullWidth" name="fullWidth">
Full Width
</mat-checkbox>
</div>
</div>
</mat-tab>
<!-- Actions Tab -->
<mat-tab label="Actions">
<div class="config-section">
<h3 class="section-title text-orange-600">Action Configuration</h3>
<div class="flex items-center space-x-4 mb-4">
<mat-checkbox [(ngModel)]="currentConfig.enableClick" name="enableClick">
Enable Click
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableHover" name="enableHover">
Enable Hover
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableTooltip" name="enableTooltip">
Enable Tooltip
</mat-checkbox>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Click Action</mat-label>
<mat-select [(ngModel)]="currentConfig.clickAction" name="clickAction">
<mat-option value="none">None</mat-option>
<mat-option value="navigate">Navigate</mat-option>
<mat-option value="modal">Open Modal</mat-option>
<mat-option value="expand">Expand</mat-option>
<mat-option value="custom">Custom</mat-option>
</mat-select>
<mat-hint>Action when card is clicked</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Hover Effect</mat-label>
<mat-select [(ngModel)]="currentConfig.hoverEffect" name="hoverEffect">
<mat-option value="none">None</mat-option>
<mat-option value="lift">Lift</mat-option>
<mat-option value="glow">Glow</mat-option>
<mat-option value="scale">Scale</mat-option>
</mat-select>
<mat-hint>Effect on hover</mat-hint>
</mat-form-field>
</div>
<mat-form-field *ngIf="currentConfig.clickAction === 'custom'" appearance="fill" class="w-full">
<mat-label>Custom Click Handler</mat-label>
<textarea matInput [(ngModel)]="currentConfig.customClickHandler" name="customClickHandler" rows="3"
placeholder="function(event) {&#10; console.log('Card clicked:', event);&#10;}"></textarea>
<mat-hint>Custom JavaScript function for click events</mat-hint>
</mat-form-field>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.showCloseButton" name="showCloseButton">
Show Close Button
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.showMenuButton" name="showMenuButton">
Show Menu Button
</mat-checkbox>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
`,
styles: [`
.config-container {
padding: 20px;
background: #f8fafc;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.config-section {
margin-bottom: 32px;
padding: 24px;
background: white;
border-radius: 8px;
border: 1px solid #e2e8f0;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
}
.section-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 8px;
border-bottom: 2px solid #e2e8f0;
}
.config-tabs {
margin-top: 0;
}
.config-tabs .mat-tab-body-content {
padding: 20px 0;
}
.config-tabs .mat-tab-header {
background: white;
border-radius: 8px 8px 0 0;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
}
.config-tabs .mat-tab-label {
min-width: 120px;
font-weight: 500;
}
.config-tabs .mat-tab-label-active {
color: #3b82f6;
}
.mat-form-field {
margin-bottom: 8px;
}
.grid {
display: grid;
gap: 16px;
}
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (min-width: 768px) {
.md\\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.md\\:grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
.w-full {
width: 100%;
}
.flex {
display: flex;
}
.items-center {
align-items: center;
}
.space-x-4 > * + * {
margin-left: 16px;
}
.mb-4 {
margin-bottom: 16px;
}
.text-blue-600 { color: #2563eb; }
.text-green-600 { color: #16a34a; }
.text-purple-600 { color: #9333ea; }
.text-orange-600 { color: #ea580c; }
.text-teal-600 { color: #0d9488; }
`]
})
export class CardConfigComponent extends BaseConfigComponent implements OnInit {
override ngOnInit() {
this.initializeDefaultConfig();
this.initializeColorDefaults();
}
override initializeDefaultConfig() {
if (!this.currentConfig.title) this.currentConfig.title = 'Card Widget';
if (!this.currentConfig.cardType) this.currentConfig.cardType = 'simple';
if (!this.currentConfig.dataSource) this.currentConfig.dataSource = 'static';
if (!this.currentConfig.apiEndpoint) this.currentConfig.apiEndpoint = '';
if (!this.currentConfig.icon) this.currentConfig.icon = '';
if (!this.currentConfig.iconPosition) this.currentConfig.iconPosition = 'left';
if (!this.currentConfig.description) this.currentConfig.description = '';
if (!this.currentConfig.primaryField) this.currentConfig.primaryField = '';
if (!this.currentConfig.secondaryField) this.currentConfig.secondaryField = '';
if (!this.currentConfig.valueField) this.currentConfig.valueField = '';
if (!this.currentConfig.labelField) this.currentConfig.labelField = '';
if (!this.currentConfig.showAvatar) this.currentConfig.showAvatar = false;
if (!this.currentConfig.showBadge) this.currentConfig.showBadge = false;
if (!this.currentConfig.showActions) this.currentConfig.showActions = false;
if (!this.currentConfig.badgeText) this.currentConfig.badgeText = '';
if (!this.currentConfig.badgeColor) this.currentConfig.badgeColor = 'primary';
if (!this.currentConfig.width) this.currentConfig.width = 300;
if (!this.currentConfig.height) this.currentConfig.height = 200;
if (!this.currentConfig.minWidth) this.currentConfig.minWidth = 200;
if (!this.currentConfig.maxWidth) this.currentConfig.maxWidth = 500;
if (!this.currentConfig.margin) this.currentConfig.margin = 8;
if (!this.currentConfig.shadow) this.currentConfig.shadow = 'medium';
if (!this.currentConfig.responsive) this.currentConfig.responsive = true;
if (!this.currentConfig.fullWidth) this.currentConfig.fullWidth = false;
if (!this.currentConfig.enableClick) this.currentConfig.enableClick = false;
if (!this.currentConfig.enableHover) this.currentConfig.enableHover = true;
if (!this.currentConfig.enableTooltip) this.currentConfig.enableTooltip = false;
if (!this.currentConfig.clickAction) this.currentConfig.clickAction = 'none';
if (!this.currentConfig.hoverEffect) this.currentConfig.hoverEffect = 'lift';
if (!this.currentConfig.customClickHandler) this.currentConfig.customClickHandler = '';
if (!this.currentConfig.showCloseButton) this.currentConfig.showCloseButton = false;
if (!this.currentConfig.showMenuButton) this.currentConfig.showMenuButton = false;
}
private initializeColorDefaults() {
if (!this.currentConfig.backgroundColor) this.currentConfig.backgroundColor = '#FFFFFF';
if (!this.currentConfig.textColor) this.currentConfig.textColor = '#374151';
if (!this.currentConfig.headerColor) this.currentConfig.headerColor = '#F9FAFB';
if (!this.currentConfig.borderColor) this.currentConfig.borderColor = '#E5E7EB';
if (!this.currentConfig.fontSize) this.currentConfig.fontSize = 14;
if (!this.currentConfig.titleSize) this.currentConfig.titleSize = 18;
if (!this.currentConfig.iconSize) this.currentConfig.iconSize = 24;
if (!this.currentConfig.padding) this.currentConfig.padding = 16;
if (!this.currentConfig.borderRadius) this.currentConfig.borderRadius = 8;
if (!this.currentConfig.elevated) this.currentConfig.elevated = true;
if (!this.currentConfig.outlined) this.currentConfig.outlined = false;
if (!this.currentConfig.flat) this.currentConfig.flat = false;
}
}
...@@ -22,415 +22,438 @@ import { BaseConfigComponent } from '../../../widget-config/base-config/base-con ...@@ -22,415 +22,438 @@ import { BaseConfigComponent } from '../../../widget-config/base-config/base-con
MatCheckboxModule, MatCheckboxModule,
MatButtonModule, MatButtonModule,
MatIconModule, MatIconModule,
MatTabsModule, MatTabsModule
BaseConfigComponent
], ],
template: ` template: `
<app-base-config> <div class="config-container">
<!-- Basic Configuration Tab --> <mat-tab-group class="config-tabs" dynamicHeight>
<div class="config-section"> <!-- Basic Configuration Tab -->
<h3 class="text-blue-600">Basic Configuration</h3> <mat-tab label="Basic">
<div class="config-section">
<mat-form-field appearance="fill" class="w-full"> <h3 class="section-title text-blue-600">Basic Configuration</h3>
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title" aria-label="Chart title"> <mat-form-field appearance="fill" class="w-full">
<mat-hint>Chart title displayed in header</mat-hint> <mat-label>Title</mat-label>
</mat-form-field> <input matInput [(ngModel)]="currentConfig.title" name="title" aria-label="Chart title">
<mat-hint>Chart title displayed in header</mat-hint>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> </mat-form-field>
<mat-form-field appearance="fill">
<mat-label>X-Axis Field</mat-label> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-select [(ngModel)]="currentConfig.xField" name="xField"> <mat-form-field appearance="fill">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> <mat-label>Chart Type</mat-label>
</mat-select> <mat-select [(ngModel)]="currentConfig.chartType" name="chartType">
<mat-hint>Field for X-axis</mat-hint> <mat-option value="bar">Bar Chart</mat-option>
</mat-form-field> <mat-option value="line">Line Chart</mat-option>
<mat-option value="pie">Pie Chart</mat-option>
<mat-form-field appearance="fill"> <mat-option value="doughnut">Doughnut Chart</mat-option>
<mat-label>Chart Type</mat-label> <mat-option value="area">Area Chart</mat-option>
<mat-select [(ngModel)]="currentConfig.chartType" name="chartType"> <mat-option value="scatter">Scatter Chart</mat-option>
<mat-option value="bar">Bar Chart</mat-option> <mat-option value="bubble">Bubble Chart</mat-option>
<mat-option value="line">Line Chart</mat-option> <mat-option value="gauge">Gauge Chart</mat-option>
<mat-option value="pie">Pie Chart</mat-option> <mat-option value="funnel">Funnel Chart</mat-option>
<mat-option value="area">Area Chart</mat-option> <mat-option value="treemap">Treemap</mat-option>
<mat-option value="doughnut">Doughnut Chart</mat-option> <mat-option value="waterfall">Waterfall Chart</mat-option>
<mat-option value="scatter">Scatter Chart</mat-option> </mat-select>
<mat-option value="bubble">Bubble Chart</mat-option> <mat-hint>Type of chart to display</mat-hint>
<mat-option value="funnel">Funnel Chart</mat-option> </mat-form-field>
<mat-option value="waterfall">Waterfall Chart</mat-option>
<mat-option value="combo">Combo Chart</mat-option> <mat-form-field appearance="fill">
<mat-option value="gauge">Gauge Chart</mat-option> <mat-label>Data Source</mat-label>
<mat-option value="treemap">Treemap</mat-option> <mat-select [(ngModel)]="currentConfig.dataSource" name="dataSource">
</mat-select> <mat-option value="static">Static Data</mat-option>
<mat-hint>Type of chart to display</mat-hint> <mat-option value="api">API Endpoint</mat-option>
</mat-form-field> <mat-option value="dataset">Dataset</mat-option>
</div> </mat-select>
<mat-hint>Source of the data</mat-hint>
<!-- Size Configuration --> </mat-form-field>
<div class="config-section">
<h3 class="text-blue-600">Size Configuration</h3>
<div class="size-config">
<div
*ngFor="let option of sizeOptions"
class="size-option"
[class.selected]="currentConfig.sizeOption === option.id"
(click)="setSizeOption(option.id)">
<h4>{{ option.label }}</h4>
<p>{{ option.description }}</p>
</div> </div>
</div>
<div *ngIf="currentConfig.sizeOption === 'custom'" class="grid grid-cols-2 gap-4 mt-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Width</mat-label> <mat-label>X-Axis Field</mat-label>
<input matInput [(ngModel)]="currentConfig.width" name="width" placeholder="e.g., 100%, 600px"> <mat-select [(ngModel)]="currentConfig.xAxisField" name="xAxisField">
<mat-hint>Chart width</mat-hint> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-form-field> </mat-select>
<mat-form-field appearance="fill"> <mat-hint>Field for X-axis</mat-hint>
<mat-label>Height</mat-label> </mat-form-field>
<input matInput [(ngModel)]="currentConfig.height" name="height" placeholder="e.g., 100%, 400px">
<mat-hint>Chart height</mat-hint> <mat-form-field appearance="fill">
<mat-label>Y-Axis Field</mat-label>
<mat-select [(ngModel)]="currentConfig.yAxisField" name="yAxisField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field for Y-axis</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Value Field</mat-label>
<mat-select [(ngModel)]="currentConfig.valueField" name="valueField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field containing the values</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Label Field</mat-label>
<mat-select [(ngModel)]="currentConfig.labelField" name="labelField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field containing the labels</mat-hint>
</mat-form-field>
</div>
<mat-form-field *ngIf="currentConfig.dataSource === 'api'" appearance="fill" class="w-full">
<mat-label>API Endpoint</mat-label>
<input matInput [(ngModel)]="currentConfig.apiEndpoint" name="apiEndpoint" placeholder="https://api.example.com/chart-data">
<mat-hint>API endpoint URL</mat-hint>
</mat-form-field> </mat-form-field>
</div> </div>
</div> </mat-tab>
</div>
<!-- Chart Options Tab -->
<!-- Columns Tab --> <mat-tab label="Chart Options">
<div class="config-section"> <div class="config-section">
<h3 class="text-blue-600">Data Series Configuration</h3> <h3 class="section-title text-green-600">Chart Options</h3>
<div class="flex items-center justify-between mb-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<h4>Y-Axis Fields</h4> <mat-form-field appearance="fill">
<button mat-raised-button color="primary" (click)="addYField()"> <mat-label>Show Legend</mat-label>
<mat-icon>add</mat-icon> <mat-select [(ngModel)]="currentConfig.showLegend" name="showLegend">
Add Series <mat-option value="true">Yes</mat-option>
</button> <mat-option value="false">No</mat-option>
</div> </mat-select>
<mat-hint>Display chart legend</mat-hint>
<div *ngFor="let field of currentConfig.yFields; let i = index" class="column-config-item p-4 mb-4"> </mat-form-field>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Field Name</mat-label> <mat-label>Show Grid Lines</mat-label>
<mat-select [(ngModel)]="field.field" name="yField{{i}}"> <mat-select [(ngModel)]="currentConfig.showGridLines" name="showGridLines">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> <mat-option value="true">Yes</mat-option>
</mat-select> <mat-option value="false">No</mat-option>
</mat-form-field> </mat-select>
<mat-hint>Display grid lines</mat-hint>
</mat-form-field>
</div>
<mat-form-field appearance="fill"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-label>Series Name</mat-label> <mat-form-field appearance="fill">
<input matInput [(ngModel)]="field.name" name="yFieldName{{i}}" placeholder="Series display name"> <mat-label>Show Data Labels</mat-label>
</mat-form-field> <mat-select [(ngModel)]="currentConfig.showDataLabels" name="showDataLabels">
<mat-option value="true">Yes</mat-option>
<mat-option value="false">No</mat-option>
</mat-select>
<mat-hint>Display data labels on chart</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Show Tooltips</mat-label>
<mat-select [(ngModel)]="currentConfig.showTooltips" name="showTooltips">
<mat-option value="true">Yes</mat-option>
<mat-option value="false">No</mat-option>
</mat-select>
<mat-hint>Display tooltips on hover</mat-hint>
</mat-form-field>
</div>
<mat-form-field appearance="fill"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-label>Chart Type</mat-label> <mat-form-field appearance="fill">
<mat-select [(ngModel)]="field.type" name="yFieldType{{i}}"> <mat-label>Animation Duration (ms)</mat-label>
<mat-option value="bar">Bar</mat-option> <input matInput type="number" [(ngModel)]="currentConfig.animationDuration" name="animationDuration" min="0" max="2000">
<mat-option value="line">Line</mat-option> <mat-hint>Duration of chart animation</mat-hint>
<mat-option value="area">Area</mat-option> </mat-form-field>
<mat-option value="scatter">Scatter</mat-option>
</mat-select> <mat-form-field appearance="fill">
</mat-form-field> <mat-label>Chart Height (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.chartHeight" name="chartHeight" min="200" max="800">
<mat-hint>Height of the chart</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.enableZoom" name="enableZoom">
Enable Zoom
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enablePan" name="enablePan">
Enable Pan
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableExport" name="enableExport">
Enable Export
</mat-checkbox>
</div>
</div> </div>
</mat-tab>
<!-- Colors Tab -->
<mat-tab label="Colors">
<div class="config-section">
<h3 class="section-title text-purple-600">Color Configuration</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Background Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.backgroundColor" name="backgroundColor">
<mat-hint>Chart background color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Text Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.textColor" name="textColor">
<mat-hint>Text color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Color</mat-label> <mat-label>Grid Color</mat-label>
<input matInput type="color" [(ngModel)]="field.color" name="yFieldColor{{i}}"> <input matInput type="color" [(ngModel)]="currentConfig.gridColor" name="gridColor">
</mat-form-field> <mat-hint>Grid lines color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.borderColor" name="borderColor">
<mat-hint>Chart border color</mat-hint>
</mat-form-field>
</div>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill" class="w-full">
<mat-label>Y-Axis</mat-label> <mat-label>Color Palette</mat-label>
<mat-select [(ngModel)]="field.yAxis" name="yFieldAxis{{i}}"> <mat-select [(ngModel)]="currentConfig.colorPalette" name="colorPalette">
<mat-option value="primary">Primary</mat-option> <mat-option value="default">Default</mat-option>
<mat-option value="secondary">Secondary</mat-option> <mat-option value="rainbow">Rainbow</mat-option>
<mat-option value="pastel">Pastel</mat-option>
<mat-option value="monochrome">Monochrome</mat-option>
<mat-option value="custom">Custom</mat-option>
</mat-select> </mat-select>
<mat-hint>Color palette for chart series</mat-hint>
</mat-form-field>
<mat-form-field *ngIf="currentConfig.colorPalette === 'custom'" appearance="fill" class="w-full">
<mat-label>Custom Colors (comma-separated)</mat-label>
<input matInput [(ngModel)]="currentConfig.customColors" name="customColors" placeholder="#FF5733, #33FF57, #3357FF">
<mat-hint>Enter custom colors separated by commas</mat-hint>
</mat-form-field> </mat-form-field>
</div> </div>
</mat-tab>
<!-- Layout Tab -->
<mat-tab label="Layout">
<div class="config-section">
<h3 class="section-title text-teal-600">Layout Settings</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Width (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.width" name="width" min="200" max="1200">
<mat-hint>Widget width</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Height (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.height" name="height" min="200" max="800">
<mat-hint>Widget height</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Padding (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.padding" name="padding" min="0" max="50">
<mat-hint>Internal spacing</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Radius (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.borderRadius" name="borderRadius" min="0" max="20">
<mat-hint>Corner roundness</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center justify-between mt-4">
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="field.visible" name="yFieldVisible{{i}}"> <mat-checkbox [(ngModel)]="currentConfig.responsive" name="responsive">
Visible Responsive Layout
</mat-checkbox> </mat-checkbox>
<mat-checkbox [(ngModel)]="field.showDataLabels" name="yFieldDataLabels{{i}}"> <mat-checkbox [(ngModel)]="currentConfig.showTitle" name="showTitle">
Show Data Labels Show Title
</mat-checkbox> </mat-checkbox>
</div> </div>
<button mat-icon-button color="warn" (click)="removeYField(i)">
<mat-icon>delete</mat-icon>
</button>
</div> </div>
</div> </mat-tab>
</div>
<!-- Data Tab -->
<!-- Rows Tab --> <mat-tab label="Data">
<div class="config-section"> <div class="config-section">
<h3 class="text-blue-600">Data Configuration</h3> <h3 class="section-title text-red-600">Data Settings</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Data Limit</mat-label> <mat-label>Refresh Interval (ms)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.dataLimit" name="dataLimit" min="10" max="1000"> <input matInput type="number" [(ngModel)]="currentConfig.refreshInterval" name="refreshInterval" min="0" step="1000">
<mat-hint>Maximum number of data points</mat-hint> <mat-hint>0 = No auto-refresh</mat-hint>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill"> <div class="flex items-center">
<mat-label>Data Sort Field</mat-label> <mat-checkbox [(ngModel)]="currentConfig.cacheEnabled" name="cacheEnabled">
<mat-select [(ngModel)]="currentConfig.dataSortField" name="dataSortField"> Enable Data Caching
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> </mat-checkbox>
</mat-select> </div>
<mat-hint>Field to sort data by</mat-hint> </div>
</mat-form-field>
</div> <mat-form-field *ngIf="currentConfig.cacheEnabled" appearance="fill" class="w-full">
<mat-label>Cache Duration (seconds)</mat-label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <input matInput type="number" [(ngModel)]="currentConfig.cacheDuration" name="cacheDuration" min="1" max="3600">
<mat-form-field appearance="fill"> <mat-hint>How long to cache data</mat-hint>
<mat-label>Sort Order</mat-label> </mat-form-field>
<mat-select [(ngModel)]="currentConfig.dataSortOrder" name="dataSortOrder">
<mat-option value="asc">Ascending</mat-option> <mat-form-field appearance="fill" class="w-full">
<mat-option value="desc">Descending</mat-option> <mat-label>Data Transform Function</mat-label>
</mat-select> <textarea matInput [(ngModel)]="currentConfig.dataTransform" name="dataTransform" rows="3"
<mat-hint>Sort order for data</mat-hint> placeholder="data => data.map(item => ({ ...item, formattedValue: formatCurrency(item.value) }))"></textarea>
</mat-form-field> <mat-hint>JavaScript function to transform data</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill"> </div>
<mat-label>Group By Field</mat-label> </mat-tab>
<mat-select [(ngModel)]="currentConfig.groupByField" name="groupByField"> </mat-tab-group>
<mat-option value="">None</mat-option> </div>
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field to group data by</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.showDataTable" name="showDataTable">
Show Data Table
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableDataZoom" name="enableDataZoom">
Enable Data Zoom
</mat-checkbox>
</div>
</div>
<!-- Style Tab -->
<div class="config-section">
<h3 class="text-blue-600">Style Configuration</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Background Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.backgroundColor" name="backgroundColor">
<mat-hint>Chart background color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Text Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.textColor" name="textColor">
<mat-hint>Text color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Grid Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.gridColor" name="gridColor">
<mat-hint>Grid line color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.borderColor" name="borderColor">
<mat-hint>Chart border color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Font Size (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.fontSize" name="fontSize" min="8" max="24">
<mat-hint>Base font size</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Legend Font Size (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.legendFontSize" name="legendFontSize" min="8" max="20">
<mat-hint>Legend font size</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Border Radius (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.borderRadius" name="borderRadius" min="0" max="20">
<mat-hint>Corner roundness</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Shadow</mat-label>
<mat-select [(ngModel)]="currentConfig.shadow" name="shadow">
<mat-option value="none">None</mat-option>
<mat-option value="small">Small</mat-option>
<mat-option value="medium">Medium</mat-option>
<mat-option value="large">Large</mat-option>
</mat-select>
<mat-hint>Drop shadow effect</mat-hint>
</mat-form-field>
</div>
</div>
<!-- Filter Tab -->
<div class="config-section">
<h3 class="text-blue-600">Filter Configuration</h3>
<div class="flex items-center mb-4">
<mat-checkbox [(ngModel)]="currentConfig.enableFilter" name="enableFilter">
Enable Filtering
</mat-checkbox>
</div>
<div *ngIf="currentConfig.enableFilter" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Filter Field</mat-label>
<mat-select [(ngModel)]="currentConfig.filterField" name="filterField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field to filter by</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Filter Operator</mat-label>
<mat-select [(ngModel)]="currentConfig.filterOperator" name="filterOperator">
<mat-option value="equals">Equals</mat-option>
<mat-option value="not_equals">Not Equals</mat-option>
<mat-option value="greater_than">Greater Than</mat-option>
<mat-option value="less_than">Less Than</mat-option>
<mat-option value="contains">Contains</mat-option>
<mat-option value="starts_with">Starts With</mat-option>
<mat-option value="ends_with">Ends With</mat-option>
</mat-select>
<mat-hint>Filter comparison operator</mat-hint>
</mat-form-field>
</div>
<div *ngIf="currentConfig.enableFilter" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Filter Value</mat-label>
<input matInput [(ngModel)]="currentConfig.filterValue" name="filterValue" placeholder="Enter filter value">
<mat-hint>Value to filter by</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Filter Label</mat-label>
<input matInput [(ngModel)]="currentConfig.filterLabel" name="filterLabel" placeholder="Filter label">
<mat-hint>Label for the filter</mat-hint>
</mat-form-field>
</div>
</div>
<!-- Aggregate Tab -->
<div class="config-section">
<h3 class="text-blue-600">Aggregate Configuration</h3>
<div class="flex items-center mb-4">
<mat-checkbox [(ngModel)]="currentConfig.showAggregate" name="showAggregate">
Show Aggregate Information
</mat-checkbox>
</div>
<div *ngIf="currentConfig.showAggregate" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Aggregate Type</mat-label>
<mat-select [(ngModel)]="currentConfig.aggregateType" name="aggregateType">
<mat-option value="sum">Sum</mat-option>
<mat-option value="count">Count</mat-option>
<mat-option value="average">Average</mat-option>
<mat-option value="min">Min</mat-option>
<mat-option value="max">Max</mat-option>
</mat-select>
<mat-hint>Type of aggregation</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Aggregate Field</mat-label>
<mat-select [(ngModel)]="currentConfig.aggregateField" name="aggregateField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Field to aggregate</mat-hint>
</mat-form-field>
</div>
<div *ngIf="currentConfig.showAggregate" class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Aggregate Format</mat-label>
<mat-select [(ngModel)]="currentConfig.aggregateFormat" name="aggregateFormat">
<mat-option value="none">None</mat-option>
<mat-option value="number">Number</mat-option>
<mat-option value="currency">Currency</mat-option>
<mat-option value="percentage">Percentage</mat-option>
</mat-select>
<mat-hint>Format for aggregate value</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Aggregate Position</mat-label>
<mat-select [(ngModel)]="currentConfig.aggregatePosition" name="aggregatePosition">
<mat-option value="top">Top</mat-option>
<mat-option value="bottom">Bottom</mat-option>
<mat-option value="left">Left</mat-option>
<mat-option value="right">Right</mat-option>
</mat-select>
<mat-hint>Position of aggregate info</mat-hint>
</mat-form-field>
</div>
</div>
</app-base-config>
`, `,
styles: [` styles: [`
.config-section { .config-container {
margin-bottom: 24px; padding: 20px;
background: #f8fafc;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
} }
.column-config-item { .config-section {
background: #f9fafb; margin-bottom: 32px;
border: 1px solid #e5e7eb; padding: 24px;
background: white;
border-radius: 8px; border-radius: 8px;
border: 1px solid #e2e8f0;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
}
.section-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 8px;
border-bottom: 2px solid #e2e8f0;
}
.config-tabs {
margin-top: 0;
}
.config-tabs .mat-tab-body-content {
padding: 20px 0;
}
.config-tabs .mat-tab-header {
background: white;
border-radius: 8px 8px 0 0;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
}
.config-tabs .mat-tab-label {
min-width: 120px;
font-weight: 500;
}
.config-tabs .mat-tab-label-active {
color: #3b82f6;
}
.mat-form-field {
margin-bottom: 8px;
}
.grid {
display: grid;
gap: 16px;
} }
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px) {
.md\\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
.w-full {
width: 100%;
}
.flex {
display: flex;
}
.items-center {
align-items: center;
}
.space-x-4 > * + * {
margin-left: 16px;
}
.text-blue-600 { color: #2563eb; }
.text-green-600 { color: #16a34a; }
.text-purple-600 { color: #9333ea; }
.text-teal-600 { color: #0d9488; }
.text-red-600 { color: #dc2626; }
`] `]
}) })
export class ChartConfigComponent extends BaseConfigComponent implements OnInit { export class ChartConfigComponent extends BaseConfigComponent implements OnInit {
override ngOnInit() { override ngOnInit() {
this.initializeDefaultConfig(); this.initializeDefaultConfig();
this.initializeYFields();
this.initializeColorDefaults(); this.initializeColorDefaults();
} }
override initializeDefaultConfig() {
if (!this.currentConfig.title) this.currentConfig.title = 'Chart Widget';
if (!this.currentConfig.chartType) this.currentConfig.chartType = 'bar';
if (!this.currentConfig.dataSource) this.currentConfig.dataSource = 'static';
if (!this.currentConfig.xAxisField) this.currentConfig.xAxisField = '';
if (!this.currentConfig.yAxisField) this.currentConfig.yAxisField = '';
if (!this.currentConfig.valueField) this.currentConfig.valueField = '';
if (!this.currentConfig.labelField) this.currentConfig.labelField = '';
if (!this.currentConfig.apiEndpoint) this.currentConfig.apiEndpoint = '';
if (!this.currentConfig.showLegend) this.currentConfig.showLegend = 'true';
if (!this.currentConfig.showGridLines) this.currentConfig.showGridLines = 'true';
if (!this.currentConfig.showDataLabels) this.currentConfig.showDataLabels = 'false';
if (!this.currentConfig.showTooltips) this.currentConfig.showTooltips = 'true';
if (!this.currentConfig.animationDuration) this.currentConfig.animationDuration = 1000;
if (!this.currentConfig.chartHeight) this.currentConfig.chartHeight = 400;
if (!this.currentConfig.enableZoom) this.currentConfig.enableZoom = false;
if (!this.currentConfig.enablePan) this.currentConfig.enablePan = false;
if (!this.currentConfig.enableExport) this.currentConfig.enableExport = false;
if (!this.currentConfig.width) this.currentConfig.width = 600;
if (!this.currentConfig.height) this.currentConfig.height = 400;
if (!this.currentConfig.padding) this.currentConfig.padding = 16;
if (!this.currentConfig.borderRadius) this.currentConfig.borderRadius = 8;
if (!this.currentConfig.responsive) this.currentConfig.responsive = true;
if (!this.currentConfig.showTitle) this.currentConfig.showTitle = true;
if (!this.currentConfig.refreshInterval) this.currentConfig.refreshInterval = 0;
if (!this.currentConfig.cacheEnabled) this.currentConfig.cacheEnabled = false;
if (!this.currentConfig.cacheDuration) this.currentConfig.cacheDuration = 300;
if (!this.currentConfig.dataTransform) this.currentConfig.dataTransform = '';
}
private initializeColorDefaults() { private initializeColorDefaults() {
if (!this.currentConfig.backgroundColor) this.currentConfig.backgroundColor = '#FFFFFF'; if (!this.currentConfig.backgroundColor) this.currentConfig.backgroundColor = '#FFFFFF';
if (!this.currentConfig.textColor) this.currentConfig.textColor = '#374151'; if (!this.currentConfig.textColor) this.currentConfig.textColor = '#000000';
if (!this.currentConfig.gridColor) this.currentConfig.gridColor = '#E5E7EB'; if (!this.currentConfig.gridColor) this.currentConfig.gridColor = '#E5E7EB';
if (!this.currentConfig.borderColor) this.currentConfig.borderColor = '#E5E7EB'; if (!this.currentConfig.borderColor) this.currentConfig.borderColor = '#D1D5DB';
} if (!this.currentConfig.colorPalette) this.currentConfig.colorPalette = 'default';
if (!this.currentConfig.customColors) this.currentConfig.customColors = '';
private initializeYFields() {
if (!this.currentConfig.yFields) {
this.currentConfig.yFields = [];
}
}
addYField() {
this.addArrayItem('yFields', {
field: '',
name: '',
type: 'bar',
color: '#2563eb',
yAxis: 'primary',
visible: true,
showDataLabels: false
});
}
removeYField(index: number) {
this.removeArrayItem('yFields', index);
} }
} }
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTabsModule } from '@angular/material/tabs';
import { BaseConfigComponent } from '../../../widget-config/base-config/base-config.component';
@Component({
selector: 'app-table-config',
standalone: true,
imports: [
CommonModule,
FormsModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatCheckboxModule,
MatButtonModule,
MatIconModule,
MatTabsModule
],
template: `
<div class="config-container">
<mat-tab-group class="config-tabs" dynamicHeight>
<!-- Basic Configuration Tab -->
<mat-tab label="Basic">
<div class="config-section">
<h3 class="section-title text-blue-600">Basic Configuration</h3>
<mat-form-field appearance="fill" class="w-full">
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title" aria-label="Table title">
<mat-hint>Table title displayed in header</mat-hint>
</mat-form-field>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Data Source</mat-label>
<mat-select [(ngModel)]="currentConfig.dataSource" name="dataSource">
<mat-option value="static">Static Data</mat-option>
<mat-option value="api">API Endpoint</mat-option>
<mat-option value="dataset">Dataset</mat-option>
</mat-select>
<mat-hint>Source of the data</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Table Type</mat-label>
<mat-select [(ngModel)]="currentConfig.tableType" name="tableType">
<mat-option value="simple">Simple Table</mat-option>
<mat-option value="data-grid">Data Grid</mat-option>
<mat-option value="pivot">Pivot Table</mat-option>
</mat-select>
<mat-hint>Type of table to display</mat-hint>
</mat-form-field>
</div>
<mat-form-field *ngIf="currentConfig.dataSource === 'api'" appearance="fill" class="w-full">
<mat-label>API Endpoint</mat-label>
<input matInput [(ngModel)]="currentConfig.apiEndpoint" name="apiEndpoint" placeholder="https://api.example.com/table-data">
<mat-hint>API endpoint URL</mat-hint>
</mat-form-field>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Page Size</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.pageSize" name="pageSize" min="5" max="100">
<mat-hint>Number of rows per page</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Max Height (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.maxHeight" name="maxHeight" min="200" max="800">
<mat-hint>Maximum height of the table</mat-hint>
</mat-form-field>
</div>
</div>
</mat-tab>
<!-- Columns Tab -->
<mat-tab label="Columns">
<div class="config-section">
<h3 class="section-title text-green-600">Column Configuration</h3>
<div class="flex items-center mb-4">
<mat-checkbox [(ngModel)]="currentConfig.showColumnSelector" name="showColumnSelector">
Show Column Selector
</mat-checkbox>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Visible Columns</mat-label>
<mat-select [(ngModel)]="currentConfig.visibleColumns" name="visibleColumns" multiple>
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Columns to display in the table</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Sortable Columns</mat-label>
<mat-select [(ngModel)]="currentConfig.sortableColumns" name="sortableColumns" multiple>
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Columns that can be sorted</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Filterable Columns</mat-label>
<mat-select [(ngModel)]="currentConfig.filterableColumns" name="filterableColumns" multiple>
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Columns that can be filtered</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Editable Columns</mat-label>
<mat-select [(ngModel)]="currentConfig.editableColumns" name="editableColumns" multiple>
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select>
<mat-hint>Columns that can be edited</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.showRowNumbers" name="showRowNumbers">
Show Row Numbers
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.showCheckboxes" name="showCheckboxes">
Show Checkboxes
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.allowColumnResize" name="allowColumnResize">
Allow Column Resize
</mat-checkbox>
</div>
</div>
</mat-tab>
<!-- Styling Tab -->
<mat-tab label="Styling">
<div class="config-section">
<h3 class="section-title text-purple-600">Table Styling</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Header Background Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.headerBackgroundColor" name="headerBackgroundColor">
<mat-hint>Header background color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Header Text Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.headerTextColor" name="headerTextColor">
<mat-hint>Header text color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Row Background Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.rowBackgroundColor" name="rowBackgroundColor">
<mat-hint>Row background color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Row Text Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.rowTextColor" name="rowTextColor">
<mat-hint>Row text color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Border Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.borderColor" name="borderColor">
<mat-hint>Table border color</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Hover Color</mat-label>
<input matInput type="color" [(ngModel)]="currentConfig.hoverColor" name="hoverColor">
<mat-hint>Row hover color</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<mat-form-field appearance="fill">
<mat-label>Font Size (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.fontSize" name="fontSize" min="10" max="20">
<mat-hint>Table font size</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Row Height (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.rowHeight" name="rowHeight" min="30" max="80">
<mat-hint>Height of each row</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Width (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.borderWidth" name="borderWidth" min="0" max="5">
<mat-hint>Table border width</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.stripedRows" name="stripedRows">
Striped Rows
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.bordered" name="bordered">
Bordered Table
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.hoverable" name="hoverable">
Hoverable Rows
</mat-checkbox>
</div>
</div>
</mat-tab>
<!-- Features Tab -->
<mat-tab label="Features">
<div class="config-section">
<h3 class="section-title text-orange-600">Table Features</h3>
<div class="flex items-center space-x-4 mb-4">
<mat-checkbox [(ngModel)]="currentConfig.enablePagination" name="enablePagination">
Enable Pagination
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableSorting" name="enableSorting">
Enable Sorting
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableFiltering" name="enableFiltering">
Enable Filtering
</mat-checkbox>
</div>
<div class="flex items-center space-x-4 mb-4">
<mat-checkbox [(ngModel)]="currentConfig.enableSearch" name="enableSearch">
Enable Search
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableExport" name="enableExport">
Enable Export
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableSelection" name="enableSelection">
Enable Selection
</mat-checkbox>
</div>
<div class="flex items-center space-x-4 mb-4">
<mat-checkbox [(ngModel)]="currentConfig.enableInlineEdit" name="enableInlineEdit">
Enable Inline Edit
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableColumnReorder" name="enableColumnReorder">
Enable Column Reorder
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.enableVirtualScroll" name="enableVirtualScroll">
Enable Virtual Scroll
</mat-checkbox>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Search Placeholder</mat-label>
<input matInput [(ngModel)]="currentConfig.searchPlaceholder" name="searchPlaceholder" placeholder="Search...">
<mat-hint>Search input placeholder</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>No Data Message</mat-label>
<input matInput [(ngModel)]="currentConfig.noDataMessage" name="noDataMessage" placeholder="No data available">
<mat-hint>Message when no data is available</mat-hint>
</mat-form-field>
</div>
</div>
</mat-tab>
<!-- Layout Tab -->
<mat-tab label="Layout">
<div class="config-section">
<h3 class="section-title text-teal-600">Layout Settings</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Width (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.width" name="width" min="400" max="1200">
<mat-hint>Widget width</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Height (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.height" name="height" min="300" max="800">
<mat-hint>Widget height</mat-hint>
</mat-form-field>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<mat-form-field appearance="fill">
<mat-label>Padding (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.padding" name="padding" min="0" max="50">
<mat-hint>Internal spacing</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Border Radius (px)</mat-label>
<input matInput type="number" [(ngModel)]="currentConfig.borderRadius" name="borderRadius" min="0" max="20">
<mat-hint>Corner roundness</mat-hint>
</mat-form-field>
</div>
<div class="flex items-center space-x-4">
<mat-checkbox [(ngModel)]="currentConfig.responsive" name="responsive">
Responsive Layout
</mat-checkbox>
<mat-checkbox [(ngModel)]="currentConfig.fullWidth" name="fullWidth">
Full Width
</mat-checkbox>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
`,
styles: [`
.config-container {
padding: 20px;
background: #f8fafc;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.config-section {
margin-bottom: 32px;
padding: 24px;
background: white;
border-radius: 8px;
border: 1px solid #e2e8f0;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
}
.section-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 8px;
border-bottom: 2px solid #e2e8f0;
}
.config-tabs {
margin-top: 0;
}
.config-tabs .mat-tab-body-content {
padding: 20px 0;
}
.config-tabs .mat-tab-header {
background: white;
border-radius: 8px 8px 0 0;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
}
.config-tabs .mat-tab-label {
min-width: 120px;
font-weight: 500;
}
.config-tabs .mat-tab-label-active {
color: #3b82f6;
}
.mat-form-field {
margin-bottom: 8px;
}
.grid {
display: grid;
gap: 16px;
}
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (min-width: 768px) {
.md\\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.md\\:grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
.w-full {
width: 100%;
}
.flex {
display: flex;
}
.items-center {
align-items: center;
}
.space-x-4 > * + * {
margin-left: 16px;
}
.mb-4 {
margin-bottom: 16px;
}
.text-blue-600 { color: #2563eb; }
.text-green-600 { color: #16a34a; }
.text-purple-600 { color: #9333ea; }
.text-orange-600 { color: #ea580c; }
.text-teal-600 { color: #0d9488; }
`]
})
export class TableConfigComponent extends BaseConfigComponent implements OnInit {
override ngOnInit() {
this.initializeDefaultConfig();
this.initializeColorDefaults();
}
override initializeDefaultConfig() {
if (!this.currentConfig.title) this.currentConfig.title = 'Table Widget';
if (!this.currentConfig.dataSource) this.currentConfig.dataSource = 'static';
if (!this.currentConfig.tableType) this.currentConfig.tableType = 'simple';
if (!this.currentConfig.apiEndpoint) this.currentConfig.apiEndpoint = '';
if (!this.currentConfig.pageSize) this.currentConfig.pageSize = 10;
if (!this.currentConfig.maxHeight) this.currentConfig.maxHeight = 400;
if (!this.currentConfig.visibleColumns) this.currentConfig.visibleColumns = [];
if (!this.currentConfig.sortableColumns) this.currentConfig.sortableColumns = [];
if (!this.currentConfig.filterableColumns) this.currentConfig.filterableColumns = [];
if (!this.currentConfig.editableColumns) this.currentConfig.editableColumns = [];
if (!this.currentConfig.showColumnSelector) this.currentConfig.showColumnSelector = false;
if (!this.currentConfig.showRowNumbers) this.currentConfig.showRowNumbers = false;
if (!this.currentConfig.showCheckboxes) this.currentConfig.showCheckboxes = false;
if (!this.currentConfig.allowColumnResize) this.currentConfig.allowColumnResize = true;
if (!this.currentConfig.enablePagination) this.currentConfig.enablePagination = true;
if (!this.currentConfig.enableSorting) this.currentConfig.enableSorting = true;
if (!this.currentConfig.enableFiltering) this.currentConfig.enableFiltering = false;
if (!this.currentConfig.enableSearch) this.currentConfig.enableSearch = false;
if (!this.currentConfig.enableExport) this.currentConfig.enableExport = false;
if (!this.currentConfig.enableSelection) this.currentConfig.enableSelection = false;
if (!this.currentConfig.enableInlineEdit) this.currentConfig.enableInlineEdit = false;
if (!this.currentConfig.enableColumnReorder) this.currentConfig.enableColumnReorder = false;
if (!this.currentConfig.enableVirtualScroll) this.currentConfig.enableVirtualScroll = false;
if (!this.currentConfig.searchPlaceholder) this.currentConfig.searchPlaceholder = 'Search...';
if (!this.currentConfig.noDataMessage) this.currentConfig.noDataMessage = 'No data available';
if (!this.currentConfig.width) this.currentConfig.width = 800;
if (!this.currentConfig.height) this.currentConfig.height = 400;
if (!this.currentConfig.padding) this.currentConfig.padding = 16;
if (!this.currentConfig.borderRadius) this.currentConfig.borderRadius = 8;
if (!this.currentConfig.responsive) this.currentConfig.responsive = true;
if (!this.currentConfig.fullWidth) this.currentConfig.fullWidth = false;
}
private initializeColorDefaults() {
if (!this.currentConfig.headerBackgroundColor) this.currentConfig.headerBackgroundColor = '#F3F4F6';
if (!this.currentConfig.headerTextColor) this.currentConfig.headerTextColor = '#374151';
if (!this.currentConfig.rowBackgroundColor) this.currentConfig.rowBackgroundColor = '#FFFFFF';
if (!this.currentConfig.rowTextColor) this.currentConfig.rowTextColor = '#374151';
if (!this.currentConfig.borderColor) this.currentConfig.borderColor = '#E5E7EB';
if (!this.currentConfig.hoverColor) this.currentConfig.hoverColor = '#F9FAFB';
if (!this.currentConfig.fontSize) this.currentConfig.fontSize = 14;
if (!this.currentConfig.rowHeight) this.currentConfig.rowHeight = 40;
if (!this.currentConfig.borderWidth) this.currentConfig.borderWidth = 1;
if (!this.currentConfig.stripedRows) this.currentConfig.stripedRows = false;
if (!this.currentConfig.bordered) this.currentConfig.bordered = true;
if (!this.currentConfig.hoverable) this.currentConfig.hoverable = true;
}
}
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