Commit ed89bf27 by sawit

แก้ไข widget

parent aac8ace4
......@@ -135,7 +135,7 @@
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);
border: 1px solid #e5e7eb;
min-height: 600px;
min-height: 1200px;
}
/* Empty State */
......@@ -144,7 +144,7 @@
flex-direction: column;
justify-content: center;
align-items: center;
height: 600px;
height: 1200px;
text-align: center;
color: #6b7280;
}
......@@ -437,39 +437,39 @@
/* Ensure widgets don't exceed panel boundaries and fill full space */
.e-panel .e-panel-container .content > * {
max-width: 100% !important;
max-height: 100% !important;
width: 100% !important;
height: 100% !important;
overflow: hidden !important;
box-sizing: border-box !important;
flex: 1 !important;
display: flex !important;
flex-direction: column !important;
max-width: 100% !important;
min-width: 0 !important;
}
/* Specific widget component styling */
.e-panel .e-panel-container .content > * {
/* Specific styling for Syncfusion Datagrid Widget */
.e-panel .e-panel-container .content app-syncfusion-datagrid-widget {
width: 100% !important;
height: 100% !important;
flex: 1 !important;
display: flex !important;
flex-direction: column !important;
min-height: 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;
margin: 0 !important;
padding: 0 !important;
}
/* Force all nested elements to use full space */
.e-panel .e-panel-container .content * {
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 {
originalWidget: widget
};
// Force SyncfusionDatagridWidgetComponent to use full width
if (widget.component === 'SyncfusionDatagridWidgetComponent') {
panel.sizeX = this.columns;
panel.maxSizeX = this.columns;
}
return panel;
})
......
/* Dashboard Viewer Styles - Clean and Responsive */
/* Background */
// .dashboard-background {
// background: linear-gradient(to bottom right, #f8fafc, #e0e7ff);
// /* Dashboard Viewer Styles - Clean and Responsive */
// /* Background */
// // .dashboard-background {
// // background: linear-gradient(to bottom right, #f8fafc, #e0e7ff);
// // min-height: 100vh;
// // }
// /* Error Message */
// .error-message {
// display: flex;
// justify-content: center;
// align-items: center;
// min-height: 100vh;
// background: linear-gradient(to bottom right, #f8fafc, #e0e7ff);
// }
/* Error Message */
.error-message {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(to bottom right, #f8fafc, #e0e7ff);
}
.error-message-content {
background: white;
padding: 2rem;
border-radius: 12px;
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;
text-align: center;
max-width: 500px;
}
// .error-message-content {
// background: white;
// padding: 2rem;
// border-radius: 12px;
// 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;
// text-align: center;
// max-width: 500px;
// }
.error-icon {
font-size: 3rem;
color: #ef4444;
margin-bottom: 1rem;
}
// .error-icon {
// font-size: 3rem;
// color: #ef4444;
// margin-bottom: 1rem;
// }
.error-text {
font-size: 1.25rem;
font-weight: 600;
color: #374151;
display: block;
margin-bottom: 0.5rem;
}
// .error-text {
// font-size: 1.25rem;
// font-weight: 600;
// color: #374151;
// display: block;
// margin-bottom: 0.5rem;
// }
.error-description {
color: #6b7280;
font-size: 1rem;
}
// .error-description {
// color: #6b7280;
// font-size: 1rem;
// }
/* Layout Classes */
.action-buttons {
display: flex;
align-items: center;
gap: 0.75rem;
flex-shrink: 0;
flex-wrap: wrap;
}
// /* Layout Classes */
// .action-buttons {
// display: flex;
// align-items: center;
// gap: 0.75rem;
// flex-shrink: 0;
// flex-wrap: wrap;
// }
.view-dashboard-section {
margin-bottom: 1rem;
}
// .view-dashboard-section {
// margin-bottom: 1rem;
// }
.dashboard-header-container {
background: white;
......@@ -126,34 +126,34 @@
margin-top: 0.25rem;
}
.dashboard-selector {
display: flex;
align-items: center;
gap: 0.75rem;
flex-shrink: 0;
}
.selector-label {
font-size: 0.875rem;
font-weight: 500;
color: #374151;
}
// .dashboard-selector {
// display: flex;
// align-items: center;
// gap: 0.75rem;
// flex-shrink: 0;
// }
.dashboard-select {
padding: 0.5rem 1rem;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
background: white;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
min-width: 200px;
font-size: 0.875rem;
// .selector-label {
// font-size: 0.875rem;
// font-weight: 500;
// color: #374151;
// }
&:focus {
outline: none;
border-color: #4f46e5;
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
}
// .dashboard-select {
// padding: 0.5rem 1rem;
// border: 1px solid #d1d5db;
// border-radius: 0.5rem;
// background: white;
// box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
// min-width: 200px;
// font-size: 0.875rem;
// &:focus {
// outline: none;
// border-color: #4f46e5;
// box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
// }
// }
.dataset-picker-section {
display: flex;
......@@ -162,541 +162,541 @@
flex-shrink: 0;
}
/* Dashboard Content Area - Full Width and Responsive */
.dashboard-content-area {
width: 100%;
min-height: 100vh;
padding: 0;
margin: 0;
background: linear-gradient(to bottom right, #f8fafc, #e0e7ff);
}
/* Dashboard Layout Container - Clean and Responsive */
// .dashboard-layout-container {
// /* Dashboard Content Area - Full Width and Responsive */
// .dashboard-content-area {
// width: 100%;
// min-height: 100vh;
// padding: 1rem;
// box-sizing: border-box;
// padding: 0;
// margin: 0;
// background: linear-gradient(to bottom right, #f8fafc, #e0e7ff);
// }
/* Dashboard Layout - Responsive Grid */
.dashboard-layout {
width: 100% !important;
height: auto !important;
min-height: calc(100vh - 2rem);
background: transparent;
// /* Dashboard Layout Container - Clean and Responsive */
// // .dashboard-layout-container {
// // width: 100%;
// // min-height: 100vh;
// // padding: 1rem;
// // box-sizing: border-box;
// // }
// /* Dashboard Layout - Responsive Grid */
// .dashboard-layout {
// width: 100% !important;
// height: auto !important;
// min-height: calc(100vh - 2rem);
// background: transparent;
// .e-panel {
// border-radius: 12px;
// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
// border: 1px solid #e5e7eb;
// background: white;
// transition: all 0.3s ease;
// position: relative;
// overflow: hidden;
// margin: 0;
// &:hover {
// box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
// transform: translateY(-2px);
// }
// }
.e-panel {
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
border: 1px solid #e5e7eb;
background: white;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
margin: 0;
// .e-panel-header {
// display: none !important; /* Hide panel headers in viewer mode */
// }
&:hover {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
transform: translateY(-2px);
}
}
.e-panel-header {
display: none !important; /* Hide panel headers in viewer mode */
}
.e-panel-content {
border-radius: 12px;
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
}
// .e-panel-content {
// border-radius: 12px;
// overflow: hidden;
// position: relative;
// width: 100%;
// height: 100%;
// padding: 0;
// margin: 0;
// }
// }
.dashboard-content-card {
background: white;
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);
border: 1px solid #e5e7eb;
min-height: 600px;
}
// .dashboard-content-card {
// background: white;
// 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);
// border: 1px solid #e5e7eb;
// min-height: 600px;
// }
/* Empty State */
.empty-state {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 600px;
text-align: center;
color: #6b7280;
}
// /* Empty State */
// .empty-state {
// display: flex;
// flex-direction: column;
// justify-content: center;
// align-items: center;
// height: 600px;
// text-align: center;
// color: #6b7280;
// }
.empty-state-icon {
padding: 2rem;
background: linear-gradient(to bottom right, #dbeafe, #e0e7ff);
border-radius: 50%;
margin-bottom: 1.5rem;
}
// .empty-state-icon {
// padding: 2rem;
// background: linear-gradient(to bottom right, #dbeafe, #e0e7ff);
// border-radius: 50%;
// margin-bottom: 1.5rem;
// }
.empty-state-icon i {
font-size: 3.75rem;
color: #60a5fa;
}
// .empty-state-icon i {
// font-size: 3.75rem;
// color: #60a5fa;
// }
.empty-state-title {
font-size: 1.5rem;
font-weight: 600;
color: #374151;
margin-bottom: 0.5rem;
}
// .empty-state-title {
// font-size: 1.5rem;
// font-weight: 600;
// color: #374151;
// margin-bottom: 0.5rem;
// }
.empty-state-description {
color: #6b7280;
max-width: 28rem;
margin-bottom: 1.5rem;
}
// .empty-state-description {
// color: #6b7280;
// max-width: 28rem;
// margin-bottom: 1.5rem;
// }
/* Custom Button Styles (fallback for Tailwind) */
.custom-btn {
display: inline-flex;
align-items: center;
padding: 0.5rem 1rem;
font-size: 0.875rem;
font-weight: 500;
border-radius: 0.5rem;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
transition: all 0.2s ease-in-out;
border: none;
cursor: pointer;
text-decoration: none;
&:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
}
&:hover {
transform: translateY(-1px);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}
i {
margin-right: 0.5rem;
}
}
// /* Custom Button Styles (fallback for Tailwind) */
// .custom-btn {
// display: inline-flex;
// align-items: center;
// padding: 0.5rem 1rem;
// font-size: 0.875rem;
// font-weight: 500;
// border-radius: 0.5rem;
// box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
// transition: all 0.2s ease-in-out;
// border: none;
// cursor: pointer;
// text-decoration: none;
// &:focus {
// outline: none;
// box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
// }
.btn-indigo {
background-color: #4f46e5;
color: white;
// &:hover {
// transform: translateY(-1px);
// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
// }
&:hover {
background-color: #4338ca;
}
// i {
// margin-right: 0.5rem;
// }
// }
&:focus {
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.5);
}
}
// .btn-indigo {
// background-color: #4f46e5;
// color: white;
.btn-emerald {
background-color: #10b981;
color: white;
// &:hover {
// background-color: #4338ca;
// }
&:hover {
background-color: #059669;
}
// &:focus {
// box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.5);
// }
// }
&:focus {
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.5);
}
}
// .btn-emerald {
// background-color: #10b981;
// color: white;
.btn-red {
background-color: #ef4444;
color: white;
// &:hover {
// background-color: #059669;
// }
&:hover {
background-color: #dc2626;
}
// &:focus {
// box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.5);
// }
// }
&:focus {
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.5);
}
}
// .btn-red {
// background-color: #ef4444;
// color: white;
.btn-green {
background-color: #22c55e;
color: white;
// &:hover {
// background-color: #dc2626;
// }
&:hover {
background-color: #16a34a;
}
// &:focus {
// box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.5);
// }
// }
&:focus {
box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.5);
}
}
// .btn-green {
// background-color: #22c55e;
// color: white;
.btn-blue {
background-color: #3b82f6;
color: white;
// &:hover {
// background-color: #16a34a;
// }
&:hover {
background-color: #2563eb;
}
// &:focus {
// box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.5);
// }
// }
&:focus {
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
}
}
// .btn-blue {
// background-color: #3b82f6;
// color: white;
.btn-gray {
background-color: #6b7280;
color: white;
// &:hover {
// background-color: #2563eb;
// }
&:hover {
background-color: #4b5563;
}
// &:focus {
// box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
// }
// }
&:focus {
box-shadow: 0 0 0 3px rgba(107, 114, 128, 0.5);
}
}
// .btn-gray {
// background-color: #6b7280;
// color: white;
/* Dashboard Layout Styling */
.dashboard-layout {
.e-panel {
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
border: 1px solid #e5e7eb;
transition: all 0.3s ease;
position: relative;
max-width: 100%;
overflow: hidden;
&:hover {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
transform: translateY(-2px);
}
}
.e-panel-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 12px 12px 0 0;
padding: 12px 16px;
font-weight: 600;
position: relative;
}
.e-panel-content {
border-radius: 0 0 12px 12px;
overflow: hidden;
position: relative;
}
}
// &:hover {
// background-color: #4b5563;
// }
/* Syncfusion DashboardLayout Override for Viewer */
::ng-deep {
#dashboard_default.e-dashboardlayout {
width: 100% !important;
height: auto !important;
min-height: calc(100vh - 2rem) !important;
max-height: none !important;
overflow: visible !important;
position: relative !important;
background: transparent !important;
padding: 0 !important;
margin: 0 !important;
.e-panel {
max-width: 100% !important;
overflow: hidden !important;
position: relative !important;
background: white !important;
border: 1px solid #e5e7eb !important;
border-radius: 12px !important;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
margin: 0 !important;
}
.e-panel-header {
display: none !important; /* Completely hide headers in viewer */
}
.e-panel-content {
overflow: hidden !important;
max-width: 100% !important;
width: 100% !important;
height: 100% !important;
padding: 0 !important;
margin: 0 !important;
background: white !important;
border-radius: 12px !important;
}
/* Ensure widgets don't overflow */
.e-panel .e-panel-container {
width: 100% !important;
height: 100% !important;
overflow: hidden !important;
position: relative !important;
}
/* Widget content styling */
.e-panel .e-panel-container .content {
width: 100% !important;
height: 100% !important;
overflow: hidden !important;
position: relative !important;
padding: 0 !important;
margin: 0 !important;
}
}
}
// &:focus {
// box-shadow: 0 0 0 3px rgba(107, 114, 128, 0.5);
// }
// }
/* Widget Panel Enhancements */
.widget-panel {
.e-panel {
background: white;
border: 1px solid #e5e7eb;
border-radius: 12px;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
&:hover {
border-color: #3b82f6;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
}
}
// /* Dashboard Layout Styling */
// .dashboard-layout {
// .e-panel {
// border-radius: 12px;
// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
// border: 1px solid #e5e7eb;
// transition: all 0.3s ease;
// position: relative;
// max-width: 100%;
// overflow: hidden;
// &:hover {
// box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
// transform: translateY(-2px);
// }
// }
/* Loading States */
.loading-shimmer {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 2s infinite;
}
// .e-panel-header {
// background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
// color: white;
// border-radius: 12px 12px 0 0;
// padding: 12px 16px;
// font-weight: 600;
// position: relative;
// }
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
// .e-panel-content {
// border-radius: 0 0 12px 12px;
// overflow: hidden;
// position: relative;
// }
// }
/* Responsive Design for Dashboard Viewer */
@media (max-width: 1200px) {
.dashboard-layout-container {
padding: 0.75rem;
}
::ng-deep {
#dashboard_default.e-dashboardlayout {
min-height: calc(100vh - 1.5rem) !important;
}
}
}
// /* Syncfusion DashboardLayout Override for Viewer */
// ::ng-deep {
// #dashboard_default.e-dashboardlayout {
// width: 100% !important;
// height: auto !important;
// min-height: calc(100vh - 2rem) !important;
// max-height: none !important;
// overflow: visible !important;
// position: relative !important;
// background: transparent !important;
// padding: 0 !important;
// margin: 0 !important;
// .e-panel {
// max-width: 100% !important;
// overflow: hidden !important;
// position: relative !important;
// background: white !important;
// border: 1px solid #e5e7eb !important;
// border-radius: 12px !important;
// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
// margin: 0 !important;
// }
@media (max-width: 1024px) {
.dashboard-layout-container {
padding: 0.5rem;
}
.dashboard-layout {
.e-panel {
margin: 0.25rem;
}
}
::ng-deep {
#dashboard_default.e-dashboardlayout {
min-height: calc(100vh - 1rem) !important;
.e-panel {
border-radius: 8px !important;
}
}
}
}
// .e-panel-header {
// display: none !important; /* Completely hide headers in viewer */
// }
@media (max-width: 768px) {
.dashboard-layout-container {
padding: 0.25rem;
}
.dashboard-layout {
.e-panel {
margin: 0.125rem;
border-radius: 8px;
}
}
::ng-deep {
#dashboard_default.e-dashboardlayout {
min-height: calc(100vh - 0.5rem) !important;
.e-panel {
border-radius: 8px !important;
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.06) !important;
}
}
}
}
// .e-panel-content {
// overflow: hidden !important;
// max-width: 100% !important;
// width: 100% !important;
// height: 100% !important;
// padding: 0 !important;
// margin: 0 !important;
// background: white !important;
// border-radius: 12px !important;
// }
@media (max-width: 480px) {
.dashboard-layout-container {
padding: 0.125rem;
}
.dashboard-layout {
.e-panel {
margin: 0.0625rem;
border-radius: 6px;
}
}
::ng-deep {
#dashboard_default.e-dashboardlayout {
min-height: calc(100vh - 0.25rem) !important;
.e-panel {
border-radius: 6px !important;
box-shadow: 0 1px 3px -1px rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.06) !important;
}
}
}
}
// /* Ensure widgets don't overflow */
// .e-panel .e-panel-container {
// width: 100% !important;
// height: 100% !important;
// overflow: hidden !important;
// position: relative !important;
// }
// /* Widget content styling */
// .e-panel .e-panel-container .content {
// width: 100% !important;
// height: 100% !important;
// overflow: hidden !important;
// position: relative !important;
// padding: 0 !important;
// margin: 0 !important;
// }
// }
// }
.dashboard-container {
display: flex;
height: 100vh;
background-color: #f3f4f6; /* bg-gray-100 */
}
// /* Widget Panel Enhancements */
// .widget-panel {
// .e-panel {
// background: white;
// border: 1px solid #e5e7eb;
// border-radius: 12px;
// overflow: hidden;
// transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
// &:hover {
// border-color: #3b82f6;
// box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
// }
// }
// }
.widget-sidebar {
width: 18rem; /* w-72 */
background-color: #ffffff; /* bg-white */
padding: 1rem; /* p-4 */
overflow-y: auto;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-lg */
border-right: 1px solid #e5e7eb; /* border-r border-gray-200 */
display: flex;
flex-direction: column;
}
// /* Loading States */
// .loading-shimmer {
// background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
// background-size: 200% 100%;
// animation: shimmer 2s infinite;
// }
.widget-list {
flex-grow: 1;
/* space-y-2 is handled by margin-bottom on widget-item */
}
// @keyframes shimmer {
// 0% { background-position: -200% 0; }
// 100% { background-position: 200% 0; }
// }
.widget-item {
padding: 0.75rem; /* p-3 */
margin-bottom: 0.5rem; /* mb-2 */
background-color: #f9fafb; /* bg-gray-50 */
border-radius: 0.5rem; /* rounded-lg */
border: 1px solid #e5e7eb; /* border border-gray-200 */
cursor: pointer;
transition: all 0.2s ease-in-out;
&:hover {
background-color: #e0e7ff; /* hover:bg-indigo-50 */
border-color: #c7d2fe; /* hover:border-indigo-100 */
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* hover:shadow-md */
}
}
// /* Responsive Design for Dashboard Viewer */
// @media (max-width: 1200px) {
// .dashboard-layout-container {
// padding: 0.75rem;
// }
.dashboard-area {
flex: 1;
display: flex;
flex-direction: column;
background-color: #f3f4f6; /* bg-gray-100 */
}
// ::ng-deep {
// #dashboard_default.e-dashboardlayout {
// min-height: calc(100vh - 1.5rem) !important;
// }
// }
// }
.dashboard-header {
padding: 1rem; /* p-4 */
background-color: #ffffff; /* bg-white */
border-bottom: 1px solid #e5e7eb; /* border-b border-gray-200 */
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); /* shadow-sm */
}
// @media (max-width: 1024px) {
// .dashboard-layout-container {
// padding: 0.5rem;
// }
.dashboard-content {
// flex: 1;
padding: 1rem; /* p-4 */
overflow: auto;
min-height: 600px; /* min-h-[600px] */
}
// .dashboard-layout {
// .e-panel {
// margin: 0.25rem;
// }
// }
/* Button styles (assuming ti-btn is a base class) */
.ti-btn {
font-weight: bold;
padding: 0.5rem 1rem; /* py-2 px-4 */
border-radius: 0.5rem; /* rounded-lg */
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-md */
transition: transform 0.2s ease-in-out; /* transition-transform */
transform: scale(1); /* transform */
&:hover {
transform: scale(1.05); /* hover:scale-105 */
}
}
// ::ng-deep {
// #dashboard_default.e-dashboardlayout {
// min-height: calc(100vh - 1rem) !important;
.ti-btn-primary-full {
background-color: #4f46e5; /* bg-indigo-600 */
color: #ffffff; /* text-white */
&:hover {
background-color: #4338ca; /* hover:bg-indigo-700 */
}
}
// .e-panel {
// border-radius: 8px !important;
// }
// }
// }
// }
.ti-btn-info-full {
background-color: #14b8a6; /* bg-teal-600 */
color: #ffffff; /* text-white */
&:hover {
background-color: #0d9488; /* hover:bg-teal-700 */
}
}
// @media (max-width: 768px) {
// .dashboard-layout-container {
// padding: 0.25rem;
// }
.ti-btn-danger-full {
background-color: #ef4444; /* bg-rose-600 */
color: #ffffff; /* text-white */
&:hover {
background-color: #dc2626; /* hover:bg-rose-700 */
}
}
// .dashboard-layout {
// .e-panel {
// margin: 0.125rem;
// border-radius: 8px;
// }
// }
.ti-btn-success-full {
background-color: #10b981; /* bg-emerald-600 */
color: #ffffff; /* text-white */
&:hover {
background-color: #059669; /* hover:bg-emerald-700 */
}
}
// ::ng-deep {
// #dashboard_default.e-dashboardlayout {
// min-height: calc(100vh - 0.5rem) !important;
.ti-btn-secondary-full {
background-color: #6b7280; /* A shade of gray, similar to default secondary */
color: #ffffff;
&:hover {
background-color: #4b5563;
}
}
// .control-section {
// margin: 0 auto;
// width: 500px;
// .e-panel {
// border-radius: 8px !important;
// box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.06) !important;
// }
// }
// }
// }
// #defaultLayout {
// padding: 10px;
// @media (max-width: 480px) {
// .dashboard-layout-container {
// padding: 0.125rem;
// }
// #dashboard_default .e-panel .e-panel-container .content {
// vertical-align: middle;
// font-weight: 600;
// font-size: 20px;
// text-align: center;
// line-height: 90px;
// .dashboard-layout {
// .e-panel {
// margin: 0.0625rem;
// border-radius: 6px;
// }
// }
// ::ng-deep {
// #dashboard_default.e-dashboardlayout {
// min-height: calc(100vh - 0.25rem) !important;
// .e-panel {
// border-radius: 6px !important;
// box-shadow: 0 1px 3px -1px rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.06) !important;
// }
// }
// }
// }
// .dashboard-container {
// display: flex;
// height: 100vh;
// background-color: #f3f4f6; /* bg-gray-100 */
// }
// .widget-sidebar {
// width: 18rem; /* w-72 */
// background-color: #ffffff; /* bg-white */
// padding: 1rem; /* p-4 */
// overflow-y: auto;
// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-lg */
// border-right: 1px solid #e5e7eb; /* border-r border-gray-200 */
// display: flex;
// flex-direction: column;
// }
// .widget-list {
// flex-grow: 1;
// /* space-y-2 is handled by margin-bottom on widget-item */
// }
// .widget-item {
// padding: 0.75rem; /* p-3 */
// margin-bottom: 0.5rem; /* mb-2 */
// background-color: #f9fafb; /* bg-gray-50 */
// border-radius: 0.5rem; /* rounded-lg */
// border: 1px solid #e5e7eb; /* border border-gray-200 */
// cursor: pointer;
// transition: all 0.2s ease-in-out;
// &:hover {
// background-color: #e0e7ff; /* hover:bg-indigo-50 */
// border-color: #c7d2fe; /* hover:border-indigo-100 */
// box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* hover:shadow-md */
// }
// }
// .dashboard-area {
// flex: 1;
// display: flex;
// flex-direction: column;
// background-color: #f3f4f6; /* bg-gray-100 */
// }
// .dashboard-header {
// padding: 1rem; /* p-4 */
// background-color: #ffffff; /* bg-white */
// border-bottom: 1px solid #e5e7eb; /* border-b border-gray-200 */
// box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); /* shadow-sm */
// }
// .dashboard-content {
// // flex: 1;
// padding: 1rem; /* p-4 */
// overflow: auto;
// min-height: 600px; /* min-h-[600px] */
// }
// /* Button styles (assuming ti-btn is a base class) */
// .ti-btn {
// font-weight: bold;
// padding: 0.5rem 1rem; /* py-2 px-4 */
// border-radius: 0.5rem; /* rounded-lg */
// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-md */
// transition: transform 0.2s ease-in-out; /* transition-transform */
// transform: scale(1); /* transform */
// &:hover {
// transform: scale(1.05); /* hover:scale-105 */
// }
// }
// .ti-btn-primary-full {
// background-color: #4f46e5; /* bg-indigo-600 */
// color: #ffffff; /* text-white */
// &:hover {
// background-color: #4338ca; /* hover:bg-indigo-700 */
// }
// }
// .ti-btn-info-full {
// background-color: #14b8a6; /* bg-teal-600 */
// color: #ffffff; /* text-white */
// &:hover {
// background-color: #0d9488; /* hover:bg-teal-700 */
// }
// }
// .ti-btn-danger-full {
// background-color: #ef4444; /* bg-rose-600 */
// color: #ffffff; /* text-white */
// &:hover {
// background-color: #dc2626; /* hover:bg-rose-700 */
// }
// }
// .ti-btn-success-full {
// background-color: #10b981; /* bg-emerald-600 */
// color: #ffffff; /* text-white */
// &:hover {
// background-color: #059669; /* hover:bg-emerald-700 */
// }
// }
// .ti-btn-secondary-full {
// background-color: #6b7280; /* A shade of gray, similar to default secondary */
// color: #ffffff;
// &:hover {
// background-color: #4b5563;
// }
// }
// // .control-section {
// // margin: 0 auto;
// // width: 500px;
// // }
// // #defaultLayout {
// // padding: 10px;
// // }
// // #dashboard_default .e-panel .e-panel-container .content {
// // vertical-align: middle;
// // font-weight: 600;
// // font-size: 20px;
// // text-align: center;
// // line-height: 90px;
// // }
......@@ -163,7 +163,7 @@ export class DashboardViewerComponent implements OnInit, OnDestroy {
return null;
}
return {
const panel = {
id: `${(widget as any).instanceId}-${widget.y}-${widget.x}`,
header: widget.thName,
sizeX: widget.cols || 4, // Default size if not specified
......@@ -177,6 +177,13 @@ export class DashboardViewerComponent implements OnInit, OnDestroy {
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[];
}
......
......@@ -609,6 +609,10 @@
<div *ngIf="widgetType === 'PieChartWidgetComponent' || widgetType === 'BarChartWidgetComponent' || widgetType === 'AreaChartWidgetComponent' || widgetType === 'DoughnutChartWidgetComponent' || widgetType === 'FunnelChartWidgetComponent'">
<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-select [(ngModel)]="currentConfig.xField" name="xField">
<mat-option *ngFor="let col of availableColumns" [value]="col">{{ col }}</mat-option>
......@@ -620,18 +624,26 @@
<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>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-label>Aggregation (for Pie/Doughnut/Funnel)</mat-label>
<mat-label>Aggregation</mat-label>
<mat-select [(ngModel)]="currentConfig.aggregation" name="aggregation">
<mat-option value="none">None</mat-option>
<mat-option value="count">Count</mat-option>
<mat-option value="sum">Sum</mat-option>
</mat-select>
</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 *ngIf="widgetType === 'GaugeChartWidgetComponent'">
......
......@@ -218,9 +218,11 @@ export class WidgetConfigComponent implements OnInit, AfterViewInit, OnDestroy {
if (!this.currentConfig.clickAction) this.currentConfig.clickAction = 'none';
// 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.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
if (!this.currentConfig.dataSource) this.currentConfig.dataSource = 'static';
......@@ -257,6 +259,7 @@ export class WidgetConfigComponent implements OnInit, AfterViewInit, OnDestroy {
if (!this.currentConfig.yAxisField) this.currentConfig.yAxisField = '';
if (!this.currentConfig.valueField) this.currentConfig.valueField = '';
if (!this.currentConfig.labelField) this.currentConfig.labelField = '';
if (!this.currentConfig.aggregation) this.currentConfig.aggregation = 'count';
if (!this.currentConfig.apiEndpoint) this.currentConfig.apiEndpoint = '';
// Chart options defaults
......
......@@ -31,20 +31,76 @@ export class BarChartWidgetComponent extends BaseWidgetComponent {
}
onDataUpdate(data: any[]): void {
if (!data || data.length === 0) {
// Check if data is an array
if (!Array.isArray(data) || data.length === 0) {
this.chartData = [];
return;
}
const xField = this.configObj.xField || 'x';
const yField = this.configObj.yField || 'y';
// Support multiple field name formats from config
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';
console.log('BarChart onDataUpdate:', {
data: data.slice(0, 3),
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[yField] || 0
y: item[fieldToUse] || 0
}));
}
console.log('BarChart chartData:', this.chartData.slice(0, 5));
}
onReset(): void {
this.title = 'Bar Chart (Default)';
this.chartData = [
......
......@@ -35,22 +35,34 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy {
next: (selectedDataset: SelectedDataset | null) => {
this.isLoading = true;
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 {
this.originalData = selectedDataset.data;
console.log('BaseWidget applying filters on data of length:', this.originalData.length);
this.applyFilters();
console.log('BaseWidget filtered data length:', this.filteredData.length);
this.onDataUpdate(this.filteredData);
this.isLoading = false;
} catch (error) {
console.error('BaseWidget error in data processing:', error);
this.handleError(error);
}
} 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.
// The initial state is set by applyInitialConfig().
this.isLoading = true;
}
},
error: (err) => {
console.error('BaseWidget error in subscription:', err);
this.handleError(err);
}
});
......@@ -105,7 +117,9 @@ export abstract class BaseWidgetComponent implements OnInit, OnDestroy {
// Parse data string to array
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) {
console.warn('Failed to parse data JSON:', error);
this.originalData = [];
......
......@@ -21,33 +21,102 @@ export class PieChartWidgetComponent extends BaseWidgetComponent {
applyInitialConfig(): void {
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 = [];
}
onDataUpdate(data: any[]): void {
if (!data || data.length === 0) {
// Check if data is an array
if (!Array.isArray(data) || data.length === 0) {
this.chartData = [];
return;
}
const xField = this.configObj.xField || 'x';
const yField = this.configObj.yField || 'y';
// Support multiple field name formats from config
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;
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 key = item[xField] || '';
const key = item[labelField] || '';
acc[key] = (acc[key] || 0) + 1;
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 {
// No aggregation: map directly
transformedData = transformedData.map(item => ({
x: item[xField] || '',
y: item[yField] || 0
x: item[labelField] || '(Empty)',
y: item[valueField] || 0,
text: `${item[labelField] || '(Empty)'}: ${item[valueField] || 0}`
}));
}
console.log('PieChart chartData:', transformedData.slice(0, 10));
this.chartData = transformedData;
}
......
......@@ -325,17 +325,37 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
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
let transformedData = this.transformData(data);
// Apply filtering if enabled
if (this.enableFilter && this.filterField && this.filterValue) {
transformedData = this.applyFilter(transformedData);
console.log('SimpleKpiWidget after filter:', {
filteredLength: transformedData?.length
});
}
// Handle count aggregation separately as it doesn't need a valueField
if (this.aggregation === 'count') {
// 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.updateLabel(transformedData);
return;
......@@ -914,15 +934,22 @@ export class SimpleKpiWidgetComponent extends BaseWidgetComponent {
return data;
}
console.log('SimpleKpiWidget applying filter:', {
filterField: this.filterField,
filterValue: this.filterValue,
filterOperator: this.filterOperator,
dataLength: data?.length
});
return data.filter(item => {
const fieldValue = item[this.filterField];
const filterValue = this.filterValue;
switch (this.filterOperator) {
case 'equals':
return fieldValue == filterValue;
return String(fieldValue).toLowerCase() === String(filterValue).toLowerCase();
case 'not_equals':
return fieldValue != filterValue;
return String(fieldValue).toLowerCase() !== String(filterValue).toLowerCase();
case 'greater_than':
return Number(fieldValue) > Number(filterValue);
case 'less_than':
......
......@@ -115,6 +115,7 @@
(actionComplete)="actionComplete($event)"
(dataBound)="onDataBound($event)"
[height]="'100%'"
[width]="'100%'"
[allowResizing]="allowResizing"
[rowHeight]="rowHeight">
......
......@@ -5,6 +5,9 @@
height: 100%;
position: relative;
overflow: hidden;
width: 100%;
margin: 0;
padding: 0;
// Widget Header
.widget-header {
......@@ -300,6 +303,10 @@
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
// Interaction States
......@@ -454,10 +461,18 @@
.e-grid {
border: none !important;
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 {
background-color: inherit;
border-bottom: 1px solid rgba(229, 231, 235, 0.5);
width: 100% !important;
.e-headercell {
background-color: inherit;
......@@ -466,6 +481,10 @@
font-size: 13px;
padding: 12px 8px;
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 {
border-right: none;
......@@ -475,6 +494,8 @@
.e-content {
background-color: transparent;
width: 100% !important;
min-width: 0 !important;
.e-row {
border-bottom: 1px solid rgba(229, 231, 235, 0.2);
......@@ -497,6 +518,10 @@
border-right: 1px solid rgba(229, 231, 235, 0.2);
font-size: 13px;
color: inherit;
min-width: 0 !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
&:last-child {
border-right: none;
......
......@@ -167,7 +167,7 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
public animateConditionalChange: boolean = true;
// Layout properties
public width: number = 600;
public width: number = 100;
public height: number = 400;
public minWidth: number = 400;
public minHeight: number = 300;
......@@ -175,11 +175,11 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
public maxHeight: number = 800;
public aspectRatio: string = 'auto';
public responsive: boolean = true;
public widthUnit: string = 'px';
public widthUnit: string = '%';
public heightUnit: string = 'px';
public fullWidth: boolean = false;
public fullWidth: boolean = true;
public fullHeight: boolean = false;
public sizeOption: string = 'medium';
public sizeOption: string = 'full-width';
// Data properties
public dataSource: string = 'static';
......@@ -392,7 +392,7 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
this.customClickHandler = this.configObj.customClickHandler || '';
// Layout configuration
this.width = this.configObj.width || 600;
this.width = this.configObj.width || 100;
this.height = this.configObj.height || 400;
this.minWidth = this.configObj.minWidth || 400;
this.minHeight = this.configObj.minHeight || 300;
......@@ -400,9 +400,9 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
this.maxHeight = this.configObj.maxHeight || 800;
this.aspectRatio = this.configObj.aspectRatio || 'auto';
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.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.sizeOption = this.configObj.sizeOption || 'medium';
......@@ -843,8 +843,8 @@ export class SyncfusionDatagridWidgetComponent extends BaseWidgetComponent imple
'border-color': this.borderColor,
'border-radius': `${this.borderRadius}px`,
'border-width': `${this.borderWidth}px`,
'padding': `${this.padding}px`,
'margin': `${this.margin}px`,
'padding': '0px', // Force no padding for full width
'margin': '0px', // Force no margin for full width
'font-size': `${this.fontSize}px`,
'font-weight': this.fontWeight,
'font-family': this.fontFamily,
......
......@@ -469,11 +469,11 @@ export class SyncfusionPivotWidgetComponent extends BaseWidgetComponent implemen
onDataBound(args: any): void {
// Apply perspective after data is loaded and rendered, but only once.
if (this.perspective && !this.isPerspectiveApplied && this.perspective !== '{}') {
setTimeout(() => {
this.setWidgetState(this.perspective as string);
}, 50); // Small delay to ensure rendering is complete
}
// if (this.perspective && !this.isPerspectiveApplied && this.perspective !== '{}') {
// setTimeout(() => {
// this.setWidgetState(this.perspective as string);
// }, 50); // Small delay to ensure rendering is complete
// }
}
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