@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
731 lines (721 loc) • 27.7 kB
TypeScript
import * as i0 from '@angular/core';
import { Injector, Type, TemplateRef, ElementRef, ViewContainerRef, OnInit, OnChanges, OnDestroy, EventEmitter, SimpleChanges, InjectionToken } from '@angular/core';
import * as _c8y_client from '@c8y/client';
import { IManagedObject, IAlarm, IEvent } from '@c8y/client';
import { Observable } from 'rxjs';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { CdkTree } from '@angular/cdk/tree';
import { DataSource } from '@angular/cdk/collections';
import { BottomDrawerRef, GenericHookType, GenericHookOptions, ExtensionPointForPlugins, PluginsResolveService } from '@c8y/ngx-components';
import { Router } from '@angular/router';
interface ComputedPropertyContextMap {
device: {
type: 'device';
value: IManagedObject;
};
group: {
type: 'group';
value: IManagedObject;
};
asset: {
type: 'asset';
value: IManagedObject;
};
alarm: {
type: 'alarm';
value: IAlarm;
};
event: {
type: 'event';
value: IEvent;
};
}
type ValueCallbackMetadata = {
/**
* Mode of operation:
* - 'singleValue': Get count only once (no real-time updates)
* - 'realtime': Enable real-time updates (default)
*/
mode?: 'singleValue' | 'realtime';
/**
* Observable to control real-time updates when mode is 'realtime'.
* - true: Enable real-time updates (fetches current count from server and continues)
* - false: Disable real-time updates (preserves current count, no server call)
* If not provided, real-time runs continuously.
*/
realtimeControl$?: Observable<boolean>;
};
type ComputedPropertyContextType = keyof ComputedPropertyContextMap;
type ComputedPropertyContextValue = ComputedPropertyContextMap[keyof ComputedPropertyContextMap]['value'];
type ComputedPropertyDefinitionBase<TContext extends readonly ComputedPropertyContextType[] = ComputedPropertyContextType[], TConfig = any> = {
name: string;
prop: BaseProperty;
contextType: TContext;
value: ({ config, context, metadata }: {
config?: TConfig;
context?: ComputedPropertyContextMap[TContext[number]]['value'];
metadata?: ValueCallbackMetadata;
}) => any | Observable<any> | Promise<any>;
injector?: Injector;
};
type ComputedPropertyDefinition<TContext extends readonly ComputedPropertyContextType[] = ComputedPropertyContextType[], TConfig = any> = ComputedPropertyDefinitionBase<TContext, TConfig> & ({
configComponent?: never;
loadConfigComponent?: never;
} | {
configComponent: Type<any>;
loadConfigComponent?: never;
} | {
configComponent?: never;
loadConfigComponent: () => Promise<Type<any>>;
});
type ComputedPropertyComponent = {
/**
* The configuration which is shared between configuration component and display component.
* Should be serializable to allow saving it to the API.
*/
config: unknown;
/**
* The asset, device, group, alarm or event for which the property is displayed.
*/
asset?: IManagedObject;
};
type AssetPropertyListConfig = {
/**
* List of properties that should be selected by default when the asset property list is loaded.
*/
selectedProperties?: AssetPropertyType[];
/**
* Flag to enable or disable the filter functionality in the asset property list.
* When enabled, a search input will be displayed to filter properties by their names.
*/
filterable?: boolean;
/**
* The mode of the asset property list describing how the properties are selected.
* - `single` - only one property can be selected at a time
* - `multi` - multiple properties can be selected at a time
* - `none` - no properties can be selected
*/
selectMode?: 'single' | 'multi' | 'none';
/**
* The mode of the asset property list describing how the properties are expanded.
* - `expandedByDefault` - all properties are expanded by default and collapse button is shown
* - `collapsedByDefault` - all properties are collapsed by default and expand button is shown
* - `nonCollapsible` - all properties are expanded all the time and collapse button is hidden
*/
expansionMode?: 'expandedByDefault' | 'collapsedByDefault' | 'nonCollapsible';
/**
* Flag to show or hide the header of the asset property list.
* Header includes select all checkbox (if applicable) and the title of the list columns.
*/
showHeader?: boolean;
/**
* Flag to show or hide the value of the asset property.
*/
showValue?: boolean;
/**
* Flag to show or hide the key of the asset property.
* If set to true, the key of the property will be displayed alongside its value.
*/
showKey?: boolean;
/**
* Defines what should be displayed when asset is not selected and there are no properties to show.
* - `empty` - empty state with a message
* - `default-properties` - default properties are shown (like ID, name, type, etc.)
*/
emptyStateContent?: 'empty' | 'default-properties';
/**
* Flag to allow adding custom properties to the asset property list with additional dialog.
*/
allowAddingCustomProperties?: boolean;
/**
* Asset property list allows to provide custom properties as an input.
* This flag defines how the input properties are handled.
* - `merge` - input properties are merged with properties from asset list
* - `override` - input properties override properties from asset list, meaning that only input properties are shown
*/
inputPropertiesHandle?: 'merge' | 'override';
/**
* Enable or disable drag and drop functionality for reordering properties.
*/
allowDragAndDrop?: boolean;
};
declare const defaultAssetPropertyListConfig: AssetPropertyListConfig;
declare const defaultAssetProperties: Array<BaseProperty>;
declare const deviceAssetProperties: Array<BaseProperty>;
declare const RESULT_TYPES: {
VALUE: {
name: string;
value: number;
label: "Only value";
};
VALUE_UNIT: {
name: string;
value: number;
label: "Value and unit";
};
VALUE_UNIT_TIME: {
name: string;
value: number;
label: "Value, unit and time";
};
};
type C8yPropertyType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null' | 'date' | 'enum' | 'file' | 'c8y_JsonSchema' | ['string', 'null'] | Array<C8yPropertyType>;
type C8yPropertyFormat = 'datetime' | 'hidden' | 'textarea';
interface C8yJsonSchemaProperty {
type: C8yPropertyType;
title?: string;
label?: string;
description?: string;
key?: string;
name?: string;
minimum?: number;
maximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
required?: boolean;
readOnly?: boolean;
printFormat?: C8yPropertyFormat;
'x-schema-form'?: {
type: string;
};
properties?: Record<string, C8yJsonSchemaProperty>;
items?: C8yJsonSchemaProperty;
'x-show-if-any-available'?: {
contextPath: string;
}[];
[key: string]: any;
}
interface C8yJsonSchema {
properties: Record<string, C8yJsonSchemaProperty>;
required?: string[];
}
interface BaseProperty {
name: string;
label: string;
type: C8yPropertyType;
isEditable?: boolean;
temporary?: boolean;
isStandardProperty?: boolean;
c8y_JsonSchema?: C8yJsonSchema;
active?: boolean;
computed?: boolean;
instanceId?: string;
[key: string]: any;
}
interface NestedPropertyFields extends BaseProperty {
title?: string;
properties?: object;
keyPath: string[];
}
type AssetPropertyType = BaseProperty | NestedPropertyFields;
/**
* Service for managing asset properties.
*/
declare class AssetPropertiesService {
private readonly FRAGMENTS_TO_OMIT;
private inventoryService;
private assetTypesRealtimeService;
private groupService;
private alert;
private computedPropertiesService;
/**
* Filters added properties to only include those compatible with the given asset.
* Currently only checks compatibility for computed properties.
* @param allAddedProperties All properties that have been added by the user
* @param asset The current asset context
* @returns Promise resolving to properties compatible with the asset
*/
filterCompatibleProperties(allAddedProperties: AssetPropertyType[], asset: IManagedObject): Promise<AssetPropertyType[]>;
/**
* Retrieves properties for an asset from asset library.
* @param asset The asset for which to retrieve custom properties.
* @returns A promise resolving to the list of custom properties.
*/
requestAssetProperties(asset: IManagedObject): Promise<IManagedObject[]>;
/**
* Retrieves the initial set of properties for an asset, based on its type.
* @param asset The asset for which to retrieve properties.
* @returns A promise resolving to the list of initial properties.
*/
getInitialProperties(asset: IManagedObject): Promise<AssetPropertyType[]>;
/**
* Retrieves properties for a device asset.
* @param asset The device asset for which to retrieve properties.
* @returns A promise resolving to the list of device properties.
*/
getDeviceProperties(asset: IManagedObject): Promise<AssetPropertyType[]>;
/**
* Retrieves properties for a group asset.
* @param asset The group asset for which to retrieve properties.
* @returns A promise resolving to the list of group properties.
*/
getGroupProperties(asset: IManagedObject): Promise<AssetPropertyType[]>;
/**
* Retrieves properties for a regular asset.
* @param asset The asset for which to retrieve properties.
* @returns A promise resolving to the list of asset properties.
*/
getAssetProperties(asset: IManagedObject): Promise<AssetPropertyType[]>;
/**
* Categorizes custom properties into simple and complex types.
* @param properties The custom properties to categorize.
* @returns The categorized custom properties.
*/
categorizeCustomProperties(properties: IManagedObject[]): AssetPropertyType[];
/**
* Categorizes and flattens hierarchical properties into simple and complex types.
* @param properties The hierarchical properties to categorize and flatten.
* @returns The categorized and flattened properties.
*/
categorizeAndFlattenHierarchicalProperties(properties: AssetPropertyType[]): {
computed: AssetPropertyType[];
simple: AssetPropertyType[];
complex: AssetPropertyType[];
};
/**
* Checks if a property is complex (i.e., has nested properties).
* @param property The property to check.
* @returns True if the property is complex, false otherwise.
*/
isComplexProperty(property: AssetPropertyType): boolean;
/**
* Checks if property is available based on provided available computed property names.
* @param property The property to check.
* @param availableComputedPropertyNames Set of available computed property names.
* @returns True if the property is available, false otherwise.
*/
isPropertyAvailable(property: AssetPropertyType, availableComputedPropertyNames: Set<string>): Promise<boolean>;
/**
* Checks if two properties match for selection purposes.
* @param property1 First property to compare.
* @param property2 Second property to compare.
* @returns True if properties match.
*/
propertiesMatch(property1: AssetPropertyType, property2: AssetPropertyType): boolean;
/**
* Retrieves custom properties from the properties library, optionally filtered by search text.
* @param searchText Optional search text to filter properties.
* @returns A promise resolving to the list of properties and paging information.
*/
getPropertiesFromPropertiesLibrary(searchText?: string): Promise<{
propertiesFromLibrary: AssetPropertyType[];
paging: _c8y_client.Paging<IManagedObject>;
}>;
private requestPropertiesFromPropertiesLibrary;
private addNestedProperties;
private flattenProperties;
private getManagedObjectProperties;
private extractFragments;
private shouldSkipFragment;
private addPropertyItem;
static ɵfac: i0.ɵɵFactoryDeclaration<AssetPropertiesService, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<AssetPropertiesService>;
}
/**
* Service to open a drawer for selecting custom asset properties.
*/
declare class CustomPropertiesDrawerService {
private bottomDrawerService;
getCustomProperties(asset: IManagedObject): Promise<AssetPropertyType[]>;
static ɵfac: i0.ɵɵFactoryDeclaration<CustomPropertiesDrawerService, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<CustomPropertiesDrawerService>;
}
interface AssetPropertyFlatNode {
expandable: boolean;
level: number;
property: AssetPropertyType;
isVisible: boolean;
indeterminate?: boolean;
contextAssetId?: string;
}
declare class FlatTreeDataSource extends DataSource<AssetPropertyFlatNode> {
private _dataChange;
constructor();
get data(): AssetPropertyFlatNode[];
set data(value: AssetPropertyFlatNode[]);
connect(): Observable<AssetPropertyFlatNode[]>;
disconnect(): void;
}
declare class AssetPropertyActionDirective {
template: TemplateRef<unknown>;
elementRef: ElementRef;
viewContainer: ViewContainerRef;
constructor(template: TemplateRef<unknown>, elementRef: ElementRef, viewContainer: ViewContainerRef);
static ɵfac: i0.ɵɵFactoryDeclaration<AssetPropertyActionDirective, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<AssetPropertyActionDirective, "[c8yAssetPropertyAction]", never, {}, {}, never, never, true, never>;
}
/**
* Represents a list of asset properties with hierarchical tree structure.
*/
declare class AssetPropertyListComponent implements OnInit, OnChanges, OnDestroy {
/**
* Reference to the CDdk tree component.
*/
tree: i0.Signal<CdkTree<AssetPropertyFlatNode, AssetPropertyFlatNode>>;
/**
* Configuration for the asset property list.
*/
config: AssetPropertyListConfig;
/**
* Managed object representing the asset.
*/
asset: IManagedObject;
/**
* Extra properties to be displayed in the list.
*/
extraProperties: AssetPropertyType[];
/**
* Emits the selected properties.
*/
selectedProperties: EventEmitter<AssetPropertyType[]>;
/**
* List of all properties.
*/
properties: AssetPropertyType[];
/**
* Text input for filtering properties.
*/
filterText: string;
/**
* Data source for the tree structure.
*/
dataSource: FlatTreeDataSource;
/**
* Map of flat nodes for quick lookup.
*/
flatNodeMap: Map<string, AssetPropertyFlatNode>;
/**
* Indicates if all nodes are selected.
*/
allSelected: boolean;
/**
* Indicates if the selection state is indeterminate.
*/
indeterminate: boolean;
/**
* Directive for asset property actions.
*/
assetPropertyAction: AssetPropertyActionDirective;
hasExpandableNodes: boolean;
areAllNodesExpanded: boolean;
collapseAllLabel: "Collapse all";
expandAllLabel: "Expand all";
dragHandleEnabledLabel: "Click and drag to reorder";
dragHandleDisabledLabel: "Clear filtering to reorder";
get cdkDragDisabled(): boolean;
readonly TREE_NODE_INDENT = 24;
/**
* Stores all nodes in their complete ordered state (source of truth for order)
*/
private allNodesComplete;
/**
* Tracks which parent nodes are expanded (key = node key, value = expanded state)
*/
private expansionState;
/**
* List of properties that have been added temporarily as custom properties.
*/
private allAddedProperties;
/**
* List of properties that have been added temporarily as custom properties filtered according to context asset.
*/
private displayAddedProperties;
/**
* Subject for handling filter input.
*/
private filterSubject$;
/**
* Subject for handling component destruction.
*/
private destroy$;
/**
* Service for managing asset properties.
*/
private assetPropertiesService;
private customPropertiesDrawerService;
private computedPropertiesService;
private modalService;
private dragDropService;
/**
* Constructor initializes reactive effects for expansion modes.
*/
constructor();
ngOnInit(): void;
ngOnChanges(changes: SimpleChanges): Promise<void>;
ngAfterViewInit(): void;
ngOnDestroy(): void;
/**
* Fetches and categorizes properties.
* @returns A promise resolving to the list of asset properties.
*/
getProperties(): Promise<AssetPropertyType[]>;
/**
* Opens the drawer to add new custom properties.
*/
addProperty(): Promise<void>;
/**
* Displays the configuration modal for multiple computed properties and updates their configurations.
* @param properties Properties to configure.
* @param definitions Computed property definitions including config components.
* @returns Promise resolving to array of configurations.
*/
configureMultipleProperties(properties: AssetPropertyType[], definitions: ComputedPropertyDefinition[]): Promise<unknown[]>;
/**
* Displays the configuration modal for a computed property and updates its configuration.
* @param property Property to configure.
* @param definition Computed property definition including config component.
* @returns true if the property was configured, false if cancelled.
*/
configureProperty(property: AssetPropertyType, definition: ComputedPropertyDefinition): Promise<boolean>;
/**
* Removes temporary property from the list.
* @param property The property to remove.
*/
removeProperty(property: AssetPropertyType): Promise<void>;
editProperty(property: AssetPropertyType): Promise<void>;
hasChild(node: AssetPropertyFlatNode): boolean;
/**
* Checks if the property's context asset matches the current asset.
* @param node The node to check.
* @returns True if the context asset doesn't match the current asset.
*/
isContextMismatch(node: AssetPropertyFlatNode): boolean;
/**
* Gets the level of a node.
* @param node The node to check.
* @returns The level of the node.
*/
getLevel(node: AssetPropertyFlatNode): number;
/**
* Gets the parent node of a given node.
* @param node The node to check.
* @returns The parent node or null if none exists.
*/
getParentNode(node: AssetPropertyFlatNode): AssetPropertyFlatNode | null;
/**
* Checks if a node is expanded.
* @param node The node to check.
* @returns True if the node is expanded.
*/
isNodeExpanded(node: AssetPropertyFlatNode): boolean;
/**
* Toggles the expansion state of a node.
* @param node The node to toggle.
*/
toggleNode(node: AssetPropertyFlatNode): void;
/**
* Selects or deselects all nodes.
* @param selected True to select all, false to deselect.
*/
selectAll(selected: boolean): void;
/**
* Handles single selection mode.
* @param selected True if the node is selected.
* @param node The node to select.
*/
onSelectSingle(selected: boolean, node: AssetPropertyFlatNode): void;
/**
* Handles multi-selection mode.
* @param selected True if the node is selected.
* @param node The node to select.
*/
onSelectMulti(selected: boolean, node: AssetPropertyFlatNode): void;
/**
* Initiates a filter operation.
*/
onFilter(): void;
/**
* Clears the filter input.
*/
clearFilter(): void;
drop(event: CdkDragDrop<AssetPropertyFlatNode[]>): void;
/**
* Toggles expansion of all nodes - expands all if any are collapsed, otherwise collapses all.
*/
toggleExpandCollapseAll(): void;
/**
* Calculates the max-width for a column based on node level and configuration.
* @param node The node to calculate width for.
* @returns The calculated max-width CSS value.
*/
getColumnMaxWidth(node: AssetPropertyFlatNode): string;
/**
* Gets the unique key for a node.
* @param node The node.
* @returns The unique key.
*/
private getNodeKey;
/**
* Updates the areAllNodesExpanded state based on expansion state.
*/
private updateAreAllNodesExpandedState;
/**
* Expands all nodes in the expansion state.
*/
private expandAllNodesInState;
/**
* Collapses all nodes in the expansion state.
*/
private collapseAllNodesInState;
/**
* Updates the list of properties based on the configuration.
* @param rebuildFromAsset If true, rebuilds from scratch. Otherwise preserves existing order and only adds new properties.
* @param prependProperties New properties to add if not rebuilding from asset.
*/
private updateProperties;
private applySelectedPropertiesFromConfig;
/**
* Updates the display added properties based on compatibility with current asset.
*/
private updateDisplayAddedProperties;
/**
* Updates the selection status of child nodes.
* @param parent The parent node.
* @param selected True if the parent is selected.
*/
private updateChildSelectionStatus;
/**
* Checks if a property matches the filter criteria.
* @param property The property to check.
* @param filterText The filter text.
* @returns True if the property matches.
*/
private matchesSearch;
/**
* Updates the selection state for all nodes.
*/
private updateSelectAllState;
/**
* Builds the tree nodes from the properties.
*/
private buildTreeNodes;
/**
* Update indeterminate state for all complex nodes
*/
private updateIndeterminateStates;
/**
* Filters the tree nodes based on the filter input.
*/
private filterTree;
/**
* Makes all parent nodes visible.
* @param node The node whose parents should be made visible.
*/
private makeParentsVisible;
/**
* Rebuilds visible data based on expansion state (only when not filtering).
*/
private rebuildVisibleData;
/**
* Determines if a node should be visible based on expansion state.
* @param node The node to check.
* @returns True if the node should be visible.
*/
private shouldNodeBeVisible;
/**
* Updates complete data order after drag-drop on visible data.
* @param newVisibleData The new order of visible nodes.
*/
private updateCompleteDataOrder;
/**
* Categorizes and flattens hierarchical properties.
* @param properties The properties to categorize.
* @returns The flattened list of properties.
*/
private categorizeAndFlattenHierarchicalProperties;
static ɵfac: i0.ɵɵFactoryDeclaration<AssetPropertyListComponent, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<AssetPropertyListComponent, "c8y-asset-property-list", never, { "config": { "alias": "config"; "required": false; }; "asset": { "alias": "asset"; "required": false; }; "extraProperties": { "alias": "extraProperties"; "required": false; }; }, { "selectedProperties": "selectedProperties"; }, ["assetPropertyAction"], never, true, never>;
}
/**
* Represents a drawer component for selecting asset properties.
*/
declare class AssetPropertySelectorDrawerComponent {
/**
* Title of the drawer.
*/
title: "Select property";
/**
* Managed object representing the asset.
*/
asset: IManagedObject;
/**
* Configuration for the asset property list.
*/
config: AssetPropertyListConfig;
/**
* Extra properties to be displayed in the list.
*/
extraProperties: AssetPropertyType[];
/**
* Emits the selected properties when saved.
*/
savePropertySelection: EventEmitter<AssetPropertyType[]>;
/**
* Emits an event when the selection is canceled.
*/
cancelPropertySelection: EventEmitter<void>;
/**
* List of selected properties.
*/
selectedProperties: AssetPropertyType[];
/**
* Reference to the bottom drawer.
*/
bottomDrawerRef: BottomDrawerRef<any>;
/**
* Promise resolving to the selected properties.
*/
result: Promise<AssetPropertyType[]>;
/**
* Internal save handler.
*/
private _save;
/**
* Internal cancel handler.
*/
private _cancel;
/**
* Updates the selected properties.
* @param properties The selected properties.
*/
onSelectedProperties(properties: AssetPropertyType[]): void;
/**
* Saves the selected properties and closes the drawer.
*/
onSave(): void;
/**
* Cancels the selection and closes the drawer.
*/
onCancel(): void;
/**
* Checks if the select button should be disabled.
* @returns True if all selected properties are inactive.
*/
selectIsDisabled(): boolean;
static ɵfac: i0.ɵɵFactoryDeclaration<AssetPropertySelectorDrawerComponent, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<AssetPropertySelectorDrawerComponent, "c8y-asset-property-selector-drawer-component", never, { "title": { "alias": "title"; "required": false; }; }, { "savePropertySelection": "savePropertySelection"; "cancelPropertySelection": "cancelPropertySelection"; }, never, never, true, never>;
}
declare const HOOK_COMPUTED_PROPERTY: InjectionToken<ComputedPropertyDefinition[]>;
declare function hookComputedProperty(property: GenericHookType<ComputedPropertyDefinition>, options?: Partial<GenericHookOptions>): i0.ValueProvider | i0.ClassProvider | i0.ExistingProvider;
declare class ComputedPropertiesService extends ExtensionPointForPlugins<ComputedPropertyDefinition> {
private router;
private groupService;
constructor(rootInjector: Injector, router: Router, plugins: PluginsResolveService);
/**
* Returns the current state.
* @readonly
* @returns The current set of computed properties.
*/
get state(): Set<ComputedPropertyDefinition>;
add(propertyDef: ComputedPropertyDefinition): void;
getByName(name: string): Promise<ComputedPropertyDefinition>;
getByContext(asset: ComputedPropertyContextValue): Promise<ComputedPropertyDefinition[]>;
private getTypeOfContext;
protected setupItemsObservable(): Observable<ComputedPropertyDefinition[]>;
static ɵfac: i0.ɵɵFactoryDeclaration<ComputedPropertiesService, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<ComputedPropertiesService>;
}
export { AssetPropertiesService, AssetPropertyActionDirective, AssetPropertyListComponent, AssetPropertySelectorDrawerComponent, ComputedPropertiesService, CustomPropertiesDrawerService, HOOK_COMPUTED_PROPERTY, RESULT_TYPES, defaultAssetProperties, defaultAssetPropertyListConfig, deviceAssetProperties, hookComputedProperty };
export type { AssetPropertyListConfig, AssetPropertyType, BaseProperty, C8yJsonSchema, C8yJsonSchemaProperty, C8yPropertyType, ComputedPropertyComponent, ComputedPropertyContextType, ComputedPropertyContextValue, ComputedPropertyDefinition, NestedPropertyFields, ValueCallbackMetadata };
//# sourceMappingURL=index.d.ts.map