import * as _dragonworks_ngx_dashboard from '@dragonworks/ngx-dashboard'; import * as _angular_core from '@angular/core'; import { Type, ViewContainerRef, ComponentRef, OnChanges, SimpleChanges, InjectionToken } from '@angular/core'; import * as _ngrx_signals from '@ngrx/signals'; import { SafeHtml } from '@angular/platform-browser'; declare const NGX_DASHBOARD_VERSION = "22.1.0"; /** * Branded type for cell identifiers to ensure type safety when working with grid coordinates. * This prevents accidentally mixing up row/column numbers with cell IDs. */ type CellId = number & { __brand: 'CellId'; }; /** * Branded type for widget identifiers to ensure type safety when working with widget instances. * This prevents accidentally mixing up widget IDs with other string values. */ type WidgetId = string & { __brand: 'WidgetId'; }; interface Widget { dashboardGetState?(): unknown; dashboardSetState?(state?: unknown): void; dashboardEditState?(): void; dashboardEditSharedState?(): void; } interface WidgetMetadata { widgetTypeid: string; name: string; description: string; svgIcon: string; } interface WidgetComponentClass extends Type { metadata: WidgetMetadata; } interface WidgetFactory { widgetTypeid: string; name: string; description: string; svgIcon: string; createInstance(container: ViewContainerRef, state?: unknown): ComponentRef; } interface CellPosition { row: number; col: number; rowSpan: number; colSpan: number; } interface CellComponentPosition extends CellPosition { cellId: CellId; widgetId: WidgetId; } interface CellData extends CellPosition { widgetId: WidgetId; cellId: CellId; flat?: boolean; widgetTypeid?: string; widgetFactory: WidgetFactory; widgetState: unknown; } /** * Data structure for cell display settings */ interface CellDisplayData { id: string; flat: boolean | undefined; } /** * Serializable data format for dashboard export/import functionality. * This format can be safely converted to/from JSON for persistence. * Corresponds to the persistent state from the dashboard store features. */ interface DashboardDataDto { /** Version for future compatibility and migration support */ version: string; /** * Unique dashboard identifier managed by the client. * Set once when a dashboard is first mounted via `[dashboardData]`. * On subsequent imperative `loadDashboard()` calls this field is treated * as informational metadata (i.e. where the file came from) — the store's * existing id is preserved so that bridge registration stays stable and * Export→Import across dashboards works without rewriting the id. */ dashboardId: string; /** Grid dimensions */ rows: number; columns: number; gutterSize: string; /** Array of serializable cell data */ cells: CellDataDto[]; /** * Shared states for widget families (optional). * Maps widget type ID to shared state object. * This allows widget families to share configuration across all instances. * @since 1.1.0 */ sharedStates?: Record; } /** * Serializable version of CellData that can be safely JSON stringified. * Converts non-serializable types (CellId, WidgetFactory) to serializable equivalents. */ interface CellDataDto { /** Grid position */ row: number; col: number; /** Cell span */ rowSpan: number; colSpan: number; /** Display settings */ flat?: boolean; /** Widget type identifier for factory lookup during import */ widgetTypeid: string; /** Raw widget state (must be JSON serializable) */ widgetState: unknown; } /** * Creates an empty dashboard configuration with the specified dimensions. * This is a convenience function for creating a basic dashboard without any cells. * * @param dashboardId - Unique identifier for the dashboard (managed by client) * @param rows - Number of rows in the dashboard grid * @param columns - Number of columns in the dashboard grid * @param gutterSize - CSS size for the gutter between cells (default: '0.5em') * @returns A DashboardDataDto configured with the specified dimensions and no cells * * @example * // Create an 8x16 dashboard with default gutter * const dashboard = createEmptyDashboard('my-dashboard-1', 8, 16); * * @example * // Create a 5x10 dashboard with custom gutter * const dashboard = createEmptyDashboard('my-dashboard-2', 5, 10, '0.5rem'); */ declare function createEmptyDashboard(dashboardId: string, rows: number, columns: number, gutterSize?: string): DashboardDataDto; /** * Creates a default dashboard configuration with standard dimensions. * This provides a reasonable starting point for most use cases. * * @param dashboardId - Unique identifier for the dashboard (managed by client) * @returns A DashboardDataDto with 8 rows, 16 columns, and 0.5em gutter * * @example * const dashboard = createDefaultDashboard('my-dashboard-id'); */ declare function createDefaultDashboard(dashboardId: string): DashboardDataDto; type DragData = { kind: 'cell'; content: CellComponentPosition; } | { kind: 'widget'; content: WidgetMetadata; }; /** * Represents a rectangular selection region in the dashboard grid */ interface GridSelection { topLeft: { row: number; col: number; }; bottomRight: { row: number; col: number; }; } /** * Outcome of a grid resize request (e.g. `DashboardComponent.setGridSize()` * or an editor drag-handle commit). * * The dashboard uses a clamp-to-content policy: a requested size that would * push an existing widget outside the grid is snapped up to the smallest size * that still contains every widget's full footprint. The fields below report * the size that was actually applied, not the size that was requested. */ interface GridResizeResult { /** Rows actually applied after clamp-to-content. */ rows: number; /** Columns actually applied after clamp-to-content. */ columns: number; /** True when the requested size was clamped up to keep widgets in bounds. */ clamped: boolean; } /** * Defines space that should be reserved around the dashboard component * when calculating viewport constraints. */ interface ReservedSpace { /** Space reserved at the top (e.g., toolbar height) */ top: number; /** Space reserved on the right (e.g., padding, widget list) */ right: number; /** Space reserved at the bottom (e.g., padding) */ bottom: number; /** Space reserved on the left (e.g., padding) */ left: number; } /** * Options for filtering and exporting a selection of the dashboard. * * Used when exporting a subset of the dashboard based on a grid selection. * Provides control over how the selection bounds are calculated and applied. */ interface SelectionFilterOptions { /** * If true, shrink the export bounds to the minimal bounding box containing all widgets. * If false or undefined (default), use the selection bounds as-is. * * When enabled, the exported dashboard will be tightly cropped to only include * the space occupied by widgets, removing any empty cells around the edges. * * @default false * * @example * ```typescript * // Export with minimal bounds (tight crop around widgets) * const data = dashboard.exportDashboard(selection, { useMinimalBounds: true }); * * // Export with full selection bounds (preserve empty space) * const data = dashboard.exportDashboard(selection, { useMinimalBounds: false }); * ``` */ useMinimalBounds?: boolean; /** * Number of cells to add as padding on each side of the export bounds. * * Padding expands the export area by adding empty cells around the selection. * A padding value of 1 adds 1 row above, 1 row below, 1 column to the left, * and 1 column to the right of the bounds. * * When used with `useMinimalBounds: true`, padding is applied AFTER the bounds * are shrunk to the minimal bounding box containing all widgets. * * The minimum row and column values are clamped to 1 (grid coordinates are 1-based), * so padding will not extend below the grid origin. * * @default 0 * * @example * ```typescript * // Export with 1 cell of padding on all sides * const data = dashboard.exportDashboard(selection, { padding: 1 }); * * // Export with minimal bounds and 2 cells of padding * const data = dashboard.exportDashboard(selection, { * useMinimalBounds: true, * padding: 2 * }); * ``` */ padding?: number; } /** * Keyboard modifier that gates drag-to-select. * * When set on `DashboardComponent.selectionModifier`, the selection overlay * is mounted but transparent to pointer events until the modifier is held * (or a drag started while the modifier was held is in progress). */ type SelectionModifier = 'shift' | 'ctrl' | 'alt' | 'meta'; /** * Interface for providing shared state across all instances of a widget type. * * Widget families can implement this interface to manage state that should be * shared across all instances of that widget type (e.g., theme colors, configuration). * * During dashboard serialization, the framework calls getSharedState() once per * widget type (not per instance), and during deserialization, setSharedState() * is called to restore the shared configuration. * * @example * ```typescript * @Injectable({ providedIn: 'root' }) * export class ParkingSpaceSharedState implements WidgetSharedStateProvider { * private state = signal({ color: '#4CAF50', pricePerHour: 5 }); * * getSharedState(): ParkingConfig { * return this.state(); * } * * setSharedState(state: ParkingConfig): void { * this.state.set(state); * } * * readonly config = this.state.asReadonly(); * } * * // Register with dashboard * dashboardService.registerWidgetType(ParkingSpaceWidget, ParkingSpaceSharedState); * ``` */ interface WidgetSharedStateProvider { /** * Gets the current shared state for this widget type. * Called during dashboard export/serialization. * * @returns The current shared state, or undefined if no state should be serialized */ getSharedState(): T | undefined; /** * Sets the shared state for this widget type. * Called during dashboard import/deserialization before widget instances are created. * * @param state The shared state to restore */ setSharedState(state: T): void; } interface ResizeData { cellId: CellId; originalRowSpan: number; originalColSpan: number; previewRowSpan: number; previewColSpan: number; } interface ViewportSize { width: number; height: number; } interface DashboardConstraints { maxWidth: number; maxHeight: number; constrainedBy: 'width' | 'height' | 'none'; } /** * Internal component-scoped service that provides viewport-aware constraints for a single dashboard. * Each dashboard component gets its own instance of this service. * * This service is NOT part of the public API and should remain internal to the library. */ declare class DashboardViewportService { private readonly platformId; private readonly destroyRef; private readonly store; private readonly viewportSize; private readonly reservedSpace; private resizeObserver; constructor(); /** * Initialize viewport size tracking using ResizeObserver on the window */ private initializeViewportTracking; /** * Set reserved space that should be excluded from dashboard calculations * (e.g., toolbar height, widget list width, padding) */ setReservedSpace(space: ReservedSpace): void; /** * Get current viewport size */ readonly currentViewportSize: _angular_core.Signal; /** * Get current reserved space */ readonly currentReservedSpace: _angular_core.Signal; /** * Calculate available space for dashboard after accounting for reserved areas */ readonly availableSpace: _angular_core.Signal; /** * Calculate dashboard constraints for this dashboard instance */ readonly constraints: _angular_core.Signal; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } declare class DashboardComponent implements OnChanges { #private; protected readonly store: { dashboardId: _angular_core.Signal; rows: _angular_core.Signal; columns: _angular_core.Signal; gutterSize: _angular_core.Signal; isEditMode: _angular_core.Signal; gridCellDimensions: _ngrx_signals.DeepSignal<{ width: number; height: number; }>; widgetsById: _angular_core.Signal>; resizeData: _angular_core.Signal; gridResizePreview: _angular_core.Signal; dragData: _angular_core.Signal; hoveredDropZone: _angular_core.Signal<{ row: number; col: number; } | null>; dashboardService: _dragonworks_ngx_dashboard.DashboardService; cells: _angular_core.Signal; isDragActive: _angular_core.Signal; highlightedZones: _angular_core.Signal<{ row: number; col: number; }[]>; highlightMap: _angular_core.Signal>; effectiveRows: _angular_core.Signal; effectiveColumns: _angular_core.Signal; invalidHighlightMap: _angular_core.Signal>; isValidPlacement: _angular_core.Signal; resizePreviewCells: _angular_core.Signal<{ row: number; col: number; }[]>; resizePreviewMap: _angular_core.Signal>; setGridConfig: (config: { rows?: number; columns?: number; gutterSize?: string; }) => void; setGridCellDimensions: (width: number, height: number) => void; toggleEditMode: () => void; setEditMode: (isEditMode: boolean) => void; addWidget: (cell: CellData) => void; removeWidget: (widgetId: WidgetId) => void; updateWidgetPosition: (widgetId: WidgetId, row: number, col: number) => void; createWidget: (row: number, col: number, widgetFactory: WidgetFactory, widgetState?: string) => void; updateCellSettings: (widgetId: WidgetId, flat: boolean) => void; updateWidgetSpan: (widgetId: WidgetId, rowSpan: number, colSpan: number) => void; updateWidgetState: (widgetId: WidgetId, widgetState: unknown) => void; updateAllWidgetStates: (cellStates: Map) => void; clearDashboard: () => void; clearGridResizePreview: () => void; startDrag: (dragData: DragData) => void; endDrag: () => void; setHoveredDropZone: (zone: { row: number; col: number; } | null) => void; handleDrop: (dragData: DragData, targetPosition: { row: number; col: number; }) => boolean; startResize: (cellId: CellId) => void; updateResizePreview: (direction: "horizontal" | "vertical", delta: number) => void; endResize: (apply: boolean) => void; setGridSize: (rows: number, columns: number) => GridResizeResult; previewGridResize: (deltaRows: number, deltaColumns: number) => void; exportDashboard: (getCurrentWidgetStates?: () => Map, selection?: GridSelection, selectionOptions?: SelectionFilterOptions) => DashboardDataDto; loadDashboard: (data: DashboardDataDto) => void; endGridResize: (deltaRows: number, deltaColumns: number) => GridResizeResult | null; } & _ngrx_signals.StateSource<{ dashboardId: string; rows: number; columns: number; gutterSize: string; isEditMode: boolean; gridCellDimensions: { width: number; height: number; }; widgetsById: Record; resizeData: ResizeData | null; gridResizePreview: GridResizeResult | null; dragData: DragData | null; hoveredDropZone: { row: number; col: number; } | null; }>; protected readonly viewport: DashboardViewportService; dashboardData: _angular_core.InputSignal; editMode: _angular_core.InputSignal; reservedSpace: _angular_core.InputSignal; enableSelection: _angular_core.InputSignal; selectionModifier: _angular_core.InputSignal; dragThreshold: _angular_core.InputSignal; selectionComplete: _angular_core.OutputEmitterRef; gridResized: _angular_core.OutputEmitterRef; cells: _angular_core.Signal; private dashboardEditor; private dashboardViewer; constructor(); ngOnChanges(changes: SimpleChanges): void; /** * Get current widget states from all cell components. * Used during dashboard export to get live widget states. */ private getCurrentWidgetStates; exportDashboard(): DashboardDataDto; exportDashboard(selection: GridSelection, options?: SelectionFilterOptions): DashboardDataDto; loadDashboard(data: DashboardDataDto): void; getCurrentDashboardData(): DashboardDataDto; clearDashboard(): void; /** * Resize the dashboard grid to the given row/column counts. * * Uses a clamp-to-content policy: a size that would push an existing widget * out of bounds is snapped up to the smallest size that still contains every * widget, so shrinking never orphans a widget. The applied size (which may * differ from the request when clamped) is returned and emitted via * `gridResized`. Values below 1 are treated as 1; fractional values are * floored. */ setGridSize(rows: number, columns: number): GridResizeResult; /** * Forwards to the active viewer. No-op in edit mode. * See `DashboardViewerComponent.clearSelection()`. */ clearSelection(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } interface WidgetDisplayItem extends WidgetMetadata { safeSvgIcon?: SafeHtml; } declare class WidgetListComponent { #private; collapsed: _angular_core.InputSignal; activeWidget: _angular_core.WritableSignal; gridCellDimensions: _angular_core.Signal<{ width: number; height: number; }>; widgets: _angular_core.Signal<{ safeSvgIcon: SafeHtml; widgetTypeid: string; name: string; description: string; svgIcon: string; }[]>; onDragStart(event: DragEvent, widget: WidgetDisplayItem): void; onDragEnd(): void; getWidgetAriaLabel(widget: WidgetDisplayItem): string; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵcmp: _angular_core.ɵɵComponentDeclaration; } declare class DashboardService { #private; readonly widgetTypes: _angular_core.Signal[]>; registerWidgetType(widget: WidgetComponentClass, sharedStateProvider?: WidgetSharedStateProvider | Type>): void; getFactory(widgetTypeid: string): WidgetFactory; /** * Get the shared state provider for a specific widget type. * * @param widgetTypeid The widget type identifier * @returns The shared state provider, or undefined if none is registered */ getSharedStateProvider(widgetTypeid: string): WidgetSharedStateProvider | undefined; /** * Collect shared states for all widget types currently on the dashboard. * Called during dashboard export/serialization. * * @param activeWidgetTypes Set of widget type IDs that are currently in use * @returns Map of widget type IDs to their shared states */ collectSharedStates(activeWidgetTypes: Set): Map; /** * Restore shared states for widget types. * Called during dashboard import/deserialization, before widget instances are created. * * @param states Map of widget type IDs to their shared states */ restoreSharedStates(states: Map): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Abstract provider for cell settings dialogs. * Implement this to provide custom dialog solutions. */ declare abstract class CellSettingsDialogProvider { /** * Open a settings dialog for the given cell. * Returns a promise that resolves to the new settings, or undefined if cancelled. */ abstract openCellSettings(data: CellDisplayData): Promise; } /** * Injection token for the cell dialog provider. * Use this to provide your custom dialog implementation. * * @example * ```typescript * providers: [ * { provide: CELL_SETTINGS_DIALOG_PROVIDER, useClass: MyCellSettingsDialogProvider } * ] * ``` */ declare const CELL_SETTINGS_DIALOG_PROVIDER: InjectionToken; /** * Default cell dialog provider that uses Material Design dialogs. * Provides a modern, accessible dialog experience for cell settings. */ declare class DefaultCellSettingsDialogProvider extends CellSettingsDialogProvider { private dialog; openCellSettings(data: CellDisplayData): Promise; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Context information about the empty cell that was clicked */ interface EmptyCellContext { /** The row position in the grid (1-indexed) */ row: number; /** The column position in the grid (1-indexed) */ col: number; /** Total number of rows in the dashboard */ totalRows: number; /** Total number of columns in the dashboard */ totalColumns: number; /** The gutter size between cells (e.g., '1em') */ gutterSize: string; /** * Optional callback to create a widget at this position. * When provided, allows the context provider to create widgets directly. * * @param widgetTypeid - The widget type identifier to create * @returns true if widget was created successfully, false otherwise */ createWidget?: (widgetTypeid: string) => boolean; } /** * Abstract provider for handling context menu events on empty dashboard cells. * Implement this to provide custom behavior when users right-click on unoccupied grid spaces. * * @example * ```typescript * @Injectable() * export class CustomEmptyCellProvider extends EmptyCellContextProvider { * handleEmptyCellContext(event: MouseEvent, context: EmptyCellContext): void { * event.preventDefault(); * // Show custom menu, open dialog, etc. * } * } * ``` */ declare abstract class EmptyCellContextProvider { /** * Handle context menu event on an empty dashboard cell. * * @param event - The mouse event from the right-click * @param context - Information about the empty cell and dashboard */ abstract handleEmptyCellContext(event: MouseEvent, context: EmptyCellContext): void; } /** * Injection token for the empty cell context provider. * Use this to provide your custom implementation for handling right-clicks on empty dashboard cells. * * @example * ```typescript * // Provide a custom implementation * providers: [ * { * provide: EMPTY_CELL_CONTEXT_PROVIDER, * useClass: MyCustomEmptyCellProvider * } * ] * ``` */ declare const EMPTY_CELL_CONTEXT_PROVIDER: InjectionToken; /** * Default empty cell context provider that prevents the browser's context menu * and performs no other action. * * This is the default behavior that allows users to right-click on empty dashboard * cells without triggering the browser's default context menu. */ declare class DefaultEmptyCellContextProvider extends EmptyCellContextProvider { /** * Default empty cell context handler. * The browser context menu is already prevented by the component. * No additional action is taken by default. */ handleEmptyCellContext(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } /** * Context provider that displays a widget list menu when right-clicking on empty cells. * * This provider shows a Material Design context menu with all available widget types. * When a user clicks on a widget in the menu, it's immediately added to the empty cell. * * @example * ```typescript * // In your component or app config * providers: [ * { * provide: EMPTY_CELL_CONTEXT_PROVIDER, * useClass: WidgetListContextMenuProvider * } * ] * ``` * * @public */ declare class WidgetListContextMenuProvider extends EmptyCellContextProvider { #private; /** * Handle empty cell context menu by showing available widgets. * * @param event - The mouse event from the right-click * @param context - Information about the empty cell and dashboard */ handleEmptyCellContext(event: MouseEvent, context: EmptyCellContext): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵprov: _angular_core.ɵɵInjectableDeclaration; } export { CELL_SETTINGS_DIALOG_PROVIDER, CellSettingsDialogProvider, DashboardComponent, DashboardService, DefaultCellSettingsDialogProvider, DefaultEmptyCellContextProvider, EMPTY_CELL_CONTEXT_PROVIDER, EmptyCellContextProvider, NGX_DASHBOARD_VERSION, WidgetListComponent, WidgetListContextMenuProvider, createDefaultDashboard, createEmptyDashboard }; export type { CellDataDto, DashboardDataDto, EmptyCellContext, GridResizeResult, GridSelection, ReservedSpace, SelectionFilterOptions, SelectionModifier, Widget, WidgetMetadata, WidgetSharedStateProvider };