UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

1,208 lines (1,193 loc) 171 kB
import { aggregationType } from '@c8y/client'; import * as _angular_core from '@angular/core'; import { AfterViewInit, OnInit, OnDestroy, EventEmitter, TemplateRef, WritableSignal } from '@angular/core'; import { ViewContext, ActionBarItem, ActionBarFactory, DashboardChildComponent, CountdownIntervalComponent, TabWithTemplate } from '@c8y/ngx-components'; import { Observable, BehaviorSubject } from 'rxjs'; import * as packages_client_lib from 'packages/client/lib'; import * as _angular_forms from '@angular/forms'; import { FormGroup, ControlValueAccessor, FormControl } from '@angular/forms'; import * as _c8y_ngx_components_global_context from '@c8y/ngx-components/global-context'; import { ActivatedRoute } from '@angular/router'; import { BsDropdownDirective } from 'ngx-bootstrap/dropdown'; declare const REFRESH_OPTION: { readonly LIVE: "live"; readonly HISTORY: "history"; }; type RefreshOption = (typeof REFRESH_OPTION)[keyof typeof REFRESH_OPTION]; /** * Define the mapping between GlobalContextState keys and their equivalent in GlobalContextSettings */ declare const LINK_BTNS_CONFIG: { [K in Extract<keyof GlobalContextState, 'dateTimeContext' | 'aggregation' | 'isAutoRefreshEnabled'>]: { /** Form control name, same as global state key */ formControlName: K; /** Setting key in GlobalContextSettings */ settingKey: keyof GlobalContextSettings; /** User-friendly label for UI */ label: string; /** Css Class for link button visualization */ cssClass: string; icon: string; }; }; /** * Type for link toggle event */ interface LinkToggleEvent { key: Extract<keyof GlobalContextState, 'dateTimeContext' | 'aggregation' | 'isAutoRefreshEnabled'>; isLinked: boolean; } /** * Type for link states map */ type LinkStatesMap = Partial<Record<Extract<keyof GlobalContextState, 'dateTimeContext' | 'aggregation' | 'isAutoRefreshEnabled'>, boolean>>; /** * Type for control configs map */ type ControlConfigsMap = Partial<Record<Extract<keyof GlobalContextState, 'dateTimeContext' | 'aggregation' | 'isAutoRefreshEnabled'>, { cssClass?: string; linkTooltip?: string; unlinkTooltip?: string; icon?: string; disabled?: boolean; disabledTooltip?: string; autoUnlinked?: boolean; }>>; declare const TIME_SPAN_MS: { readonly MINUTE: number; readonly HOUR: number; readonly DAY: number; readonly WEEK: number; readonly MONTH: number; }; declare const TIME_INTERVAL: { readonly NONE: "none"; readonly MINUTES: "minutes"; readonly HOURS: "hours"; readonly DAYS: "days"; readonly WEEKS: "weeks"; readonly MONTHS: "months"; readonly CUSTOM: "custom"; }; type TimeInterval = (typeof TIME_INTERVAL)[keyof typeof TIME_INTERVAL]; type Interval = { id: 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'custom' | string; title: string; timespanInMs?: number; }; type AlarmFilterInterval = Interval | { id: 'none'; title: string; timespanInMs?: number; }; declare const INTERVALS: Interval[]; declare const INTERVAL_TITLES: Record<AlarmFilterInterval['id'], string>; interface DateTimeContext { dateFrom: Date | string; dateTo: Date | string; interval: TimeInterval; } interface DateTimeContextPickerConfig { showDateFrom?: boolean; showDateTo?: boolean; } declare const GLOBAL_CONTEXT_EVENTS: { readonly STATE_CHANGE: "GLOBAL_CONTEXT_STATE_CHANGE"; readonly REFRESH: "REFRESH"; readonly REFRESH_OPTION_CHANGE: "GLOBAL_CONTEXT_REFRESH_OPTION_CHANGE"; readonly UPDATE_GLOBAL_CONTEXT_LIVE: "UPDATE_GLOBAL_CONTEXT_LIVE"; readonly UPDATE_GLOBAL_CONTEXT_HISTORY: "UPDATE_GLOBAL_CONTEXT_HISTORY"; readonly INIT_GLOBAL_CONTEXT: "INIT_GLOBAL_CONTEXT"; }; declare enum GLOBAL_CONTEXT_DISPLAY_MODE { DASHBOARD = "dashboard", CONFIG = "config", VIEW_AND_CONFIG = "view_and_config" } type GlobalContextKeys = (keyof GlobalContextState)[]; /** * State object passed to widget state handlers */ interface WidgetState { config?: GlobalContextState; inlineControlSettings?: Partial<GlobalContextSettings>; dashboardControlSettings?: Partial<GlobalContextSettings>; currentLinks?: LinkStatesMap; displayMode?: string; [key: string]: unknown; } /** * Result returned from widget state handlers */ interface WidgetStateHandlerResult { inlineControlSettings: Partial<GlobalContextSettings>; dashboardControlSettings?: Partial<GlobalContextSettings>; links?: Partial<LinkStatesMap>; options?: { noAutoRefreshCounter?: boolean; }; } interface WidgetControls { supports: GlobalContextKeys; supportedModes?: RefreshOption[]; options?: { noAutoRefreshCounter?: boolean; }; configSettings: { [mode in GLOBAL_CONTEXT_DISPLAY_MODE]?: { [option in RefreshOption]?: Partial<GlobalContextSettings>; }; }; settings: { [mode in GLOBAL_CONTEXT_DISPLAY_MODE]?: { [option in RefreshOption]?: Partial<GlobalContextSettings>; }; }; defaultLinks?: { [mode in GLOBAL_CONTEXT_DISPLAY_MODE]?: { [option in RefreshOption]?: LinkStatesMap; }; }; stateHandlers?: { [stateName: string]: (widgetState?: WidgetState) => WidgetStateHandlerResult; }; } /** Settings to control which features are visible in the global context UI */ interface GlobalContextSettings { showTimeContext: boolean; showAggregation: boolean; showAutoRefresh: boolean; showRefresh: boolean; showRefreshInterval: boolean; } /** Base interface for all global context events */ interface GlobalContextEventBase<Type extends string, Payload> { type: Type; payload: Payload; timestamp?: number; } /** * Registry of all available global context events and their payloads * * Extend with new events by declaring module augmentation: * interface GlobalContextEventRegistry { * NEW_EVENT: boolean; // Add your event payload type * } */ interface GlobalContextEventRegistry { [GLOBAL_CONTEXT_EVENTS.REFRESH]: { dateFrom?: string | Date; dateTo?: string | Date; interval?: TimeInterval; }; [GLOBAL_CONTEXT_EVENTS.STATE_CHANGE]: Partial<GlobalContextState>; [GLOBAL_CONTEXT_EVENTS.REFRESH_OPTION_CHANGE]: RefreshOption; [GLOBAL_CONTEXT_EVENTS.UPDATE_GLOBAL_CONTEXT_LIVE]: Partial<GlobalContextState>; [GLOBAL_CONTEXT_EVENTS.UPDATE_GLOBAL_CONTEXT_HISTORY]: Partial<GlobalContextState>; [GLOBAL_CONTEXT_EVENTS.INIT_GLOBAL_CONTEXT]: void; } /** Union of all possible event type strings */ type GlobalContextEventType = keyof GlobalContextEventRegistry; /** Union type of all possible global context events */ type GlobalContextEventUnion = { [K in GlobalContextEventType]: GlobalContextEventBase<K, GlobalContextEventRegistry[K]>; }[GlobalContextEventType]; declare enum DateContextQueryParamNames { DATE_CONTEXT_FROM = "dateContextFrom", DATE_CONTEXT_TO = "dateContextTo", DATE_CONTEXT_INTERVAL = "dateContextInterval", DATE_CONTEXT_AGGREGATION = "dateContextAggregation", DATE_CONTEXT_AUTO_REFRESH = "globalContextAutoRefresh", DATE_CONTEXT_REFRESH_MODE = "globalContextRefreshMode" } type DateContextFromToQueryParams = { [DateContextQueryParamNames.DATE_CONTEXT_FROM]: string; [DateContextQueryParamNames.DATE_CONTEXT_TO]: string; [DateContextQueryParamNames.DATE_CONTEXT_INTERVAL]?: never; }; type DateContextIntervalQueryParams = { [DateContextQueryParamNames.DATE_CONTEXT_FROM]?: never; [DateContextQueryParamNames.DATE_CONTEXT_TO]?: never; [DateContextQueryParamNames.DATE_CONTEXT_INTERVAL]: Interval['id']; }; /** * Input query params is an object representing all possible query params related to widget time context. * It can be provided by user typing them in browser URL address bar, so all of them should be considered. */ type InputDateContextQueryParams = { [DateContextQueryParamNames.DATE_CONTEXT_FROM]?: string; [DateContextQueryParamNames.DATE_CONTEXT_TO]?: string; [DateContextQueryParamNames.DATE_CONTEXT_INTERVAL]?: Interval['id']; [DateContextQueryParamNames.DATE_CONTEXT_AGGREGATION]?: aggregationType; [DateContextQueryParamNames.DATE_CONTEXT_AUTO_REFRESH]?: boolean; [DateContextQueryParamNames.DATE_CONTEXT_REFRESH_MODE]?: string; }; /** * Output query params is an object representing params that are applied to current URL in browser address bar. * These params are set programmatically. * Time context interval and time range described by date "from" and date "to" exclude each other. */ type OutputDateContextQueryParams = (DateContextFromToQueryParams | DateContextIntervalQueryParams) & { [DateContextQueryParamNames.DATE_CONTEXT_AGGREGATION]: aggregationType; }; type GlobalContextDisplayMode = `${GLOBAL_CONTEXT_DISPLAY_MODE}`; declare const GLOBAL_CONTEXT_SOURCE: { readonly WIDGET: "widget"; readonly DASHBOARD: "dashboard"; }; type GlobalContextSource = (typeof GLOBAL_CONTEXT_SOURCE)[keyof typeof GLOBAL_CONTEXT_SOURCE]; interface GlobalContextState { dateTimeContext?: DateTimeContext; aggregation?: aggregationType | null; isAutoRefreshEnabled?: boolean; refreshInterval?: number; refreshOption?: RefreshOption; displayMode?: `${GLOBAL_CONTEXT_DISPLAY_MODE}`; source?: GlobalContextSource; eventSourceId?: string; /** * Flag indicating global context values have been applied. * For dashboard mode, widgets should wait for this flag before processing config. */ isGlobalContextReady?: boolean; } /** * Interface for date context parameters passed to setDateContextQueryParams method. * Provides strong typing for all possible parameters. */ interface DateContextParams { /** Time interval ID ('DAYS', 'HOURS', etc.) or 'custom' for date ranges */ interval?: Interval['id']; /** Array containing [dateFrom, dateTo] strings or Date objects for custom date ranges */ date?: (string | Date)[] | null; /** Data aggregation type ('HOURLY', 'DAILY', etc.) */ aggregation?: aggregationType; /** Whether auto-refresh should be enabled */ isAutoRefreshEnabled?: boolean; /** Refresh mode ('live' or 'history') */ refreshOption?: RefreshOption; } /** * Result type for query parameter validation status. * Provides detailed validation information for debugging and UI state management. */ interface ParameterValidationStatus { /** True if interval parameter is valid and selectable */ interval: boolean; /** True if aggregation parameter is valid */ aggregation: boolean; /** True if both dateFrom and dateTo form a valid date range */ dateRange: boolean; /** Parsed boolean value, or undefined if invalid/missing */ autoRefresh: boolean | undefined; } declare const WIDGET_DISPLAY_MODE: { readonly INLINE: "inline"; readonly CONFIG: "config"; readonly PREVIEW: "preview"; }; type WidgetDisplayMode = (typeof WIDGET_DISPLAY_MODE)[keyof typeof WIDGET_DISPLAY_MODE]; interface GlobalContextEvent { context: Partial<GlobalContextState>; diff: Partial<GlobalContextState>; } /** * Default values for global context configuration * Single source of truth for all default values across the global context feature */ declare const GLOBAL_CONTEXT_DEFAULTS: { /** Default refresh option - live mode */ readonly REFRESH_OPTION: "live"; /** Default auto-refresh state */ readonly IS_AUTO_REFRESH_ENABLED: true; /** Default refresh interval in milliseconds (5 seconds) */ readonly REFRESH_INTERVAL: 5000; /** Default aggregation type */ readonly AGGREGATION: any; /** Default display mode */ readonly DISPLAY_MODE: GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD; /** Default date range duration in milliseconds (1 hour) */ readonly DATE_RANGE_DURATION_MS: number; /** Default time interval for custom ranges */ readonly TIME_INTERVAL: "hours"; }; type Aggregation = { id: aggregationType | null; title: string; }; declare const AGGREGATIONS: Aggregation[]; declare const AGGREGATION_LIMITS: { MINUTELY_LIMIT: number; HOURLY_LIMIT: number; DAILY_LIMIT: number; }; declare const AGGREGATION_ICON_TYPE: { readonly UNDEFINED: "line-chart"; readonly MINUTELY: "hourglass"; readonly HOURLY: "clock-o"; readonly DAILY: "calendar-o"; }; type AggregationIconType = (typeof AGGREGATION_ICON_TYPE)[keyof typeof AGGREGATION_ICON_TYPE]; declare const AGGREGATION_ICONS: Record<aggregationType | 'undefined', AggregationIconType>; declare const AGGREGATION_TEXTS: Record<aggregationType | 'undefined' | 'null' | 'disabled', string>; declare const AGGREGATION_VALUES: { readonly none: "NONE"; readonly minutely: aggregationType.MINUTELY; readonly hourly: aggregationType.HOURLY; readonly daily: aggregationType.DAILY; }; declare const AGGREGATION_VALUES_ARR: readonly ["NONE", aggregationType.MINUTELY, aggregationType.HOURLY, aggregationType.DAILY]; declare const AGGREGATION_LABELS: { readonly NONE: string; readonly MINUTELY: string; readonly HOURLY: string; readonly DAILY: string; }; /** * Represents the available aggregation options. * Aggregation 'none' is not handled by our backend. */ type AggregationOption = typeof AGGREGATION_VALUES.none | `${aggregationType}`; /** * Represents the status of aggregation options. * Used to determine which aggregation options should be disabled. */ type AggregationOptionStatus = { [key in AggregationOption]?: boolean; }; interface AggregationState { aggregationType: aggregationType; isDisabled: boolean; } /** * Configuration interface for context selector component */ interface ContextConfig { context: 'dashboard' | 'widget'; showInWidget: boolean; } /** * Time duration constants (ms) */ declare const TIME_DURATION: { /** One hour in milliseconds */ readonly ONE_HOUR_MS: number; /** One minute in milliseconds */ readonly ONE_MINUTE_MS: number; /** One second in milliseconds */ readonly ONE_SECOND_MS: 1000; }; /** * Timing constants for debouncing and throttling */ declare const TIMING: { /** Debounce time for form value changes (ms) */ readonly FORM_DEBOUNCE: 100; /** Throttle time for context changes (ms) */ readonly CONTEXT_THROTTLE: 200; /** Tooltip delay time (ms) */ readonly TOOLTIP_DELAY: 500; /** Default debounce time (ms) */ readonly DEFAULT_DEBOUNCE: 100; }; /** * UI priority constants */ declare const UI_PRIORITIES: { /** High priority for configuration controls */ readonly CONFIGURATION_PRIORITY: 1000; }; /** * Interface representing a registered widget's global context settings with its unique identifier. */ interface RegisteredGlobalContextSettings extends Partial<GlobalContextSettings> { /** Unique identifier for the widget that registered these settings */ readonly id: string; } /** * GlobalContextService manages widget settings registration and loading states. * * This service is responsible for: * - Registering and managing widget-specific global context settings * - Consolidating settings from multiple widgets using OR logic * - Tracking loading states across multiple widgets * - Providing default configurations for the global context * * @example * ```typescript * // Register widget settings * globalContextService.register('widget-1', { showTimeContext: true }); * * // Get consolidated settings from all widgets * globalContextService.getConsolidatedSettings().subscribe(settings => { * console.log(settings); // { showTimeContext: true, ... } * }); * * // Track loading state * globalContextService.registerLoading('widget-1'); * console.log(globalContextService.isLoading()); // true * ``` */ declare class GlobalContextService { /** * Computed signal that indicates if any widgets are currently in a loading state. * Returns true if at least one widget has registered a loading state. */ readonly isLoading: _angular_core.Signal<boolean>; /** Target context for the global context service */ protected readonly targetContext: ViewContext.Device | ViewContext.Group; /** Observable stream of all registered widget settings */ private readonly settings$; /** Signal storing unique identifiers of widgets currently in loading state */ private readonly loadingIds; /** * Registers global context settings for a specific widget. * If settings for the same widget ID already exist, they will be updated. * * @param id - Unique identifier for the widget * @param settings - Partial global context settings to register * * @throws {Error} When id is empty or null * * @example * ```typescript * globalContextService.register('my-widget', { * showTimeContext: true, * showAutoRefresh: false * }); * ``` */ register(id: string, settings: Partial<GlobalContextSettings>): void; /** * Retrieves all currently registered widget settings. * * @returns Array of all registered settings with their widget IDs */ getSettings(): readonly RegisteredGlobalContextSettings[]; /** * Removes all registered widget settings. * This will cause the consolidated settings to return to default values. */ resetSettings(): void; /** * Unregisters settings for a specific widget. * * @param id - Unique identifier of the widget to unregister * * @example * ```typescript * globalContextService.unregister('my-widget'); * ``` */ unregister(id: string): void; /** * Returns an observable of consolidated global context settings. * * Settings are consolidated using OR logic - if any widget requires a setting to be shown, * it will be included in the consolidated result. The observable emits distinct values only * and is shared among all subscribers for optimal performance. * * @returns Observable that emits consolidated settings whenever they change * * @example * ```typescript * globalContextService.getConsolidatedSettings().subscribe(settings => { * if (settings.showTimeContext) { * // Show time context controls * } * }); * ``` */ getConsolidatedSettings(): Observable<GlobalContextSettings>; /** * Returns the default global context settings. * These settings are used when no widgets have registered any settings. * * @returns Default settings object with all options disabled */ getDefaultSettings(): GlobalContextSettings; /** * Registers a loading state for a specific widget. * This will cause the `isLoading` computed signal to return true. * * @param id - Unique identifier of the widget in loading state * * @example * ```typescript * globalContextService.registerLoading('my-widget'); * console.log(globalContextService.isLoading()); // true * ``` */ registerLoading(id: string): void; /** * Unregisters a loading state for a specific widget. * When no widgets are in loading state, `isLoading` will return false. * * @param id - Unique identifier of the widget to remove from loading state * * @example * ```typescript * globalContextService.unregisterLoading('my-widget'); * ``` */ unregisterLoading(id: string): void; /** * Returns the default global context state. * This state is used as the initial configuration for new global context instances. * * @returns Default global context state with live refresh enabled and 1-minute time range * * @example * ```typescript * const defaultState = globalContextService.getDefaultState(); * console.log(defaultState.refreshOption); // 'live' * ``` */ getDefaultState(): GlobalContextState; /** * Validates that a widget ID is not empty or null. * * @param id - Widget ID to validate * @throws {Error} When ID is invalid */ private validateWidgetId; /** * Finds the index of settings for a given widget ID. * * @param id - Widget ID to search for * @param settings - Array of settings to search in * @returns Index of the settings or -1 if not found */ private findSettingsIndex; /** * Updates existing settings for a widget. * * @param index - Index of the settings to update * @param newSettings - New settings to apply * @param currentSettings - Current settings array */ private updateExistingSettings; /** * Adds new settings to the settings array. * * @param newSettings - Settings to add * @param currentSettings - Current settings array */ private addNewSettings; /** * Consolidates multiple widget settings using OR logic. * * @param settingsArray - Array of widget settings to consolidate * @returns Consolidated settings object */ private consolidateSettings; /** * Compares two settings objects for deep equality. * * @param prev - Previous settings * @param curr - Current settings * @returns True if settings are equal, false otherwise */ private areSettingsEqual; static ɵfac: _angular_core.ɵɵFactoryDeclaration<GlobalContextService, never>; static ɵprov: _angular_core.ɵɵInjectableDeclaration<GlobalContextService>; } /** * Service responsible for building and managing form groups for global context configuration. */ declare class GlobalContextFormService { private readonly fb; /** * Creates a FormGroup for global context configuration. * @param config Optional existing configuration to initialize form values * @param defaults Optional override values for specific controls * @returns A fully configured FormGroup */ buildForm(config?: Partial<GlobalContextState>, defaults?: Partial<GlobalContextState>, skipProp?: Array<keyof GlobalContextState>): FormGroup<{ dateTimeContext?: _angular_forms.FormControl<_c8y_ngx_components_global_context.DateTimeContext>; aggregation?: _angular_forms.FormControl<packages_client_lib.aggregationType>; isAutoRefreshEnabled?: _angular_forms.FormControl<boolean>; refreshInterval?: _angular_forms.FormControl<number>; refreshOption?: _angular_forms.FormControl<_c8y_ngx_components_global_context.RefreshOption>; displayMode?: _angular_forms.FormControl<"dashboard" | "config" | "view_and_config">; source?: _angular_forms.FormControl<GlobalContextSource>; eventSourceId?: _angular_forms.FormControl<string>; isGlobalContextReady?: _angular_forms.FormControl<boolean>; }>; /** * Extracts form values into a configuration object * @param form The form to extract values from * @returns GlobalContextConfig object */ getConfigFromForm(form: FormGroup): GlobalContextState; /** * Gets the default values for the global context form */ getDefaultValues(): GlobalContextState; /** * Merges default values with config and explicit overrides */ private mergeValues; static ɵfac: _angular_core.ɵɵFactoryDeclaration<GlobalContextFormService, never>; static ɵprov: _angular_core.ɵɵInjectableDeclaration<GlobalContextFormService>; } /** * GlobalContextEventService manages global context events using the browser's native event system. * * This service provides a type-safe wrapper around window custom events for global context communication. * It maintains event subjects for efficient observable-based event handling while ensuring proper * cleanup and memory management. * * Key features: * - Type-safe event emission and subscription * - Latest value caching for each event type * - Memory-efficient subject management * - Integration with browser's native event system * * @example * ```typescript * // Emit an event * eventService.emit('GLOBAL_CONTEXT_STATE_CHANGE', { * refreshOption: 'live', * isAutoRefreshEnabled: true * }); * * // Subscribe to events * eventService.on('GLOBAL_CONTEXT_STATE_CHANGE').subscribe(state => { * console.log('State changed:', state); * }); * * // Get the latest value * const latestState = eventService.getLatestValue('GLOBAL_CONTEXT_STATE_CHANGE'); * ``` */ declare class GlobalContextEventService { /** Map storing BehaviorSubjects for each event type to cache latest values */ private readonly eventSubjects; /** Observable stream of all global context events from the window */ private readonly events$; /** * Emits a global context event with type-safe payload. * * The event is both stored locally for latest value retrieval and dispatched * as a browser custom event for cross-component communication. * * @param type - The specific event type to emit (must be a valid GlobalContextEventType) * @param payload - Type-safe payload matching the event type requirements * * @throws {Error} When event type is invalid or payload validation fails * * @example * ```typescript * // Emit a state change event * eventService.emit('GLOBAL_CONTEXT_STATE_CHANGE', { * refreshOption: 'live', * isAutoRefreshEnabled: true * }); * * // Emit a refresh event * eventService.emit('GLOBAL_CONTEXT_REFRESH', { * dateFrom: '2024-01-01', * dateTo: '2024-01-02' * }); * ``` */ emit<T extends GlobalContextEventType>(type: T, payload?: GlobalContextEventRegistry[T]): void; /** * Creates an observable that emits whenever a specific event type occurs. * * The observable filters the global event stream to only emit events of the specified type. * This provides efficient, reactive event handling without manual event listener management. * * @param eventType - The specific event type to observe * @returns Observable that emits payloads of the specified event type * * @throws {Error} When event type is invalid * * @example * ```typescript * // Subscribe to state changes * eventService.on('GLOBAL_CONTEXT_STATE_CHANGE') * .pipe(takeUntilDestroyed()) * .subscribe(state => { * console.log('New state:', state); * }); * * // Subscribe to refresh events with filtering * eventService.on('GLOBAL_CONTEXT_REFRESH') * .pipe( * filter(data => data?.interval === 'MINUTES'), * takeUntilDestroyed() * ) * .subscribe(refreshData => { * console.log('Minute-based refresh:', refreshData); * }); * ``` */ on<T extends GlobalContextEventType>(eventType: T): Observable<GlobalContextEventRegistry[T]>; /** * Retrieves the most recently emitted value for a specific event type. * * This method provides synchronous access to the latest event data without * requiring a subscription. Returns null if no event of the specified type * has been emitted yet. * * @param eventType - The event type to retrieve the latest value for * @returns The latest emitted value or null if none exists * * @throws {Error} When event type is invalid * * @example * ```typescript * // Get the current state * const currentState = eventService.getLatestValue('GLOBAL_CONTEXT_STATE_CHANGE'); * if (currentState) { * console.log('Current refresh option:', currentState.refreshOption); * } * * // Check for latest refresh data * const refreshData = eventService.getLatestValue('GLOBAL_CONTEXT_REFRESH'); * if (refreshData?.dateFrom) { * console.log('Last refresh from:', refreshData.dateFrom); * } * ``` */ getLatestValue<T extends GlobalContextEventType>(eventType: T): GlobalContextEventRegistry[T] | null; /** * Synchronizes dateTimeContext from REFRESH event to STATE_CHANGE event. * * This method ensures that when a REFRESH event contains dateTimeContext data, * it updates the STATE_CHANGE event subject's value directly without emitting a new event. * This keeps the internal state synchronized without triggering listeners. * * @param refreshDateTimeContext - The dateTimeContext from the REFRESH event to sync * * @example * ```typescript * // When a refresh occurs with new dateTimeContext * const refreshData = { dateFrom: '2024-01-01', dateTo: '2024-01-02', interval: 'HOURLY' }; * eventService.emit(GLOBAL_CONTEXT_EVENTS.REFRESH, refreshData); * * // Sync it to STATE_CHANGE internal state * eventService.syncRefreshToStateChange(refreshData); * ``` */ syncRefreshToStateChange(refreshDateTimeContext?: GlobalContextEventRegistry[typeof GLOBAL_CONTEXT_EVENTS.REFRESH]): void; /** * Validates that an event type is not empty or invalid. * * @param eventType - The event type to validate * @throws {Error} When event type is invalid */ private validateEventType; /** * Dispatches a browser custom event for cross-component communication. * * @param type - Event type * @param payload - Event payload */ private dispatchBrowserEvent; /** * Gets or creates a BehaviorSubject for a specific event type. * Implements memory management by limiting the number of cached subjects. * * @param type - The event type * @returns BehaviorSubject for the event type */ private getOrCreateEventSubject; /** * Ensures the event subject cache doesn't exceed the maximum limit. * Removes the oldest subjects when limit is reached. */ private ensureSubjectCacheLimit; static ɵfac: _angular_core.ɵɵFactoryDeclaration<GlobalContextEventService, never>; static ɵprov: _angular_core.ɵɵInjectableDeclaration<GlobalContextEventService>; } /** * Standard result interface for all widget settings operations. * Used consistently across resolution, toggle, and configuration methods. */ interface WidgetSettingsResult { /** Settings for inline (widget-level) controls (new naming) */ settings: Partial<GlobalContextSettings>; /** Link states determining dashboard vs inline control visibility */ links: LinkStatesMap; /** Settings for dashboard-level controls (new naming) */ dashboardControls: Partial<GlobalContextSettings>; } /** * Service responsible for managing widget-level control settings and their interaction * with dashboard-level controls. Handles the resolution of settings based on display mode, * link states, and refresh options. * * Key responsibilities: * - Widget settings resolution for different display modes * - Link state management between inline and dashboard controls * - Dashboard control calculations based on link states * - Settings toggle operations for individual and bulk link changes */ declare class WidgetControlService { /** * Resolves widget settings for inline controls based on the specified mode and refresh option. * For dashboard mode, calculates the split between inline and dashboard controls. * * @param controls - Widget control configuration containing settings and links * @param mode - Display mode determining which settings to use * @param refreshOption - Refresh mode (live/history) for settings selection * @returns Resolved settings with inline controls, links, and dashboard controls */ resolveInlineControlSettings(controls: WidgetControls, mode: GlobalContextDisplayMode, refreshOption: RefreshOption): WidgetSettingsResult; /** * Resolves widget settings for configuration controls based on the specified mode and refresh option. * Configuration controls are simpler and don't require dashboard control calculations. * * @param controls - Widget control configuration containing config settings * @param mode - Display mode determining which config settings to use * @param refreshOption - Refresh mode (live/history) for settings selection * @returns Resolved configuration settings with empty links and dashboard controls */ resolveConfigControlSettings(controls: WidgetControls, mode: GlobalContextDisplayMode, refreshOption: RefreshOption): WidgetSettingsResult; /** * Extracts inline settings from widget controls for the specified display mode and refresh option. * Applies fallback logic for invalid refresh options, defaulting to LIVE mode. * * @param controls - Widget control configuration * @param displayMode - Display mode (dashboard, config, view_and_config) * @param refreshOption - Refresh mode, may be invalid and will fallback to LIVE * @returns Inline settings for the specified mode and refresh option */ getInlineSettingsFromWidgetControls(controls: WidgetControls, displayMode: GlobalContextDisplayMode, refreshOption: RefreshOption | string): Partial<GlobalContextSettings>; /** * Extracts configuration settings from widget controls for the specified display mode and refresh option. * Applies fallback logic for invalid refresh options, defaulting to LIVE mode. * * @param controls - Widget control configuration * @param displayMode - Display mode (dashboard, config, view_and_config) * @param refreshOption - Refresh mode, may be invalid and will fallback to LIVE * @returns Configuration settings for the specified mode and refresh option */ getConfigSettingsFromWidgetControls(controls: WidgetControls, displayMode: GlobalContextDisplayMode, refreshOption: RefreshOption | string): Partial<GlobalContextSettings>; /** * Extracts default link states from widget controls for the specified display mode and refresh option. * Applies fallback logic for invalid refresh options, defaulting to LIVE mode. * * @param controls - Widget control configuration * @param displayMode - Display mode (dashboard, config, view_and_config) * @param refreshOption - Refresh mode, may be invalid and will fallback to LIVE * @returns Default link states for the specified mode and refresh option */ getDefaultLinksFromControls(controls: WidgetControls, displayMode: GlobalContextDisplayMode, refreshOption: RefreshOption | string): LinkStatesMap; /** * Toggles a single link state and recalculates the resulting settings and dashboard controls. * When a link is toggled, it affects how controls are distributed between inline and dashboard. * * @param linkKey - The key of the link to toggle * @param currentSettings - Current inline control settings * @param currentLinks - Current link states * @returns Updated settings with toggled link and recalculated dashboard controls */ toggleControlLink(linkKey: string, currentSettings: Partial<GlobalContextSettings>, currentLinks: LinkStatesMap): WidgetSettingsResult; /** * Sets all link states to the specified value and recalculates the resulting settings. * This is used for bulk operations like "link all" or "unlink all" controls. * * @param state - The state to set for all links (true = linked, false = unlinked) * @param currentSettings - Current inline control settings * @param currentLinks - Current link states * @returns Updated settings with all links set to the specified state */ toggleAllControlLinks(state: boolean, currentSettings: Partial<GlobalContextSettings>, currentLinks: LinkStatesMap): WidgetSettingsResult; /** * Validates and normalizes a refresh option, providing fallback to LIVE for invalid values. * Handles type coercion and validates against the REFRESH_OPTION enum. * * @param refreshOption - Refresh option to validate (may be string or RefreshOption) * @returns Valid RefreshOption, defaulting to LIVE for invalid inputs */ private validateRefreshOption; /** * Calculates how settings should be split between dashboard and inline controls based on link states. * When a control is linked (true), it appears on the dashboard. When unlinked (false), it appears inline. * This method implements the core business logic for the dashboard/inline control relationship. * * @param settings - Base settings to split between dashboard and inline * @param links - Link states determining where each control should appear * @returns Object containing settings for both inline and dashboard controls */ private calculateDashboardSettings; static ɵfac: _angular_core.ɵɵFactoryDeclaration<WidgetControlService, never>; static ɵprov: _angular_core.ɵɵInjectableDeclaration<WidgetControlService>; } declare class DateTimeContextPickerService { /** * Calculates date time context according to provided interval. * * @param intervalId - Interval id indicating time range * @returns Tuple of [dateFrom, dateTo] where dateTo is current time, or null if interval is invalid * * @example * ```typescript * // Returns [epoch, current date] for 'none' interval * service.getDateTimeContextByInterval('none'); * * // Returns [1 hour ago, now] for 'hours' interval * service.getDateTimeContextByInterval('hours'); * * // Returns null for invalid intervals * service.getDateTimeContextByInterval('invalid'); // null * ``` */ getDateTimeContextByInterval(intervalId: TimeInterval): [Date, Date] | null; /** * Validates provided param for being selectable Interval id. * @param intervalId Interval id to be validated. * @returns True if provided id is valid, selectable Interval id and false if it's not. */ isSelectableInterval(intervalId: Interval['id']): boolean; /** * Validates provided date "from" and date "to": * - if both dates are proper date strings/values * - if provided date from is earlier than date to. * @param stringifiedDateFrom Date "from" that should be validated. * @param stringifiedDateTo Date "to" that should be validated. * @returns Result of validation of dates range. */ isValidDateRange(stringifiedDateFrom: string, stringifiedDateTo: string): boolean; /** * Validates provided aggregation type. * @param aggregation Aggregation type to be validated. * @returns Result of validation of aggregation. */ isValidAggregation(aggregation: aggregationType | null): boolean; static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateTimeContextPickerService, never>; static ɵprov: _angular_core.ɵɵInjectableDeclaration<DateTimeContextPickerService>; } /** * Legacy widget configuration interface representing the various formats used in older widgets. * * This interface captures all possible legacy configuration properties that need to be migrated * to the new GlobalContextState format. Legacy widgets could store these properties at different * nesting levels (root, config, or mapConfig) with varying naming conventions. * * Note: The field 'canDecoupleGlobalTimeContext' was intentionally excluded from migration logic. * This field was used in legacy configurations but is no longer relevant for the new Global Context system. */ interface LegacyWidgetConfig { /** * Widget capability declarations from widget definitions. * These indicate which global context features the widget supports, * but don't represent the actual configuration values. */ displaySettings?: { /** Whether widget supports global time context feature */ globalTimeContext?: boolean; /** Whether widget supports auto-refresh feature */ globalAutoRefreshContext?: boolean; /** Whether widget supports realtime updates */ globalRealtimeContext?: boolean; /** Whether widget supports data aggregation */ globalAggregationContext?: boolean; }; /** * Actual widget instance configuration determining which features are active. * These take precedence over displaySettings when determining migration behavior. */ /** Whether this widget instance uses global time context */ widgetInstanceGlobalTimeContext?: boolean; /** Whether this widget instance uses global auto-refresh */ widgetInstanceGlobalAutoRefreshContext?: boolean; /** @deprecated Deprecated field not used in migration */ canDecoupleGlobalTimeContext?: boolean; /** Whether to display date selection controls in the widget */ displayDateSelection?: boolean; /** Legacy time configuration properties (multiple formats supported) */ /** Date range as array [from, to] - used by some widgets */ dateFilter?: string[] | [string, string]; /** Date range as array [from, to] - alternative legacy format */ date?: string[] | [string, string]; /** Start date as ISO string */ dateFrom?: string; /** End date as ISO string */ dateTo?: string; /** Time interval identifier (e.g., 'hours', 'days', 'none') */ interval?: string; /** Legacy refresh configuration properties */ /** Legacy refresh mode ('interval', 'global-interval', 'none') */ refreshOption?: string; /** Whether auto-refresh is enabled */ isAutoRefreshEnabled?: boolean; /** Refresh interval in milliseconds */ refreshInterval?: number; /** Whether widget is in realtime mode */ isRealtime?: boolean; /** Alternative realtime flag used by some widgets */ realtime?: boolean; /** * Nested configuration objects where widgets might store their settings. * The migration service checks these nested levels to ensure all configuration is captured. */ /** Map widget specific configuration */ mapConfig?: Record<string, unknown>; /** Generic nested configuration */ config?: Record<string, unknown>; } declare class WidgetConfigMigrationService { private dateTimeContextPickerService; constructor(dateTimeContextPickerService: DateTimeContextPickerService); /** * Transforms legacy widget configurations into the standardized GlobalContextState format. * * This migration handles the transition from various legacy configuration formats to the new * unified global context system. It detects which properties need updating and * preserves configurations that are already in the correct format. * * **What is migrated:** * - `displayMode`: Derived from widgetInstanceGlobalTimeContext/AutoRefreshContext flags * - `dateTimeContext`: Normalized from dateFilter, date, dateFrom/dateTo, or interval fields * - `refreshOption`: Converted from legacy 'interval'/'global-interval'/'none' values to LIVE/HISTORY * - `isAutoRefreshEnabled` + `refreshInterval`: Determined from realtime flags and legacy settings * - `aggregation`: Normalized from legacy 'NONE' string to null * * * **Use case:** * Call this on every widget configuration before rendering to ensure compatibility with * the global context system, regardless of when the widget was created or last saved. * * @param config - Widget configuration object that may contain legacy or new format properties. * Can be any object type, but should contain widget configuration fields. * @returns Configuration with all required GlobalContextState properties, either migrated from * legacy format or preserved if already valid. Returns input unchanged if null/undefined. * * @example * ```ts * // Legacy config with old format * const legacyConfig = { * widgetInstanceGlobalTimeContext: true, * dateFrom: '2024-01-01', * dateTo: '2024-01-02', * refreshOption: 'interval' * }; * * // After migration * const migrated = migrationService.migrateWidgetConfig(legacyConfig); * // { * // displayMode: 'dashboard', * // dateTimeContext: { dateFrom: '2024-01-01T00:00:00.000Z', dateTo: '2024-01-02T00:00:00.000Z', interval: 'custom' }, * // refreshOption: 'live', * // isAutoRefreshEnabled: true, * // refreshInterval: 60000, * // aggregation: null * // } * ``` */ migrateWidgetConfig<T extends object = object>(config: T): Partial<GlobalContextState>; /** * Creates a flattened configuration by excluding nested configuration objects. * * Legacy widgets often stored settings in nested objects like `mapConfig` or `config`. * This method creates a copy of the configuration without these nested objects to prevent * duplication in the migrated output - the nested values are extracted and merged separately * by extractGlobalContextSettings(). * * @param config - The raw widget configuration potentially containing nested objects * @returns Flattened configuration without mapConfig and config properties * */ private createFlatConfig; /** * Applies or migrates all global context properties to ensure complete configuration. * * This method implements a selective migration strategy: * - Checks which properties are missing or invalid in the current config * - Migrates only the properties that need updating * - Forces full migration when config has NO global context properties at all * * The method ensures that all widgets end up with valid displayMode, dateTimeContext, * refreshOption/isAutoRefreshEnabled/refreshInterval, and aggregation settings. * * @param config - The configuration object to modify (mutated in place) * @param mergedSettings - Combined settings from all config levels used for migration decisions * */ private applyGlobalContextProperties; /** * Determines if a configuration completely lacks global context properties. * * Used to detect widgets that have never been configured for global context integration. * When true, the migration applies full default configuration rather than selective updates. * * @param config - The configuration to check * @returns true if all global context properties are missing or undefined * */ private hasNoGlobalContextProperties; /** * Applies refresh settings as a cohesive unit to ensure consistency. * * The three refresh properties (refreshOption, isAutoRefreshEnabled, refreshInterval) are * interdependent and must be migrated together to avoid inconsistent states: * - refreshOption determines the mode (LIVE vs HISTORY) * - isAutoRefreshEnabled controls whether auto-refresh is active * - refreshInterval sets the refresh frequency in milliseconds * * Special handling: * - Realtime widgets get LIVE mode with 5-second interval * - Legacy refreshOption values are normalized to LIVE or HISTORY * - Nested config refreshInterval values are prioritized * * @param config - The configuration object to update (mutated in place) * @param mergedSettings - Combined settings from all levels for migration decisions * */ private applyRefreshSettings; /** * Determines the appropriate display mode based on legacy widget configuration. * * Display mode controls how the widget integrates with global context: * - DASHBOARD: Fully controlled by dashboard-level global context * - CONFIG: Widget manages its own settings independently * - VIEW_AND_CONFIG: Widget shows inline controls and can configure itself * * Decision logic priority: * 1. displayDateSelection=true → VIEW_AND_CONFIG (explicit request for date controls) * 2. Both time and refresh are global → DASHBOARD (full integration) * 3. One global, one local → VIEW_AND_CONFIG (partial integration) * 4. One setting defined → DASHBOARD (assume global by default) * 5. Both undefined → CONFIG (widget manages itself) * * @param settings - Merged settings from all config levels * @returns The appropriate display mode for the widget * */ private resolveDisplayMode; /** * Builds date/time context from various legacy configuration formats. * * Legacy widgets stored time configuration in many different ways. This method * normalizes all formats into the new DateTimeContext structure with consistent * ISO date strings and proper interval classification. * * Resolution priority: * 1. interval='none' → Always epoch (1970) to now with CUSTOM interval * 2. Predefined intervals (hours, days, etc.) → Calculate fresh dates based on interval * 3. Legacy date fields → Use provided dates with calculated/custom interval * 4. Widget needs time context → Apply default (last hour) * 5. Fallback → Last hour with HOURS interval * * Special cases: * - interval='none' always means "all data" regardless of other date fields * - Predefined intervals recalculate dates to be relative to current time * - Custom date ranges preserve the exact dates provided * * @param settings - Merged settings from all config levels * @returns Complete DateTimeContext with ISO dates and interval * */ private resolveDateTimeContext; /** * Resolves the refresh option (LIVE or HISTORY) from legacy configuration. * * Maps legacy refresh option values to the new binary system: * - 'interval' or 'global-interval' → LIVE (auto-refresh enabled) * - 'none' → HISTORY (no auto-refresh) * - Realtime widgets with