0">
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.scss b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.scss
index 6212182..9d1cbdc 100644
--- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.scss
+++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.scss
@@ -17,17 +17,78 @@
transform: translateY(-2px);
}
+.compact-filters-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 5px;
+ margin-bottom: 10px;
+ padding: 5px;
+ background: #ffffff;
+ border: 1px solid #e9ecef;
+ border-radius: 6px;
+ min-height: 40px;
+}
-
-.chart-title {
- font-size: 26px;
- font-weight: 700;
- color: #2c3e50;
- margin-bottom: 20px;
+.drilldown-indicator {
+ background-color: #e0e0e0;
+ padding: 10px;
+ margin-bottom: 15px;
+ border-radius: 8px;
text-align: center;
- padding-bottom: 15px;
- border-bottom: 2px solid #3498db;
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.drilldown-text {
+ font-weight: bold;
+ color: #333;
+ font-size: 16px;
+}
+
+.btn {
+ padding: 6px 12px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ transition: all 0.3s ease;
+}
+
+.btn:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
+}
+
+.btn-sm {
+ padding: 4px 8px;
+ font-size: 12px;
+}
+
+.btn-secondary {
+ background-color: #007cba;
+ color: white;
+}
+
+.btn-danger {
+ background-color: #dc3545;
+ color: white;
+}
+
+.chart-header {
+ margin-bottom: 20px;
+
+ .chart-title {
+ font-size: 22px;
+ font-weight: 600;
+ color: #0a192f;
+ margin: 0;
+ text-align: center;
+ padding-bottom: 10px;
+ border-bottom: 2px solid #3498db;
+ }
}
.chart-wrapper {
@@ -56,6 +117,62 @@
transition: all 0.3s ease;
}
+.chart-content {
+ position: relative;
+ height: 100%;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &.loading {
+ opacity: 0.7;
+
+ canvas {
+ filter: blur(2px);
+ }
+ }
+
+ .no-data-message {
+ text-align: center;
+ padding: 30px;
+ color: #666;
+ font-size: 18px;
+ font-style: italic;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ width: 100%;
+ }
+
+ .no-data-message p {
+ margin: 0;
+ }
+
+ .loading-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(255, 255, 255, 0.8);
+
+ .shimmer-donut {
+ width: 120px;
+ height: 120px;
+ border-radius: 50%;
+ background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
+ background-size: 200% 100%;
+ animation: shimmer 1.5s infinite;
+ }
+ }
+}
+
.chart-legend {
display: flex;
flex-wrap: wrap;
@@ -119,36 +236,13 @@
text-align: center;
}
-.loading-indicator, .no-data-message {
- text-align: center;
- padding: 30px;
- color: #666;
- font-size: 18px;
- font-style: italic;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 100%;
-}
-
-.loading-indicator p, .no-data-message p {
- margin: 10px 0 0 0;
-}
-
-.spinner {
- border: 4px solid #f3f3f3;
- border-top: 4px solid #3498db;
- border-radius: 50%;
- width: 40px;
- height: 40px;
- animation: spin 1s linear infinite;
- margin-bottom: 10px;
-}
-
-@keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
+@keyframes shimmer {
+ 0% {
+ background-position: -200% 0;
+ }
+ 100% {
+ background-position: 200% 0;
+ }
}
/* Responsive design */
@@ -157,9 +251,17 @@
padding: 15px;
}
- .chart-title {
- font-size: 20px;
- margin-bottom: 15px;
+ .chart-header .chart-title {
+ font-size: 18px;
+ }
+
+ .drilldown-indicator {
+ flex-direction: column;
+ gap: 5px;
+ }
+
+ .drilldown-text {
+ font-size: 14px;
}
.chart-wrapper {
@@ -181,4 +283,8 @@
font-size: 16px;
padding: 20px;
}
+
+ .compact-filters-container {
+ flex-wrap: wrap;
+ }
}
\ No newline at end of file
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.ts
index 9153a55..106e61c 100644
--- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.ts
+++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/doughnut-chart/doughnut-chart.component.ts
@@ -200,6 +200,12 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck
this.subscriptions.forEach(sub => sub.unsubscribe());
}
+ // Handle filter changes from compact filters
+ onFilterChange(event: { filterId: string, value: any }): void {
+ console.log('Compact filter changed:', event);
+ // The filter service will automatically trigger chart updates through the subscription
+ }
+
// Public method to refresh data when filters change
refreshData(): void {
this.fetchChartData();
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/components/sidebar-filters/sidebar-filters.component.html.new b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/components/sidebar-filters/sidebar-filters.component.html.new
new file mode 100644
index 0000000..95849af
--- /dev/null
+++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/components/sidebar-filters/sidebar-filters.component.html.new
@@ -0,0 +1,25 @@
+
\ No newline at end of file
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/components/sidebar-filters/sidebar-filters.component.ts.new b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/components/sidebar-filters/sidebar-filters.component.ts.new
new file mode 100644
index 0000000..295f2c1
--- /dev/null
+++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/components/sidebar-filters/sidebar-filters.component.ts.new
@@ -0,0 +1,16 @@
+import { Component, OnInit } from '@angular/core';
+import { DashboardFilterService } from '../../services/dashboard-filter.service';
+
+@Component({
+ selector: 'app-shield-sidebar-filters',
+ templateUrl: './sidebar-filters.component.html',
+ styleUrls: ['./sidebar-filters.component.scss']
+})
+export class SidebarFiltersComponent implements OnInit {
+
+ constructor(private filterService: DashboardFilterService) { }
+
+ ngOnInit(): void {
+ // Component initialization
+ }
+}
\ No newline at end of file
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts
index 8343d0b..5fec6fc 100644
--- a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts
+++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts
@@ -74,6 +74,10 @@ export class ShieldDashboardComponent implements OnInit {
{
name: 'Quarterwise Flow',
identifier: 'line_chart'
+ },
+ {
+ name: 'Compact Filter',
+ identifier: 'compact_filter'
}
];
@@ -300,6 +304,20 @@ export class ShieldDashboardComponent implements OnInit {
drilldownLayers: []
};
break;
+ case "compact_filter":
+ newItem = {
+ cols: 3,
+ rows: 2,
+ y: 0,
+ x: 0,
+ chartType: 'compact-filter',
+ name: 'Compact Filter',
+ id: newId,
+ baseFilters: [],
+ drilldownEnabled: false,
+ drilldownLayers: []
+ };
+ break;
default:
newItem = {
cols: 5,
diff --git a/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts.fixed b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts.fixed
new file mode 100644
index 0000000..32eb2b3
--- /dev/null
+++ b/frontend/angular-clarity-master/src/app/modules/main/builder/dashboardnew/gadgets/shield-dashboard/shield-dashboard.component.ts.fixed
@@ -0,0 +1,223 @@
+import { Component, OnInit } from '@angular/core';
+import { GridsterConfig, GridsterItem } from 'angular-gridster2';
+
+interface ShieldDashboardItem extends GridsterItem {
+ chartType: string;
+ name: string;
+ id: number;
+ component?: any;
+}
+
+@Component({
+ selector: 'app-shield-dashboard',
+ templateUrl: './shield-dashboard.component.html',
+ styleUrls: ['./shield-dashboard.component.scss']
+})
+export class ShieldDashboardComponent implements OnInit {
+ options: GridsterConfig;
+ dashboard: Array;
+
+ // Keep track of deleted items
+ deletedItems: Array = [];
+
+ constructor() { }
+
+ ngOnInit(): void {
+ this.options = {
+ gridType: 'fit',
+ enableEmptyCellDrop: true,
+ emptyCellDropCallback: this.onDrop,
+ pushItems: true,
+ swap: true,
+ pushDirections: { north: true, east: true, south: true, west: true },
+ resizable: { enabled: true },
+ itemChangeCallback: this.itemChange.bind(this),
+ draggable: {
+ enabled: true,
+ ignoreContent: true,
+ dropOverItems: true,
+ dragHandleClass: 'drag-handler',
+ ignoreContentClass: 'no-drag',
+ },
+ displayGrid: 'always',
+ minCols: 10,
+ minRows: 10,
+ itemResizeCallback: this.itemResize.bind(this)
+ };
+
+ // Initialize the dashboard with empty canvas
+ this.dashboard = [];
+ }
+
+ onDrop = (event: any) => {
+ // Handle dropping new components onto the dashboard
+ console.log('Item dropped:', event);
+
+ // Get the component identifier from the drag event
+ const componentType = event.dataTransfer ? event.dataTransfer.getData('widgetIdentifier') : '';
+ console.log('Component type dropped:', componentType);
+
+ if (componentType) {
+ this.addComponentToDashboard(componentType);
+ } else {
+ console.log('No component type found in drag data');
+ }
+ }
+
+ // Add a new component to the dashboard
+ addComponentToDashboard(componentType: string) {
+ // Generate a new ID for the component
+ const newId = this.dashboard.length > 0 ? Math.max(...this.dashboard.map(item => item.id), 0) + 1 : 1;
+
+ let newItem: ShieldDashboardItem;
+
+ switch (componentType) {
+ case "bar_chart":
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'bar-chart',
+ name: 'Bar Chart',
+ id: newId
+ };
+ break;
+ case "doughnut_chart":
+ // For doughnut charts, we'll need to determine which one based on existing items
+ const donutCount = this.dashboard.filter(item => item.chartType === 'donut-chart').length;
+ if (donutCount % 2 === 0) {
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'donut-chart',
+ name: 'End Customer Donut',
+ id: newId
+ };
+ } else {
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'donut-chart',
+ name: 'Segment Penetration Donut',
+ id: newId
+ };
+ }
+ break;
+ case "map_chart":
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'map-chart',
+ name: 'Map Chart',
+ id: newId
+ };
+ break;
+ case "grid_view":
+ newItem = {
+ cols: 10,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'data-table',
+ name: 'Data Table',
+ id: newId
+ };
+ break;
+ case "to_do_chart":
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'deal-details',
+ name: 'Deal Details',
+ id: newId
+ };
+ break;
+ case "line_chart":
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: 'quarterwise-flow',
+ name: 'Quarterwise Flow',
+ id: newId
+ };
+ break;
+ default:
+ newItem = {
+ cols: 5,
+ rows: 6,
+ y: 0,
+ x: 0,
+ chartType: componentType,
+ name: componentType,
+ id: newId
+ };
+ }
+
+ // Add the new item to the dashboard
+ this.dashboard.push(newItem);
+ }
+
+ removeItem(item: ShieldDashboardItem) {
+ // Add the item to deleted items list before removing
+ this.deletedItems.push({...item});
+
+ // Remove the item from the dashboard
+ this.dashboard.splice(this.dashboard.indexOf(item), 1);
+ }
+
+ // Restore a deleted item
+ restoreItem(item: ShieldDashboardItem) {
+ // Remove from deleted items
+ this.deletedItems.splice(this.deletedItems.indexOf(item), 1);
+
+ // Add back to dashboard
+ this.dashboard.push(item);
+ }
+
+ // Clear all deleted items
+ clearDeletedItems() {
+ this.deletedItems = [];
+ }
+
+ itemChange() {
+ console.log('Item changed:', this.dashboard);
+ }
+
+ itemResize(item: any, itemComponent: any) {
+ console.log('Item resized:', item);
+ // Trigger a window resize event to notify charts to resize
+ window.dispatchEvent(new Event('resize'));
+ }
+
+ /**
+ * Extract only the relevant chart configuration properties to pass to chart components
+ * This prevents errors when trying to set properties that don't exist on the components
+ */
+ getChartInputs(item: any): any {
+ // Only pass properties that are relevant to chart components
+ const chartInputs = {
+ chartType: item.chartType,
+ name: item.name
+ };
+
+ // Remove undefined properties to avoid passing unnecessary data
+ Object.keys(chartInputs).forEach(key => {
+ if (chartInputs[key] === undefined) {
+ delete chartInputs[key];
+ }
+ });
+
+ return chartInputs;
+ }
+}
\ No newline at end of file