@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
1,208 lines (1,193 loc) • 171 kB
TypeScript
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