/** * DashboardWidget Entity * Configuración de widgets de dashboard * * @module Reports * @table reports.dashboard_widgets */ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, Index, } from 'typeorm'; import { Tenant } from '../../core/entities/tenant.entity'; import { Dashboard } from './dashboard.entity'; export type WidgetType = | 'kpi_card' | 'line_chart' | 'bar_chart' | 'pie_chart' | 'donut_chart' | 'area_chart' | 'gauge' | 'table' | 'heatmap' | 'map' | 'timeline' | 'progress' | 'list' | 'text' | 'image' | 'custom'; export type DataSourceType = 'query' | 'api' | 'static' | 'kpi' | 'report'; @Entity({ schema: 'reports', name: 'dashboard_widgets' }) @Index(['tenantId']) @Index(['dashboardId']) @Index(['widgetType']) @Index(['isActive']) export class DashboardWidget { @PrimaryGeneratedColumn('uuid') id: string; @Column({ name: 'tenant_id', type: 'uuid' }) tenantId: string; @Column({ name: 'dashboard_id', type: 'uuid' }) dashboardId: string; @Column({ type: 'varchar', length: 200 }) title: string; @Column({ type: 'text', nullable: true }) subtitle: string | null; @Column({ name: 'widget_type', type: 'varchar', length: 30, }) widgetType: WidgetType; @Column({ name: 'data_source_type', type: 'varchar', length: 20, default: 'query', }) dataSourceType: DataSourceType; @Column({ name: 'data_source', type: 'jsonb', nullable: true, comment: 'Query, API endpoint, or KPI code', }) dataSource: Record | null; @Column({ type: 'jsonb', nullable: true, comment: 'Widget-specific configuration', }) config: Record | null; @Column({ type: 'jsonb', nullable: true, comment: 'Chart options (colors, legend, etc)', }) chartOptions: Record | null; @Column({ type: 'jsonb', nullable: true, comment: 'Threshold/alert configuration', }) thresholds: Record | null; @Column({ name: 'grid_x', type: 'integer', default: 0, comment: 'Grid position X', }) gridX: number; @Column({ name: 'grid_y', type: 'integer', default: 0, comment: 'Grid position Y', }) gridY: number; @Column({ name: 'grid_width', type: 'integer', default: 4, comment: 'Width in grid units', }) gridWidth: number; @Column({ name: 'grid_height', type: 'integer', default: 2, comment: 'Height in grid units', }) gridHeight: number; @Column({ name: 'min_width', type: 'integer', default: 2, }) minWidth: number; @Column({ name: 'min_height', type: 'integer', default: 1, }) minHeight: number; @Column({ name: 'refresh_interval', type: 'integer', nullable: true, comment: 'Override dashboard refresh (seconds)', }) refreshInterval: number | null; @Column({ name: 'cache_duration', type: 'integer', default: 60, comment: 'Cache duration in seconds', }) cacheDuration: number; @Column({ name: 'drill_down_config', type: 'jsonb', nullable: true, comment: 'Drill-down navigation config', }) drillDownConfig: Record | null; @Column({ name: 'click_action', type: 'jsonb', nullable: true, comment: 'Action on click (navigate, filter, etc)', }) clickAction: Record | null; @Column({ name: 'is_active', type: 'boolean', default: true, }) isActive: boolean; @Column({ name: 'sort_order', type: 'integer', default: 0, }) sortOrder: number; @CreateDateColumn({ name: 'created_at', type: 'timestamptz' }) createdAt: Date; @Column({ name: 'created_by', type: 'uuid', nullable: true }) createdById: string | null; @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', nullable: true }) updatedAt: Date | null; @Column({ name: 'updated_by', type: 'uuid', nullable: true }) updatedById: string | null; @Column({ name: 'deleted_at', type: 'timestamptz', nullable: true }) deletedAt: Date | null; // Relations @ManyToOne(() => Tenant) @JoinColumn({ name: 'tenant_id' }) tenant: Tenant; @ManyToOne(() => Dashboard) @JoinColumn({ name: 'dashboard_id' }) dashboard: Dashboard; }