shield
This commit is contained in:
		
							parent
							
								
									f24138cfbd
								
							
						
					
					
						commit
						02f37a1bc5
					
				| @ -17,42 +17,46 @@ | ||||
|         </div> | ||||
|       </div> | ||||
|        | ||||
|       <!-- Charts and Components Grid --> | ||||
|       <div class="dashboard-grid"> | ||||
|         <!-- Bar Chart --> | ||||
|         <div class="grid-item"> | ||||
|           <app-shield-bar-chart></app-shield-bar-chart> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Donut Charts --> | ||||
|         <div class="grid-item"> | ||||
|           <app-shield-donut-chart chartType="endCustomer"></app-shield-donut-chart> | ||||
|         </div> | ||||
|          | ||||
|         <div class="grid-item"> | ||||
|           <app-shield-donut-chart chartType="segmentPenetration"></app-shield-donut-chart> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Map Section --> | ||||
|         <div class="grid-item map-container"> | ||||
|           <app-shield-map-chart></app-shield-map-chart> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Data Table --> | ||||
|         <div class="grid-item table-container"> | ||||
|           <app-shield-data-table></app-shield-data-table> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Deal Details Card --> | ||||
|         <div class="grid-item"> | ||||
|           <app-shield-deal-details-card></app-shield-deal-details-card> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Quarterwise Flow --> | ||||
|         <div class="grid-item"> | ||||
|           <app-shield-quarterwise-flow></app-shield-quarterwise-flow> | ||||
|         </div> | ||||
|       </div> | ||||
|       <!-- Dashboard Grid with Drag and Drop --> | ||||
|       <gridster [options]="options" style="background-color: transparent;"> | ||||
|         <gridster-item [item]="item" *ngFor="let item of dashboard"> | ||||
|           <!-- Remove Button --> | ||||
|           <button class="btn btn-icon btn-danger" style="margin-left: 10px; margin-top: 10px;" (click)="removeItem(item)"> | ||||
|             <clr-icon shape="trash"></clr-icon> | ||||
|           </button> | ||||
|            | ||||
|           <!-- Drag Handle --> | ||||
|           <button class="btn btn-icon drag-handler" style="margin-left: 10px; margin-top: 10px;"> | ||||
|             <clr-icon shape="drag-handle"></clr-icon> | ||||
|           </button> | ||||
|            | ||||
|           <!-- Chart Components --> | ||||
|           <div class="grid-item-content"> | ||||
|             <h4 style="margin-top: 0px; margin-left: 10px;">{{item.name}}</h4> | ||||
|             <div *ngIf="item.chartType === 'bar-chart'"> | ||||
|               <app-shield-bar-chart></app-shield-bar-chart> | ||||
|             </div> | ||||
|             <div *ngIf="item.chartType === 'donut-chart' && item.name === 'End Customer'"> | ||||
|               <app-shield-donut-chart chartType="endCustomer"></app-shield-donut-chart> | ||||
|             </div> | ||||
|             <div *ngIf="item.chartType === 'donut-chart' && item.name === 'Segment Penetration'"> | ||||
|               <app-shield-donut-chart chartType="segmentPenetration"></app-shield-donut-chart> | ||||
|             </div> | ||||
|             <div *ngIf="item.chartType === 'map-chart'"> | ||||
|               <app-shield-map-chart></app-shield-map-chart> | ||||
|             </div> | ||||
|             <div *ngIf="item.chartType === 'data-table'"> | ||||
|               <app-shield-data-table></app-shield-data-table> | ||||
|             </div> | ||||
|             <div *ngIf="item.chartType === 'deal-details'"> | ||||
|               <app-shield-deal-details-card></app-shield-deal-details-card> | ||||
|             </div> | ||||
|             <div *ngIf="item.chartType === 'quarterwise-flow'"> | ||||
|               <app-shield-quarterwise-flow></app-shield-quarterwise-flow> | ||||
|             </div> | ||||
|           </div> | ||||
|         </gridster-item> | ||||
|       </gridster> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| @ -1,134 +1,109 @@ | ||||
| .shield-dashboard { | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
|   background-color: #f5f7fa; | ||||
|   font-family: 'Inter', sans-serif; | ||||
|    | ||||
|   .dashboard-container { | ||||
|     display: flex; | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
|      | ||||
|     .sidebar { | ||||
|       width: 300px; | ||||
|       background: linear-gradient(135deg, #0a192f 0%, #172a45 100%); | ||||
|       color: white; | ||||
|       padding: 20px; | ||||
|       box-shadow: 3px 0 10px rgba(0, 0, 0, 0.1); | ||||
|       z-index: 10; | ||||
|       flex-shrink: 0; | ||||
|     } | ||||
|      | ||||
|     .main-content { | ||||
|       flex: 1; | ||||
|       padding: 20px; | ||||
|       overflow-y: auto; | ||||
|        | ||||
|       .kpi-section { | ||||
|         display: flex; | ||||
|         gap: 20px; | ||||
|         margin-bottom: 30px; | ||||
|          | ||||
|         .kpi-card { | ||||
|           flex: 1; | ||||
|           background: white; | ||||
|           border-radius: 12px; | ||||
|           padding: 20px; | ||||
|           box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); | ||||
|           text-align: center; | ||||
|            | ||||
|           .kpi-title { | ||||
|             font-size: 16px; | ||||
|             color: #64748b; | ||||
|             margin-bottom: 10px; | ||||
|           } | ||||
|            | ||||
|           .kpi-value { | ||||
|             font-size: 32px; | ||||
|             font-weight: 700; | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         .total-leads { | ||||
|           border-top: 4px solid #ff6b35; | ||||
|         } | ||||
|          | ||||
|         .total-deals { | ||||
|           border-top: 4px solid #0a192f; | ||||
|         } | ||||
|       } | ||||
|        | ||||
|       .dashboard-grid { | ||||
|         display: grid; | ||||
|         grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); | ||||
|         gap: 20px; | ||||
|          | ||||
|         .grid-item { | ||||
|           background: white; | ||||
|           border-radius: 12px; | ||||
|           padding: 20px; | ||||
|           box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); | ||||
|            | ||||
|           &.map-container { | ||||
|             grid-column: span 2; | ||||
|             min-height: 400px; | ||||
|           } | ||||
|            | ||||
|           &.table-container { | ||||
|             grid-column: span 2; | ||||
|             min-height: 300px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   padding: 20px; | ||||
|   background-color: #f5f5f5; | ||||
|   min-height: 100vh; | ||||
| } | ||||
| 
 | ||||
| // Responsive design | ||||
| @media (max-width: 1200px) { | ||||
|   .shield-dashboard { | ||||
|     .dashboard-container { | ||||
|       .sidebar { | ||||
|         width: 250px; | ||||
|       } | ||||
|        | ||||
|       .main-content { | ||||
|         .dashboard-grid { | ||||
|           grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| .dashboard-container { | ||||
|   display: flex; | ||||
|   gap: 20px; | ||||
| } | ||||
| 
 | ||||
| .sidebar { | ||||
|   flex: 0 0 250px; | ||||
|   background: white; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
|   padding: 15px; | ||||
| } | ||||
| 
 | ||||
| .main-content { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 20px; | ||||
| } | ||||
| 
 | ||||
| .kpi-section { | ||||
|   display: flex; | ||||
|   gap: 20px; | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
| 
 | ||||
| .kpi-card { | ||||
|   flex: 1; | ||||
|   background: white; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
|   padding: 20px; | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| .kpi-title { | ||||
|   font-size: 14px; | ||||
|   color: #666; | ||||
|   margin-bottom: 10px; | ||||
| } | ||||
| 
 | ||||
| .kpi-value { | ||||
|   font-size: 24px; | ||||
|   font-weight: bold; | ||||
|   color: #333; | ||||
| } | ||||
| 
 | ||||
| .total-leads { | ||||
|   border-top: 4px solid #4285f4; | ||||
| } | ||||
| 
 | ||||
| .total-deals { | ||||
|   border-top: 4px solid #0f9d58; | ||||
| } | ||||
| 
 | ||||
| .dashboard-grid { | ||||
|   display: grid; | ||||
|   grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); | ||||
|   gap: 20px; | ||||
| } | ||||
| 
 | ||||
| .grid-item { | ||||
|   background: white; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
|   padding: 15px; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .grid-item-content { | ||||
|   margin-top: 30px; | ||||
| } | ||||
| 
 | ||||
| .drag-handler { | ||||
|   cursor: move; | ||||
| } | ||||
| 
 | ||||
| /* Gridster specific styles */ | ||||
| gridster { | ||||
|   background: transparent !important; | ||||
| } | ||||
| 
 | ||||
| gridster-item { | ||||
|   background: white; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
|   overflow: hidden; | ||||
| } | ||||
| 
 | ||||
| /* Responsive design */ | ||||
| @media (max-width: 768px) { | ||||
|   .shield-dashboard { | ||||
|     .dashboard-container { | ||||
|       flex-direction: column; | ||||
|        | ||||
|       .sidebar { | ||||
|         width: 100%; | ||||
|         padding: 15px; | ||||
|       } | ||||
|        | ||||
|       .main-content { | ||||
|         padding: 15px; | ||||
|          | ||||
|         .kpi-section { | ||||
|           flex-direction: column; | ||||
|           gap: 15px; | ||||
|         } | ||||
|          | ||||
|         .dashboard-grid { | ||||
|           grid-template-columns: 1fr; | ||||
|            | ||||
|           .grid-item { | ||||
|             &.map-container, &.table-container { | ||||
|               grid-column: span 1; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   .dashboard-container { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|    | ||||
|   .sidebar { | ||||
|     flex: 0 0 auto; | ||||
|   } | ||||
|    | ||||
|   .kpi-section { | ||||
|     flex-direction: column; | ||||
|   } | ||||
| } | ||||
| @ -1,4 +1,11 @@ | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { GridsterConfig, GridsterItem } from 'angular-gridster2'; | ||||
| 
 | ||||
| interface ShieldDashboardItem extends GridsterItem { | ||||
|   chartType: string; | ||||
|   name: string; | ||||
|   id: number; | ||||
| } | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'app-shield-dashboard', | ||||
| @ -6,10 +13,62 @@ import { Component, OnInit } from '@angular/core'; | ||||
|   styleUrls: ['./shield-dashboard.component.scss'] | ||||
| }) | ||||
| export class ShieldDashboardComponent implements OnInit { | ||||
|   options: GridsterConfig; | ||||
|   dashboard: Array<ShieldDashboardItem>; | ||||
| 
 | ||||
|   constructor() { } | ||||
| 
 | ||||
|   ngOnInit(): void { | ||||
|     this.options = { | ||||
|       gridType: 'fit', | ||||
|       enableEmptyCellDrop: true, | ||||
|       emptyCellDropCallback: this.onDrop.bind(this), | ||||
|       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 default components
 | ||||
|     this.dashboard = [ | ||||
|       { cols: 5, rows: 6, y: 0, x: 0, chartType: 'bar-chart', name: 'Bar Chart', id: 1 }, | ||||
|       { cols: 5, rows: 6, y: 0, x: 5, chartType: 'donut-chart', name: 'End Customer', id: 2 }, | ||||
|       { cols: 5, rows: 6, y: 6, x: 0, chartType: 'donut-chart', name: 'Segment Penetration', id: 3 }, | ||||
|       { cols: 5, rows: 6, y: 6, x: 5, chartType: 'map-chart', name: 'Map Chart', id: 4 }, | ||||
|       { cols: 10, rows: 6, y: 12, x: 0, chartType: 'data-table', name: 'Data Table', id: 5 }, | ||||
|       { cols: 5, rows: 6, y: 18, x: 0, chartType: 'deal-details', name: 'Deal Details', id: 6 }, | ||||
|       { cols: 5, rows: 6, y: 18, x: 5, chartType: 'quarterwise-flow', name: 'Quarterwise Flow', id: 7 } | ||||
|     ]; | ||||
|   } | ||||
| 
 | ||||
|   onDrop(event: any) { | ||||
|     // Handle dropping new components onto the dashboard
 | ||||
|     console.log('Item dropped:', event); | ||||
|   } | ||||
| 
 | ||||
|   removeItem(item: ShieldDashboardItem) { | ||||
|     this.dashboard.splice(this.dashboard.indexOf(item), 1); | ||||
|   } | ||||
| 
 | ||||
|   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')); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,43 @@ | ||||
| import { NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core'; | ||||
| import { CommonModule } from '@angular/common'; | ||||
| import { FormsModule } from '@angular/forms'; | ||||
| import { ClarityModule } from '@clr/angular'; | ||||
| import { GridsterModule } from 'angular-gridster2'; | ||||
| import { NgChartsModule } from 'ng2-charts'; | ||||
| import { DynamicModule } from 'ng-dynamic-component'; | ||||
| 
 | ||||
| import { ShieldDashboardRoutingModule } from './shield-dashboard-routing.module'; | ||||
| import { ShieldDashboardComponent } from './shield-dashboard.component'; | ||||
| import { SidebarFiltersComponent } from './components/sidebar-filters/sidebar-filters.component'; | ||||
| import { BarChartComponent } from './components/bar-chart/bar-chart.component'; | ||||
| import { DonutChartComponent } from './components/donut-chart/donut-chart.component'; | ||||
| import { MapChartComponent } from './components/map-chart/map-chart.component'; | ||||
| import { DataTableComponent } from './components/data-table/data-table.component'; | ||||
| import { DealDetailsCardComponent } from './components/deal-details-card/deal-details-card.component'; | ||||
| import { QuarterwiseFlowComponent } from './components/quarterwise-flow/quarterwise-flow.component'; | ||||
| import { LoadingShimmerComponent } from './components/loading-shimmer/loading-shimmer.component'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|   declarations: [ | ||||
|     ShieldDashboardComponent, | ||||
|     SidebarFiltersComponent, | ||||
|     BarChartComponent, | ||||
|     DonutChartComponent, | ||||
|     MapChartComponent, | ||||
|     DataTableComponent, | ||||
|     DealDetailsCardComponent, | ||||
|     QuarterwiseFlowComponent, | ||||
|     LoadingShimmerComponent | ||||
|   ], | ||||
|   imports: [ | ||||
|     CommonModule, | ||||
|     FormsModule, | ||||
|     ClarityModule, | ||||
|     GridsterModule, | ||||
|     NgChartsModule, | ||||
|     DynamicModule, | ||||
|     ShieldDashboardRoutingModule | ||||
|   ], | ||||
|   schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA] | ||||
| }) | ||||
| export class ShieldDashboardModule { } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user