Commit ed89bf27 by sawit

แก้ไข widget

parent aac8ace4
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
border-radius: 0.75rem; border-radius: 0.75rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
border: 1px solid #e5e7eb; border: 1px solid #e5e7eb;
min-height: 600px; min-height: 1200px;
} }
/* Empty State */ /* Empty State */
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 600px; height: 1200px;
text-align: center; text-align: center;
color: #6b7280; color: #6b7280;
} }
...@@ -437,39 +437,39 @@ ...@@ -437,39 +437,39 @@
/* Ensure widgets don't exceed panel boundaries and fill full space */ /* Ensure widgets don't exceed panel boundaries and fill full space */
.e-panel .e-panel-container .content > * { .e-panel .e-panel-container .content > * {
max-width: 100% !important;
max-height: 100% !important;
width: 100% !important; width: 100% !important;
height: 100% !important; height: 100% !important;
overflow: hidden !important; max-width: 100% !important;
box-sizing: border-box !important; min-width: 0 !important;
flex: 1 !important;
display: flex !important;
flex-direction: column !important;
} }
/* Specific widget component styling */ /* Specific styling for Syncfusion Datagrid Widget */
.e-panel .e-panel-container .content > * { .e-panel .e-panel-container .content app-syncfusion-datagrid-widget {
width: 100% !important; width: 100% !important;
height: 100% !important; height: 100% !important;
flex: 1 !important;
display: flex !important; display: flex !important;
flex-direction: column !important; flex-direction: column !important;
min-height: 0 !important; margin: 0 !important;
} padding: 0 !important;
/* Ensure all child elements fill the space */
.e-panel .e-panel-container .content > * > * {
width: 100% !important;
height: 100% !important;
flex: 1 !important;
min-height: 0 !important;
} }
/* Force all nested elements to use full space */ /* Force all nested elements to use full space */
.e-panel .e-panel-container .content * { .e-panel .e-panel-container .content * {
box-sizing: border-box !important; box-sizing: border-box !important;
} }
/* Remove margin/padding from grid container and grid */
.e-panel .e-panel-container .content app-syncfusion-datagrid-widget .grid-container {
margin: 0 !important;
padding: 0 !important;
}
.e-panel .e-panel-container .content app-syncfusion-datagrid-widget .grid-container .ejs-grid {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
max-width: 100% !important;
}
} }
} }
......
...@@ -486,6 +486,12 @@ export class DashboardManagementComponent implements OnInit, OnDestroy { ...@@ -486,6 +486,12 @@ export class DashboardManagementComponent implements OnInit, OnDestroy {
originalWidget: widget originalWidget: widget
}; };
// Force SyncfusionDatagridWidgetComponent to use full width
if (widget.component === 'SyncfusionDatagridWidgetComponent') {
panel.sizeX = this.columns;
panel.maxSizeX = this.columns;
}
return panel; return panel;
}) })
......
...@@ -163,7 +163,7 @@ export class DashboardViewerComponent implements OnInit, OnDestroy { ...@@ -163,7 +163,7 @@ export class DashboardViewerComponent implements OnInit, OnDestroy {
return null; return null;
} }
return { const panel = {
id: `${(widget as any).instanceId}-${widget.y}-${widget.x}`, id: `${(widget as any).instanceId}-${widget.y}-${widget.x}`,
header: widget.thName, header: widget.thName,
sizeX: widget.cols || 4, // Default size if not specified sizeX: widget.cols || 4, // Default size if not specified
...@@ -177,6 +177,13 @@ export class DashboardViewerComponent implements OnInit, OnDestroy { ...@@ -177,6 +177,13 @@ export class DashboardViewerComponent implements OnInit, OnDestroy {
data: JSON.stringify(dataObject) data: JSON.stringify(dataObject)
}, },
}; };
// Force SyncfusionDatagridWidgetComponent to use full width in viewer
if (widget.component === 'SyncfusionDatagridWidgetComponent') {
panel.sizeX = this.columns;
}
return panel;
}) })
.filter(panel => panel !== null) as DashboardPanel[]; .filter(panel => panel !== null) as DashboardPanel[];
} }
......
...@@ -609,6 +609,10 @@ ...@@ -609,6 +609,10 @@
<div *ngIf="widgetType === 'PieChartWidgetComponent' || widgetType === 'BarChartWidgetComponent' || widgetType === 'AreaChartWidgetComponent' || widgetType === 'DoughnutChartWidgetComponent' || widgetType === 'FunnelChartWidgetComponent'"> <div *ngIf="widgetType === 'PieChartWidgetComponent' || widgetType === 'BarChartWidgetComponent' || widgetType === 'AreaChartWidgetComponent' || widgetType === 'DoughnutChartWidgetComponent' || widgetType === 'FunnelChartWidgetComponent'">
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title">
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>X-Axis Field</mat-label> <mat-label>X-Axis Field</mat-label>
<mat-select [(ngModel)]="currentConfig.xField" name="xField"> <mat-select [(ngModel)]="currentConfig.xField" name="xField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
...@@ -620,18 +624,26 @@ ...@@ -620,18 +624,26 @@
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option> <mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill" *ngIf="widgetType === 'PieChartWidgetComponent' || widgetType === 'DoughnutChartWidgetComponent' || widgetType === 'FunnelChartWidgetComponent'">
<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-form-field>
<mat-form-field appearance="fill" *ngIf="widgetType === 'PieChartWidgetComponent' || widgetType === 'DoughnutChartWidgetComponent' || widgetType === 'FunnelChartWidgetComponent'">
<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-form-field>
<mat-form-field appearance="fill"> <mat-form-field appearance="fill">
<mat-label>Aggregation (for Pie/Doughnut/Funnel)</mat-label> <mat-label>Aggregation</mat-label>
<mat-select [(ngModel)]="currentConfig.aggregation" name="aggregation"> <mat-select [(ngModel)]="currentConfig.aggregation" name="aggregation">
<mat-option value="none">None</mat-option> <mat-option value="none">None</mat-option>
<mat-option value="count">Count</mat-option> <mat-option value="count">Count</mat-option>
<mat-option value="sum">Sum</mat-option> <mat-option value="sum">Sum</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="currentConfig.title" name="title">
</mat-form-field>
</div> </div>
<div *ngIf="widgetType === 'GaugeChartWidgetComponent'"> <div *ngIf="widgetType === 'GaugeChartWidgetComponent'">
......
...@@ -218,9 +218,11 @@ export class WidgetConfigComponent implements OnInit, AfterViewInit, OnDestroy { ...@@ -218,9 +218,11 @@ export class WidgetConfigComponent implements OnInit, AfterViewInit, OnDestroy {
if (!this.currentConfig.clickAction) this.currentConfig.clickAction = 'none'; if (!this.currentConfig.clickAction) this.currentConfig.clickAction = 'none';
// Layout configuration defaults // Layout configuration defaults
if (this.currentConfig.width === undefined) this.currentConfig.width = 600; if (this.currentConfig.width === undefined) this.currentConfig.width = 100;
if (this.currentConfig.height === undefined) this.currentConfig.height = 400; if (this.currentConfig.height === undefined) this.currentConfig.height = 400;
if (this.currentConfig.responsive === undefined) this.currentConfig.responsive = true; if (this.currentConfig.responsive === undefined) this.currentConfig.responsive = true;
if (this.currentConfig.widthUnit === undefined) this.currentConfig.widthUnit = '%';
if (this.currentConfig.fullWidth === undefined) this.currentConfig.fullWidth = true;
// Data configuration defaults // Data configuration defaults
if (!this.currentConfig.dataSource) this.currentConfig.dataSource = 'static'; if (!this.currentConfig.dataSource) this.currentConfig.dataSource = 'static';
...@@ -257,6 +259,7 @@ export class WidgetConfigComponent implements OnInit, AfterViewInit, OnDestroy { ...@@ -257,6 +259,7 @@ export class WidgetConfigComponent implements OnInit, AfterViewInit, OnDestroy {
if (!this.currentConfig.yAxisField) this.currentConfig.yAxisField = ''; if (!this.currentConfig.yAxisField) this.currentConfig.yAxisField = '';
if (!this.currentConfig.valueField) this.currentConfig.valueField = ''; if (!this.currentConfig.valueField) this.currentConfig.valueField = '';
if (!this.currentConfig.labelField) this.currentConfig.labelField = ''; if (!this.currentConfig.labelField) this.currentConfig.labelField = '';
if (!this.currentConfig.aggregation) this.currentConfig.aggregation = 'count';
if (!this.currentConfig.apiEndpoint) this.currentConfig.apiEndpoint = ''; if (!this.currentConfig.apiEndpoint) this.currentConfig.apiEndpoint = '';
// Chart options defaults // Chart options defaults
......
...@@ -31,18 +31,74 @@ export class BarChartWidgetComponent extends BaseWidgetComponent { ...@@ -31,18 +31,74 @@ export class BarChartWidgetComponent extends BaseWidgetComponent {
} }
onDataUpdate(data: any[]): void { onDataUpdate(data: any[]): void {
if (!data || data.length === 0) { // Check if data is an array
if (!Array.isArray(data) || data.length === 0) {
this.chartData = []; this.chartData = [];
return; return;
} }
const xField = this.configObj.xField || 'x'; // Support multiple field name formats from config
const yField = this.configObj.yField || 'y'; const xField = this.configObj.xField || this.configObj.xAxisField || 'x';
const yField = this.configObj.yField || this.configObj.yAxisField || 'y';
const valueField = this.configObj.valueField || this.configObj.aggregation ? this.configObj.valueField : 'y';
this.chartData = data.map(item => ({ console.log('BarChart onDataUpdate:', {
x: item[xField] || '', data: data.slice(0, 3),
y: item[yField] || 0 xField,
})); yField,
valueField,
aggregation: this.configObj.aggregation,
config: this.configObj
});
// Handle aggregation if needed
// Auto-detect if using ID field
let effectiveAggregation = this.configObj.aggregation;
if (this.configObj.aggregation === 'sum' && valueField) {
const fieldLower = valueField.toLowerCase();
if (fieldLower.includes('id') || (fieldLower.includes('employee') && fieldLower.includes('id'))) {
effectiveAggregation = 'count';
console.warn(`BarChart: Detected ID field "${valueField}", switching from sum to count`);
}
}
if (effectiveAggregation === 'sum' || effectiveAggregation === 'count') {
const groupedData = data.reduce((acc, item) => {
const key = item[xField] || '';
if (!acc[key]) {
acc[key] = 0;
}
if (effectiveAggregation === 'count') {
// Count: เพียงแค่นับจำนวน record
acc[key] += 1;
} else if (effectiveAggregation === 'sum' && valueField && item[valueField]) {
// Sum: ใช้ valueField ในการรวมค่า (เช่น salary, amount)
const value = typeof item[valueField] === 'number' ? item[valueField] : parseFloat(item[valueField]) || 0;
acc[key] += value;
} else {
// ถ้าไม่มี valueField หรือไม่ใช่ number ให้ใช้ count แทน
acc[key] += 1;
}
return acc;
}, {});
this.chartData = Object.keys(groupedData).map(key => ({
x: key,
y: groupedData[key]
}));
} else {
// No aggregation - map directly
const fieldToUse = valueField || yField;
this.chartData = data.map(item => ({
x: item[xField] || '',
y: item[fieldToUse] || 0
}));
}
console.log('BarChart chartData:', this.chartData.slice(0, 5));
} }
onReset(): void { onReset(): void {
......
...@@ -35,22 +35,34 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy { ...@@ -35,22 +35,34 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy {
next: (selectedDataset: SelectedDataset | null) => { next: (selectedDataset: SelectedDataset | null) => {
this.isLoading = true; this.isLoading = true;
this.hasError = false; this.hasError = false;
if (selectedDataset && selectedDataset.data) {
console.log('BaseWidget received dataset:', {
selectedDataset,
hasData: selectedDataset?.data?.length,
widgetConfig: this.configObj
});
if (selectedDataset && selectedDataset.data && Array.isArray(selectedDataset.data)) {
try { try {
this.originalData = selectedDataset.data; this.originalData = selectedDataset.data;
console.log('BaseWidget applying filters on data of length:', this.originalData.length);
this.applyFilters(); this.applyFilters();
console.log('BaseWidget filtered data length:', this.filteredData.length);
this.onDataUpdate(this.filteredData); this.onDataUpdate(this.filteredData);
this.isLoading = false; this.isLoading = false;
} catch (error) { } catch (error) {
console.error('BaseWidget error in data processing:', error);
this.handleError(error); this.handleError(error);
} }
} else { } else {
console.warn('BaseWidget no dataset available, showing loading state');
// If no dataset is selected, just keep showing the initial config with a loading state. // If no dataset is selected, just keep showing the initial config with a loading state.
// The initial state is set by applyInitialConfig(). // The initial state is set by applyInitialConfig().
this.isLoading = true; this.isLoading = true;
} }
}, },
error: (err) => { error: (err) => {
console.error('BaseWidget error in subscription:', err);
this.handleError(err); this.handleError(err);
} }
}); });
...@@ -105,7 +117,9 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy { ...@@ -105,7 +117,9 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy {
// Parse data string to array // Parse data string to array
try { try {
this.originalData = JSON.parse(this.data); const parsedData = JSON.parse(this.data);
// Ensure parsed data is an array, not an object
this.originalData = Array.isArray(parsedData) ? parsedData : [];
} catch (error) { } catch (error) {
console.warn('Failed to parse data JSON:', error); console.warn('Failed to parse data JSON:', error);
this.originalData = []; this.originalData = [];
......
...@@ -21,33 +21,102 @@ export class PieChartWidgetComponent extends BaseWidgetComponent { ...@@ -21,33 +21,102 @@ export class PieChartWidgetComponent extends BaseWidgetComponent {
applyInitialConfig(): void { applyInitialConfig(): void {
this.title = this.configObj.title || 'Pie Chart'; this.title = this.configObj.title || 'Pie Chart';
this.legendSettings = { visible: true }; this.legendSettings = {
visible: true,
position: 'Bottom',
textStyle: { size: '14px' },
height: '50px',
width: '100%',
alignment: 'Center'
};
this.chartData = []; this.chartData = [];
} }
onDataUpdate(data: any[]): void { onDataUpdate(data: any[]): void {
if (!data || data.length === 0) { // Check if data is an array
if (!Array.isArray(data) || data.length === 0) {
this.chartData = []; this.chartData = [];
return; return;
} }
const xField = this.configObj.xField || 'x'; // Support multiple field name formats from config
const yField = this.configObj.yField || 'y'; const labelField = this.configObj.labelField || this.configObj.xField || this.configObj.xAxisField || 'x';
const valueField = this.configObj.valueField || this.configObj.yField || this.configObj.yAxisField || 'y';
console.log('PieChart onDataUpdate:', {
title: this.title,
dataLength: data.length,
labelField,
valueField,
aggregation: this.configObj.aggregation,
sampleData: data.slice(0, 2)
});
let transformedData = data; let transformedData = data;
if (this.configObj.aggregation === 'count') { // Handle aggregation if needed
// Default to count if using any id field as value
let effectiveAggregation = this.configObj.aggregation;
if (this.configObj.aggregation === 'sum' && valueField) {
const fieldLower = valueField.toLowerCase();
if (fieldLower.includes('id') ||
fieldLower.includes('employee') && fieldLower.includes('id')) {
effectiveAggregation = 'count';
console.warn(`Detected ID field "${valueField}", switching from sum to count aggregation`);
}
}
console.log('Effective aggregation:', effectiveAggregation, 'original:', this.configObj.aggregation, 'labelField:', labelField, 'valueField:', valueField);
if (effectiveAggregation === 'count' || (effectiveAggregation === 'sum' && !valueField)) {
// Count: นับจำนวนรายการตาม labelField
// หรือ Sum ถ้าไม่ระบุ valueField (คล้าย count)
const counts = transformedData.reduce((acc, item) => { const counts = transformedData.reduce((acc, item) => {
const key = item[xField] || ''; const key = item[labelField] || '';
acc[key] = (acc[key] || 0) + 1; acc[key] = (acc[key] || 0) + 1;
return acc; return acc;
}, {}); }, {});
transformedData = Object.keys(counts).map(key => ({ x: key, y: counts[key] })); transformedData = Object.keys(counts).map(key => ({
x: key || '(Empty)',
y: counts[key],
text: `${key || '(Empty)'}: ${counts[key]}`
}));
console.log('PieChart using COUNT aggregation, result:', transformedData);
} else if (effectiveAggregation === 'sum' && valueField) {
// Sum: รวมค่า valueField ตาม labelField (เฉพาะกรณีที่ระบุ valueField)
// ตรวจสอบว่า valueField มีค่าที่สมเหตุสมผลหรือไม่
const groupedData = transformedData.reduce((acc, item) => {
const key = item[labelField] || '';
const value = item[valueField] || 0;
if (!acc[key]) {
acc[key] = 0;
}
// ถ้า value เป็น ID หรือ string ที่ไม่ได้เป็นตัวเลข ให้ไม่ sum
if (typeof value === 'string' && isNaN(Number(value))) {
// ถ้าเป็น ID หรือ string ธรรมดา ให้ข้าม
return acc;
}
acc[key] += typeof value === 'number' ? value : parseFloat(value) || 0;
return acc;
}, {});
transformedData = Object.keys(groupedData).map(key => ({
x: key || '(Empty)',
y: groupedData[key],
text: `${key || '(Empty)'}: ${groupedData[key]}`
}));
} else { } else {
// No aggregation: map directly
transformedData = transformedData.map(item => ({ transformedData = transformedData.map(item => ({
x: item[xField] || '', x: item[labelField] || '(Empty)',
y: item[yField] || 0 y: item[valueField] || 0,
text: `${item[labelField] || '(Empty)'}: ${item[valueField] || 0}`
})); }));
} }
console.log('PieChart chartData:', transformedData.slice(0, 10));
this.chartData = transformedData; this.chartData = transformedData;
} }
......
...@@ -325,17 +325,37 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent { ...@@ -325,17 +325,37 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
return; return;
} }
console.log('SimpleKpiWidget onDataUpdate:', {
title: this.title,
dataLength: data?.length,
hasFilter: this.enableFilter,
filterField: this.filterField,
filterValue: this.filterValue
});
// Transform data if transform function is provided // Transform data if transform function is provided
let transformedData = this.transformData(data); let transformedData = this.transformData(data);
// Apply filtering if enabled // Apply filtering if enabled
if (this.enableFilter && this.filterField && this.filterValue) { if (this.enableFilter && this.filterField && this.filterValue) {
transformedData = this.applyFilter(transformedData); transformedData = this.applyFilter(transformedData);
console.log('SimpleKpiWidget after filter:', {
filteredLength: transformedData?.length
});
} }
// Handle count aggregation separately as it doesn't need a valueField // Handle count aggregation separately as it doesn't need a valueField
if (this.aggregation === 'count') { if (this.aggregation === 'count') {
this.value = (transformedData?.length || 0).toLocaleString(); // If valueField is specified and it's a date/unique field, count unique values
if (this.valueField && ['dateid', 'date', 'datetime', 'day'].some(part => this.valueField.toLowerCase().includes(part))) {
// Count unique values instead of all records
const uniqueValues = new Set(transformedData.map(item => item[this.valueField]));
this.value = uniqueValues.size.toLocaleString();
console.log(`SimpleKpiWidget counting unique ${this.valueField}: ${uniqueValues.size} from ${transformedData.length} records`);
} else {
// Regular count: count all records
this.value = (transformedData?.length || 0).toLocaleString();
}
this.updateTrendData(transformedData); this.updateTrendData(transformedData);
this.updateLabel(transformedData); this.updateLabel(transformedData);
return; return;
...@@ -914,15 +934,22 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent { ...@@ -914,15 +934,22 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
return data; return data;
} }
console.log('SimpleKpiWidget applying filter:', {
filterField: this.filterField,
filterValue: this.filterValue,
filterOperator: this.filterOperator,
dataLength: data?.length
});
return data.filter(item => { return data.filter(item => {
const fieldValue = item[this.filterField]; const fieldValue = item[this.filterField];
const filterValue = this.filterValue; const filterValue = this.filterValue;
switch (this.filterOperator) { switch (this.filterOperator) {
case 'equals': case 'equals':
return fieldValue == filterValue; return String(fieldValue).toLowerCase() === String(filterValue).toLowerCase();
case 'not_equals': case 'not_equals':
return fieldValue != filterValue; return String(fieldValue).toLowerCase() !== String(filterValue).toLowerCase();
case 'greater_than': case 'greater_than':
return Number(fieldValue) > Number(filterValue); return Number(fieldValue) > Number(filterValue);
case 'less_than': case 'less_than':
......
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
(actionComplete)="actionComplete($event)" (actionComplete)="actionComplete($event)"
(dataBound)="onDataBound($event)" (dataBound)="onDataBound($event)"
[height]="'100%'" [height]="'100%'"
[width]="'100%'"
[allowResizing]="allowResizing" [allowResizing]="allowResizing"
[rowHeight]="rowHeight"> [rowHeight]="rowHeight">
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
height: 100%; height: 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
width: 100%;
margin: 0;
padding: 0;
// Widget Header // Widget Header
.widget-header { .widget-header {
...@@ -300,6 +303,10 @@ ...@@ -300,6 +303,10 @@
background: white; background: white;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: 100%;
height: 100%;
margin: 0;
padding: 0;
} }
// Interaction States // Interaction States
...@@ -454,10 +461,18 @@ ...@@ -454,10 +461,18 @@
.e-grid { .e-grid {
border: none !important; border: none !important;
font-family: inherit; font-family: inherit;
width: 100% !important;
height: 100% !important;
min-width: 0 !important;
min-height: 0 !important;
margin: 0 !important;
padding: 0 !important;
max-width: 100% !important;
.e-gridheader { .e-gridheader {
background-color: inherit; background-color: inherit;
border-bottom: 1px solid rgba(229, 231, 235, 0.5); border-bottom: 1px solid rgba(229, 231, 235, 0.5);
width: 100% !important;
.e-headercell { .e-headercell {
background-color: inherit; background-color: inherit;
...@@ -466,6 +481,10 @@ ...@@ -466,6 +481,10 @@
font-size: 13px; font-size: 13px;
padding: 12px 8px; padding: 12px 8px;
border-right: 1px solid rgba(229, 231, 235, 0.3); border-right: 1px solid rgba(229, 231, 235, 0.3);
min-width: 0 !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
&:last-child { &:last-child {
border-right: none; border-right: none;
...@@ -475,6 +494,8 @@ ...@@ -475,6 +494,8 @@
.e-content { .e-content {
background-color: transparent; background-color: transparent;
width: 100% !important;
min-width: 0 !important;
.e-row { .e-row {
border-bottom: 1px solid rgba(229, 231, 235, 0.2); border-bottom: 1px solid rgba(229, 231, 235, 0.2);
...@@ -497,6 +518,10 @@ ...@@ -497,6 +518,10 @@
border-right: 1px solid rgba(229, 231, 235, 0.2); border-right: 1px solid rgba(229, 231, 235, 0.2);
font-size: 13px; font-size: 13px;
color: inherit; color: inherit;
min-width: 0 !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
&:last-child { &:last-child {
border-right: none; border-right: none;
......
...@@ -167,7 +167,7 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple ...@@ -167,7 +167,7 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
public animateConditionalChange: boolean = true; public animateConditionalChange: boolean = true;
// Layout properties // Layout properties
public width: number = 600; public width: number = 100;
public height: number = 400; public height: number = 400;
public minWidth: number = 400; public minWidth: number = 400;
public minHeight: number = 300; public minHeight: number = 300;
...@@ -175,11 +175,11 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple ...@@ -175,11 +175,11 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
public maxHeight: number = 800; public maxHeight: number = 800;
public aspectRatio: string = 'auto'; public aspectRatio: string = 'auto';
public responsive: boolean = true; public responsive: boolean = true;
public widthUnit: string = 'px'; public widthUnit: string = '%';
public heightUnit: string = 'px'; public heightUnit: string = 'px';
public fullWidth: boolean = false; public fullWidth: boolean = true;
public fullHeight: boolean = false; public fullHeight: boolean = false;
public sizeOption: string = 'medium'; public sizeOption: string = 'full-width';
// Data properties // Data properties
public dataSource: string = 'static'; public dataSource: string = 'static';
...@@ -392,7 +392,7 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple ...@@ -392,7 +392,7 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
this.customClickHandler = this.configObj.customClickHandler || ''; this.customClickHandler = this.configObj.customClickHandler || '';
// Layout configuration // Layout configuration
this.width = this.configObj.width || 600; this.width = this.configObj.width || 100;
this.height = this.configObj.height || 400; this.height = this.configObj.height || 400;
this.minWidth = this.configObj.minWidth || 400; this.minWidth = this.configObj.minWidth || 400;
this.minHeight = this.configObj.minHeight || 300; this.minHeight = this.configObj.minHeight || 300;
...@@ -400,9 +400,9 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple ...@@ -400,9 +400,9 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
this.maxHeight = this.configObj.maxHeight || 800; this.maxHeight = this.configObj.maxHeight || 800;
this.aspectRatio = this.configObj.aspectRatio || 'auto'; this.aspectRatio = this.configObj.aspectRatio || 'auto';
this.responsive = this.configObj.responsive !== undefined ? this.configObj.responsive : true; this.responsive = this.configObj.responsive !== undefined ? this.configObj.responsive : true;
this.widthUnit = this.configObj.widthUnit || 'px'; this.widthUnit = this.configObj.widthUnit || '%';
this.heightUnit = this.configObj.heightUnit || 'px'; this.heightUnit = this.configObj.heightUnit || 'px';
this.fullWidth = this.configObj.fullWidth !== undefined ? this.configObj.fullWidth : false; this.fullWidth = this.configObj.fullWidth !== undefined ? this.configObj.fullWidth : true;
this.fullHeight = this.configObj.fullHeight !== undefined ? this.configObj.fullHeight : false; this.fullHeight = this.configObj.fullHeight !== undefined ? this.configObj.fullHeight : false;
this.sizeOption = this.configObj.sizeOption || 'medium'; this.sizeOption = this.configObj.sizeOption || 'medium';
...@@ -843,8 +843,8 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple ...@@ -843,8 +843,8 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
'border-color': this.borderColor, 'border-color': this.borderColor,
'border-radius': `${this.borderRadius}px`, 'border-radius': `${this.borderRadius}px`,
'border-width': `${this.borderWidth}px`, 'border-width': `${this.borderWidth}px`,
'padding': `${this.padding}px`, 'padding': '0px', // Force no padding for full width
'margin': `${this.margin}px`, 'margin': '0px', // Force no margin for full width
'font-size': `${this.fontSize}px`, 'font-size': `${this.fontSize}px`,
'font-weight': this.fontWeight, 'font-weight': this.fontWeight,
'font-family': this.fontFamily, 'font-family': this.fontFamily,
......
...@@ -469,11 +469,11 @@ export class SyncfusionPivotWidgetComponent extends BaseWidgetComponent implemen ...@@ -469,11 +469,11 @@ export class SyncfusionPivotWidgetComponent extends BaseWidgetComponent implemen
onDataBound(args: any): void { onDataBound(args: any): void {
// Apply perspective after data is loaded and rendered, but only once. // Apply perspective after data is loaded and rendered, but only once.
if (this.perspective && !this.isPerspectiveApplied && this.perspective !== '{}') { // if (this.perspective && !this.isPerspectiveApplied && this.perspective !== '{}') {
setTimeout(() => { // setTimeout(() => {
this.setWidgetState(this.perspective as string); // this.setWidgetState(this.perspective as string);
}, 50); // Small delay to ensure rendering is complete // }, 50); // Small delay to ensure rendering is complete
} // }
} }
onReset(): void { onReset(): void {
......
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