This commit is contained in:
string 2025-10-25 17:55:46 +05:30
parent f24138cfbd
commit 02f37a1bc5
4 changed files with 243 additions and 162 deletions

View File

@ -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>
<!-- 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>
<!-- Donut Charts -->
<div class="grid-item">
<app-shield-donut-chart chartType="endCustomer"></app-shield-donut-chart>
</div>
<!-- Drag Handle -->
<button class="btn btn-icon drag-handler" style="margin-left: 10px; margin-top: 10px;">
<clr-icon shape="drag-handle"></clr-icon>
</button>
<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>
<!-- 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>

View File

@ -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;
.dashboard-container {
flex-direction: column;
}
.sidebar {
width: 100%;
padding: 15px;
}
.sidebar {
flex: 0 0 auto;
}
.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;
}
}
}
}
}
.kpi-section {
flex-direction: column;
}
}

View File

@ -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'));
}
}

View File

@ -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 { }