@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
416 lines (408 loc) • 30.5 kB
TypeScript
import { IIdentified, InventoryService } from '@c8y/client';
import * as _c8y_ngx_components_widgets_implementations_html_widget from '@c8y/ngx-components/widgets/implementations/html-widget';
import { HtmlWidgetConfig } from '@c8y/ngx-components/widgets/implementations/html-widget';
import * as _c8y_ngx_components_context_dashboard from '@c8y/ngx-components/context-dashboard';
import { ContextWidgetConfig, AssetPropertyMappings, WidgetConfigService, WidgetConfigSectionComponent } from '@c8y/ngx-components/context-dashboard';
import * as _c8y_ngx_components from '@c8y/ngx-components';
import { C8yPropertyType, AlertService, DropAreaComponent, DroppedFile, DynamicComponent, DashboardChildComponent, DynamicComponentAlertAggregator } from '@c8y/ngx-components';
import * as _angular_core from '@angular/core';
import { OnInit, DestroyRef, ElementRef } from '@angular/core';
import * as _c8y_ngx_components_ai from '@c8y/ngx-components/ai';
import { AIService, AgentChatConfig, AssistantMessageDisplayConfig, AIAssistantMessage, AIStreamResponse } from '@c8y/ngx-components/ai';
import * as _angular_forms from '@angular/forms';
import { FormBuilder } from '@angular/forms';
import * as rxjs from 'rxjs';
import { Subject, Observable } from 'rxjs';
import * as _c8y_ngx_components_global_context from '@c8y/ngx-components/global-context';
import { GlobalContextState, GLOBAL_CONTEXT_DISPLAY_MODE } from '@c8y/ngx-components/global-context';
import * as _c8y_ngx_components_dist_global_context from '@c8y/ngx-components/dist/global-context';
import * as _c8y_ngx_components_widgets_implementations_scada from '@c8y/ngx-components/widgets/implementations/scada';
import * as packages_client_lib from 'packages/client/lib';
declare const SCADA_WIDGET_FEATURE_FLAG_NAME = "ui.scada-widget.v2";
interface ScadaWidgetConfig extends ContextWidgetConfig {
config: {
htmlWidgetConfig: HtmlWidgetConfig;
mappings: AssetPropertyMappings;
svgDisplaySettings?: SvgDisplaySettings;
};
}
type DisplayOption = 'contain' | 'full-width';
type HorizontalAlignment = 'left' | 'center' | 'right';
type VerticalAlignment = 'top' | 'center' | 'bottom';
interface SvgDisplaySettings {
displayOption: DisplayOption;
horizontalAlignment: HorizontalAlignment;
verticalAlignment: VerticalAlignment;
}
interface SvgComputedStyling {
svgWidth: string;
svgHeight: string;
svgMaxWidth: string;
svgMaxHeight: string;
/** null means the preserveAspectRatio attribute should be removed */
preserveAspectRatio: string | null;
containerDisplay: string;
containerJustifyContent: string;
containerAlignItems: string;
containerOverflow: string;
containerHeight: string;
containerBoxSizing: string;
}
declare const defaultDisplayOption: DisplayOption;
declare const defaultAlignment = "center";
interface ScadaWidgetConfigLegacy {
binaryId: string;
sanitization: 'strict' | 'lax' | 'none';
device: Pick<IIdentified, 'id' | 'name'>;
deviceIds: {
[placeholderName: string]: string;
};
mapping: {
[placeholderName: string]: LegacyMapping;
};
}
type LegacyMapping = LegacyMappingBase | LegacyMappingComputed | LegacyMappingFieldbus;
interface LegacyMappingBase {
id: string;
keyPath: string[];
label: string;
type: C8yPropertyType;
}
interface LegacyMappingComputed extends LegacyMappingBase {
computed: true;
configSchema: object;
config: {
_id: string;
[key: string]: any;
};
}
interface LegacyMappingFieldbus {
fieldbus: true;
id: string;
keyPath: [string, string];
label: string;
}
interface ActiveAlarmsStatus {
critical: number;
major: number;
minor: number;
warning: number;
}
declare const INITIAL_SVG_CODE = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg width=\"600px\" height=\"1350px\" viewBox=\"0 0 600 1350\" xmlns=\"http://www.w3.org/2000/svg\">\n <style>\n /* Typography */\n .header {\n font-family: var(--c8y-font-family-base);\n font-size: 28px;\n font-weight: bold;\n fill: var(--text-color, var(--c8y-component-color-default, var(--c8y-root-component-color-default)));\n }\n .branded {\n fill: var(--brand-primary,var(--c8y-brand-primary));\n }\n .step-number {\n font-family: var(--c8y-font-family-base);\n font-size: 18px;\n font-weight: bold;\n fill: var(--c8y-component-background-default, var(--c8y-root-component-background-default));\n }\n .step-title {\n font-family: var(--c8y-font-family-base);\n font-size: 16px;\n font-weight: bold;\n fill: var(--text-color, var(--c8y-component-color-default, var(--c8y-root-component-color-default)));\n }\n .description {\n font-family: var(--c8y-font-family-base);\n font-size: 14px;\n }\n .placeholder {\n font-family: var(--c8y-font-family-base);\n font-size: 14px;\n fill: var(--brand-primary,var(--c8y-brand-primary));\n font-weight: bold;\n }\n .code {\n font-family: var(--c8y-font-family-mono-spaced);\n font-size: 12px;\n fill: var(--c8y-code-color);\n }\n .label {\n font-family: var(--c8y-font-family-base);\n font-size: 13px;\n fill: var(--text-color, var(--c8y-component-color-default, var(--c8y-root-component-color-default)));\n }\n \n /* Components */\n .section-bg {\n fill: var(--c8y-pre-background);\n stroke: var(--c8y-pre-border-color);\n stroke-width: 1px;\n rx: 4px;\n }\n .step-circle {\n fill: var(--brand-primary,var(--c8y-brand-primary));\n }\n .code-bg {\n fill: #0000000d;\n stroke: transparent;\n stroke-width: 1px;\n rx: 13px;\n }\n .button{\n cursor: pointer;\n }\n .button-bg {\n fill: var(--brand-primary,var(--c8y-brand-primary));\n rx: var(--c8y-btn-border-radius-base);\n stroke: var(--brand-primary,var(--c8y-brand-primary));\n stroke-width: 1px;\n }\n .button-text {\n font-family: inherit;\n font-size: 14px;\n fill: var(--c8y-component-background-default, var(--c8y-root-component-background-default));\n text-anchor: middle;\n }\n .button:hover .button-bg {\n fill: var(--c8y-component-background-default, var(--c8y-root-component-background-default));\n }\n .button:hover .button-text {\n fill: var(--brand-primary,var(--c8y-brand-primary));\n }\n .divider {\n stroke: var(--c8y-component-border-color, var(--c8y-root-component-border-color));\n stroke-width: 2px;\n }\n \n /* Alarm status indicators */\n .alarm-none {\n fill: var(--c8y-palette-status-success);\n }\n .alarm-warning {\n fill: var(--c8y-palette-status-info);\n }\n .alarm-minor {\n fill: var(--c8y-palette-status-warning-high);\n }\n .alarm-major {\n fill: var(--c8y-palette-status-warning);\n }\n .alarm-critical {\n fill: var(--c8y-palette-status-danger);\n }\n \n /* Conditional text colors */\n .temp-ok {\n fill: var(--c8y-palette-status-success);\n }\n .temp-warning {\n fill:var(--c8y-palette-status-danger);\n }\n </style>\n \n <!-- Background -->\n <rect width=\"600\" height=\"1400\" fill=\"var(--c8y-component-background-default, var(--c8y-root-component-background-default))\" />\n \n <!-- Header -->\n <text x=\"40\" y=\"50\" class=\"header\">SCADA widget example</text>\n \n <text x=\"40\" y=\"90\" class=\"description\">Follow these steps to customize your visualization</text>\n \n <!-- Divider -->\n <line x1=\"40\" y1=\"110\" x2=\"560\" y2=\"110\" class=\"divider\" />\n \n <!-- STEP 1: SVG configuration -->\n <circle cx=\"55\" cy=\"150\" r=\"15\" class=\"step-circle\" />\n <text x=\"55\" y=\"157\" class=\"step-number\" text-anchor=\"middle\">1</text>\n <text x=\"85\" y=\"155\" class=\"step-title\">SVG configuration</text>\n \n <text x=\"85\" y=\"180\" class=\"description\">Use \"SVG configuration\" section to upload a file, paste code, or generate with AI.</text>\n \n <!-- STEP 2: Add Placeholders -->\n <circle cx=\"55\" cy=\"230\" r=\"15\" class=\"step-circle\" />\n <text x=\"55\" y=\"237\" class=\"step-number\" text-anchor=\"middle\">2</text>\n <text x=\"85\" y=\"235\" class=\"step-title\">Add placeholders</text>\n \n <text x=\"85\" y=\"260\" class=\"description\">Click on a text or tspan element in the preview to convert it into a placeholder.</text>\n \n <rect x=\"85\" y=\"280\" width=\"475\" height=\"80\" class=\"section-bg\" />\n <text x=\"100\" y=\"305\" class=\"label\">Example - click text below to make it dynamic:</text>\n <text x=\"100\" y=\"330\" class=\"placeholder\"><tspan>Device name</tspan> (<tspan>Device ID</tspan>)</text>\n \n <!-- STEP 3: Configure Data Binding -->\n <circle cx=\"55\" cy=\"395\" r=\"15\" class=\"step-circle\" />\n <text x=\"55\" y=\"402\" class=\"step-number\" text-anchor=\"middle\">3</text>\n <text x=\"85\" y=\"400\" class=\"step-title\">Configure data binding</text>\n \n <text x=\"85\" y=\"425\" class=\"description\">Assign asset properties to placeholders in the \"Placeholder mappings\" section</text>\n <text x=\"85\" y=\"445\" class=\"description\">to see their values in the preview.</text>\n \n <!-- Example with actual placeholders -->\n <rect x=\"40\" y=\"470\" width=\"520\" height=\"120\" class=\"section-bg\" />\n <text x=\"60\" y=\"495\" class=\"label\">Examples:</text>\n \n <text x=\"60\" y=\"525\" class=\"label\">Device name:</text>\n <text x=\"180\" y=\"525\" class=\"placeholder\">${this.c8yScadaValues?.deviceName || '-'}</text>\n\n <text x=\"60\" y=\"550\" class=\"label\">Temperature:</text>\n <text x=\"180\" y=\"550\" class=\"placeholder\">${this.c8yScadaValues?.temperature || '-'} \u00B0C</text>\n\n <text x=\"60\" y=\"575\" class=\"label\">Status:</text>\n <text x=\"180\" y=\"575\" class=\"placeholder\">${this.c8yScadaValues?.status || '-'}</text>\n\n <!-- STEP 4: Advanced Customization -->\n <circle cx=\"55\" cy=\"630\" r=\"15\" class=\"step-circle\" />\n <text x=\"55\" y=\"637\" class=\"step-number\" text-anchor=\"middle\">4</text>\n <text x=\"85\" y=\"635\" class=\"step-title\">Advanced: Edit component code</text>\n\n <text x=\"85\" y=\"660\" class=\"description\">Open \"Advanced editor\" section to customize the web component directly.</text>\n \n <!-- Advanced Examples -->\n <rect x=\"40\" y=\"690\" width=\"520\" height=\"630\" class=\"section-bg\" />\n <text x=\"60\" y=\"715\" class=\"label\">Advanced examples (see implementation in the editor):</text>\n \n <!-- Example 1a: Interactive Button - Device Details -->\n <text x=\"60\" y=\"745\" class=\"description\">\u2022 Button navigating to device details:</text>\n <g class=\"button\" @click=${() => this.c8yScadaFunctions?.goToDeviceDetails(this.c8yScadaValues?.deviceId)}>\n <rect x=\"70\" y=\"755\" width=\"200\" height=\"35\" class=\"button-bg\" />\n <text x=\"170\" y=\"777\" class=\"button-text\">Go to device details</text>\n </g>\n\n <!-- Example 1b: Interactive Button - Group Details -->\n <text x=\"60\" y=\"820\" class=\"description\">\u2022 Button navigating to group details:</text>\n <g class=\"button\" @click=${() => this.c8yScadaFunctions?.goToGroupDetails(this.c8yScadaValues?.groupId)}>\n <rect x=\"70\" y=\"830\" width=\"200\" height=\"35\" class=\"button-bg\" />\n <text x=\"170\" y=\"852\" class=\"button-text\">Go to group details</text>\n </g>\n\n <!-- Example 2: Conditional Styling -->\n <text x=\"60\" y=\"895\" class=\"description\">\u2022 Conditional styling based on temperature range:</text>\n <text x=\"70\" y=\"920\" \n class=\"${(this.c8yScadaValues?.temperature >= 20 && this.c8yScadaValues?.temperature <= 30) ? 'temp-ok' : 'temp-warning'}\"\n font-size=\"14px\"\n font-weight=\"bold\">\n Green if temperature is between 20 and 30 \u00B0C, otherwise red.\n </text>\n \n <!-- Example 3: Dynamic Width Progress Bar -->\n <text x=\"60\" y=\"975\" class=\"description\">\u2022 Dynamic calculations (progress bar):</text>\n <rect x=\"70\" y=\"985\" width=\"400\" height=\"25\" class=\"code-bg\" />\n <rect x=\"70\" y=\"985\" \n width=\"${Math.min((this.c8yScadaValues?.progress || 0) * 4, 400)}\" \n height=\"25\" \n fill=\"var(--brand-primary,var(--c8y-brand-primary))\" \n rx=\"13\" />\n <text x=\"480\" y=\"1000\" class=\"label\">${this.c8yScadaValues?.progress || 0}%</text>\n \n <!-- Example 4: Alarm Status Circle -->\n <text x=\"60\" y=\"1040\" class=\"description\">\u2022 Alarm status indicator using getActiveAlarmsStatusClass():</text>\n <circle cx=\"80\" cy=\"1065\" r=\"12\" \n class=\"${this.c8yScadaFunctions?.getActiveAlarmsStatusClass ? 'alarm-' + this.c8yScadaFunctions.getActiveAlarmsStatusClass(this.c8yScadaValues?.alarmsStatus) : 'alarm-none'}\" />\n <text x=\"100\" y=\"1070\" class=\"label\">\n Alarm status:\n ${this.c8yScadaValues?.alarmsStatus?.critical > 0 ? 'CRITICAL' : this.c8yScadaValues?.alarmsStatus?.major > 0 ? 'MAJOR' : this.c8yScadaValues?.alarmsStatus?.minor > 0 ? 'MINOR' : this.c8yScadaValues?.alarmsStatus?.warning > 0 ? 'WARNING' : 'OK'}\n </text>\n \n <!-- Legend for alarm colors -->\n <text x=\"70\" y=\"1110\" class=\"label\">Alarm color legend:</text>\n <circle cx=\"80\" cy=\"1130\" r=\"8\" class=\"alarm-none\" />\n <text x=\"95\" y=\"1135\" class=\"description\">OK</text>\n \n <circle cx=\"150\" cy=\"1130\" r=\"8\" class=\"alarm-warning\" />\n <text x=\"165\" y=\"1135\" class=\"description\">Warning</text>\n \n <circle cx=\"240\" cy=\"1130\" r=\"8\" class=\"alarm-minor\" />\n <text x=\"255\" y=\"1135\" class=\"description\">Minor</text>\n \n <circle cx=\"320\" cy=\"1130\" r=\"8\" class=\"alarm-major\" />\n <text x=\"335\" y=\"1135\" class=\"description\">Major</text>\n \n <circle cx=\"400\" cy=\"1130\" r=\"8\" class=\"alarm-critical\" />\n <text x=\"415\" y=\"1135\" class=\"description\">Critical</text>\n \n <!-- Additional examples info -->\n <rect x=\"70\" y=\"1170\" width=\"460\" height=\"130\" fill=\"var(--c8y-palette-status-info-light)\" stroke=\"var(--c8y-palette-status-info)\" stroke-width=\"1\" rx=\"4\" />\n <text x=\"85\" y=\"1195\" class=\"label\" font-weight=\"bold\">\uD83D\uDCA1 Tips for advanced usage:</text>\n <text x=\"85\" y=\"1220\" class=\"description\">\u2022 Use this.c8yScadaValues to access placeholder values</text>\n <text x=\"85\" y=\"1240\" class=\"description\">\u2022 Use this.c8yScadaFunctions for navigation and utilities</text>\n <text x=\"85\" y=\"1260\" class=\"description\">\u2022 Combine template literals \\${ } with conditional logic</text>\n <text x=\"85\" y=\"1280\" class=\"description\">\u2022 Apply CSS classes dynamically for styling</text>\n</svg>\n";
declare class ScadaWidgetService {
getScadaFunctions(): {
goToGroupDetails: (groupId: IIdentified["id"]) => void;
goToDeviceDetails: (deviceId: IIdentified["id"]) => void;
getActiveAlarmsStatusClass: (activeAlarmsStatus: ActiveAlarmsStatus) => keyof ActiveAlarmsStatus | "none";
};
getSvgComputedStyling(settings: SvgDisplaySettings | null | undefined): SvgComputedStyling;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScadaWidgetService, never>;
static ɵprov: _angular_core.ɵɵInjectableDeclaration<ScadaWidgetService>;
}
declare class ScadaWidgetConfigService {
private readonly widgetConfigService;
private readonly widgetConfigMigration;
private readonly inventory;
private readonly inventoryBinary;
private readonly computedPropertiesService;
private readonly fieldbusService;
private readonly destroyRef;
configChanged$: Subject<ScadaWidgetConfig>;
config$: rxjs.Observable<ScadaWidgetConfig | (ScadaWidgetConfig & GlobalContextState)>;
constructor();
initializeConfig(config: ContextWidgetConfig | null): Promise<ScadaWidgetConfig & GlobalContextState>;
save(config: ScadaWidgetConfig): void;
updateConfigWithSvgFile(config: ScadaWidgetConfig, svgFile: File): Promise<ScadaWidgetConfig>;
updateConfigWithSvgCode(config: ScadaWidgetConfig, originalSvgCode: string): Promise<ScadaWidgetConfig>;
extractTagContent(text: string, tagName: string): string | undefined;
applySvgCode(code: string): Promise<void>;
applyMappings(mappings: string): Promise<void>;
applyScadaOutput(content: string): Promise<void>;
/**
* Safely parses an SVG string containing Lit expressions, allows DOM editing, and returns the edited SVG string.
* Handles escaping/unescaping Lit syntax and expressions.
*
* @param svg The SVG string to process.
* @param editFn A function that receives the parsed SVG document for editing.
* @returns The edited SVG string, or throws an exception if parsing or editing failed.
*/
editSafelySvgWithLitExpressions(svg: string, editFn: (doc: Document) => Promise<void>): Promise<string>;
updateMappings(config: ScadaWidgetConfig): void;
/**
* Removes hardcoded width and height attributes from the root SVG element.
*
* @param svg The SVG string to process.
* @returns The modified SVG string with width and height attributes removed from the root SVG element.
*/
private removeHardcodedSvgDimensions;
/**
* Processes an SVG string to identify and mark potential text placeholders within `<text>` and `<tspan>` elements.
*
* This method performs the following steps:
* 1. Escapes Lit syntax event bindings (e.g., `@click=${...}`) to avoid XML parsing issues.
* 2. Parses the SVG string into a DOM structure.
* 3. For each `<text>` and `<tspan>` element:
* - Adds a unique `id` attribute if not already present.
* - Adds the CSS class `potential-placeholder` if the element's text content does not already contain a placeholder expression (`this.c8yScadaValues?.`).
* 4. Serializes the DOM back to an SVG string and restores the original Lit syntax.
*
* If parsing fails (e.g., due to unhandled Lit syntax), the original SVG string is returned unchanged.
*
* @param svg The SVG string to process.
* @returns The modified SVG string with potential placeholders marked, or the original SVG if parsing fails.
*/
private findAndAddMarkupForPotentialTextPlaceholders;
/**
* Replaces `{{ key }}` placeholders with new template syntax `${this.c8yScadaValues?.key}`.
*
* @param svgCode The SVG code string with placeholders.
* @returns The SVG code string with new template syntax.
*/
private replacePlaceholdersWithTemplateSyntax;
/**
* Extracts placeholder keys used in the template syntax (`${this.c8yScadaValues?.key}`)
* from the provided SVG code string.
*
* @param svgCode The SVG code string containing template syntax placeholders.
* @returns Array of unique placeholder keys.
*/
private extractScadaKeys;
/**
* Extracts placeholder keys used in the legacy template syntax (`{{ key }}`)
* from the provided SVG code string.
*
* @param svgCode The SVG code string containing legacy template syntax placeholders.
* @returns Array of unique placeholder keys.
*/
private extractLegacyScadaKeys;
private migrateConfigIfNeeded;
private migrateGlobalContextConfig;
private migrateFromLegacyBinary;
private migrateProperty;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScadaWidgetConfigService, never>;
static ɵprov: _angular_core.ɵɵInjectableDeclaration<ScadaWidgetConfigService>;
}
declare class ScadaWidgetSvgSelectorComponent implements OnInit {
widgetConfigService: WidgetConfigService;
scadaConfigService: ScadaWidgetConfigService;
sectionComponent: WidgetConfigSectionComponent;
inventoryService: InventoryService;
alertService: AlertService;
aiService: AIService;
formBuilder: FormBuilder;
destroyRef: DestroyRef;
formGroup: _angular_forms.FormGroup<{
source: _angular_forms.FormControl<"file" | "text" | "ai">;
svgCode: _angular_forms.FormControl<string>;
svgDisplaySettings: _angular_forms.FormGroup<{
displayOption: _angular_forms.FormControl<"contain" | "full-width">;
horizontalAlignment: _angular_forms.FormControl<string>;
verticalAlignment: _angular_forms.FormControl<string>;
}>;
}>;
dropArea: _angular_core.Signal<DropAreaComponent>;
placeholderText: string;
displayOptions: ({
label: "Full width`image fitting option`";
value: string;
description: "The image is resized to fit the widget's width while preserving the aspect ratio. Overflowing area is scrollable.";
} | {
label: "Contain`verb, image fitting option`";
value: string;
description: "The image is entirely displayed within the widget while preserving the aspect ratio.";
})[];
horizontalAlignmentOptions: ({
label: "left`horizontal alignment`";
value: string;
} | {
label: "center`horizontal alignment`";
value: string;
} | {
label: "right`horizontal alignment`";
value: string;
})[];
verticalAlignmentOptions: ({
label: "top`vertical alignment`";
value: string;
} | {
label: "center`vertical alignment`";
value: string;
} | {
label: "bottom`vertical alignment`";
value: string;
})[];
isAiAvailable: _angular_core.WritableSignal<boolean>;
aiInitialized: boolean;
chatConfig: Partial<AgentChatConfig>;
agent: _c8y_ngx_components_ai.ClientAgentDefinition;
variables: {
c8yContext: any;
c8yContextMeasurements: any;
};
suggestions: ({
label: "Analyze and suggest";
prompt: string;
} | {
label: "Best guess";
prompt: string;
})[];
assistantMessageDisplayConfig: AssistantMessageDisplayConfig;
readonly preprocessAgentMessage: (message: AIAssistantMessage, changedPart: AIStreamResponse["changedPart"]) => AIAssistantMessage;
ngOnInit(): Promise<void>;
onSvgFileDropped(event: DroppedFile[]): Promise<void>;
applySvgCode(): Promise<void>;
private initializeAI;
private applyScadaOutput;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScadaWidgetSvgSelectorComponent, never>;
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ScadaWidgetSvgSelectorComponent, "c8y-scada-widget-svg-selector", never, {}, {}, never, never, true, never>;
}
declare class ScadaWidgetAdvancedEditorComponent {
private modalService;
private destroyRef;
private alert;
widgetConfigService: WidgetConfigService;
scadaWidgetConfigService: ScadaWidgetConfigService;
config$: rxjs.Observable<_c8y_ngx_components_widgets_implementations_scada.ScadaWidgetConfig | (_c8y_ngx_components_widgets_implementations_scada.ScadaWidgetConfig & _c8y_ngx_components_dist_global_context.GlobalContextState)>;
propertyKeys$: rxjs.Observable<string[]>;
readonly PROPERTY_PREFIX = "this.c8yScadaValues";
private readonly isLegacy;
private readonly scadaWidgetPreview;
constructor();
readonly getFormattedPropertyExpressionFn: (key: string) => string;
changeCode(newCode: string): Promise<void>;
/**
* Adds a placeholder variable to a clicked SVG text or tspan element.
*
* This method handles the conversion of static text content in SVG elements into dynamic
* placeholders that can be mapped to SCADA values. It locates the SVG node in the configuration,
* prompts the user for a placeholder name, and updates both the SVG code and mappings.
*
* @param event - The event object containing the SVG Element that was clicked
* @param event.node - The SVG Element (text or tspan) that was clicked
*
* @returns A promise that resolves when the placeholder has been added and configuration saved
*
* @remarks
* - Only processes `<text>` and `<tspan>` SVG elements
* - Skips elements that already contain placeholder syntax
* - Removes the 'potential-placeholder' CSS class from the processed node
* - Generates a camelCase placeholder name from the existing text content
* - Updates the widget configuration with new placeholder and mapping
* - If user cancels the placeholder name prompt, no changes are made
*/
addPlaceholder(event: {
node: Element;
}): Promise<void>;
confirmPlaceholderName(proposedName: string): Promise<string | null>;
private handleRename;
private replaceAsync;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScadaWidgetAdvancedEditorComponent, never>;
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ScadaWidgetAdvancedEditorComponent, "c8y-scada-widget-advanced-editor", never, {}, {}, never, never, true, never>;
}
declare class ScadaWidgetViewComponent implements DynamicComponent {
elementRef: ElementRef<any>;
scadaWidgetService: ScadaWidgetService;
scadaWidgetConfigService: ScadaWidgetConfigService;
config: _angular_core.InputSignal<ScadaWidgetConfig>;
private readonly contextOverride;
private readonly initializedConfig;
readonly effectiveConfig: _angular_core.Signal<{
dateTimeContext?: _c8y_ngx_components_global_context.DateTimeContext;
aggregation?: packages_client_lib.aggregationType | null;
isAutoRefreshEnabled?: boolean;
refreshInterval?: number;
refreshOption?: _c8y_ngx_components_global_context.RefreshOption;
displayMode?: `${GLOBAL_CONTEXT_DISPLAY_MODE}`;
source?: _c8y_ngx_components_global_context.GlobalContextSource;
eventSourceId?: string;
isGlobalContextReady?: boolean;
config: {
htmlWidgetConfig: _c8y_ngx_components_widgets_implementations_html_widget.HtmlWidgetConfig;
mappings: _c8y_ngx_components_context_dashboard.AssetPropertyMappings;
svgDisplaySettings?: SvgDisplaySettings;
};
settings?: _c8y_ngx_components.WidgetSettings;
displaySettings?: _c8y_ngx_components.WidgetDisplaySettings;
device?: {
id?: string | number;
name?: string;
[key: string]: any;
};
export?: (config: any) => any | Promise<any>;
import?: (config: any, dashboardData: _c8y_ngx_components_context_dashboard.DashboardMetadata) => any | Promise<any>;
}>;
svgDisplaySettings: _angular_core.Signal<SvgDisplaySettings>;
readonly htmlFrameConfig: _angular_core.Signal<{
css: string;
code: string;
options: _c8y_ngx_components_widgets_implementations_html_widget.HtmlWidgetOptions;
legacy: boolean;
devMode: boolean;
latestCodeHash?: string;
}>;
readonly device: _angular_core.Signal<{
[key: string]: any;
id?: string | number;
name?: string;
}>;
enablePotentialPlaceholders: _angular_core.InputSignal<boolean>;
potentialPlaceholderClick: _angular_core.OutputEmitterRef<{
node: Element;
}>;
private clickListenerController;
webComponentRef: Element;
legacyScopeRef: object;
private legacyElementRef?;
preview: _angular_core.InputSignal<boolean>;
private destroyRef;
private alertService;
protected readonly dashboardChild: DashboardChildComponent;
alerts: DynamicComponentAlertAggregator;
private readonly SERVER_ERROR_TEXT;
private assetPropertyMappings;
readonly realtimeControl$: Observable<boolean>;
private realtimeSubscription;
private readonly refresh$;
propertyValues$: Observable<Record<string, unknown>>;
isLoading: _angular_core.WritableSignal<boolean>;
/**
* Controls link state to global context:
* - true/undefined: Widget follows global time context
* - false: Widget uses local state, ignores global changes
* Set to false when user is interacting (scrolling, zooming) to prevent interruption
*/
isLinkedToGlobal: _angular_core.WritableSignal<boolean>;
readonly GLOBAL_CONTEXT_DISPLAY_MODE: typeof GLOBAL_CONTEXT_DISPLAY_MODE;
readonly PRESET_NAME: {
readonly DEFAULT: "default";
readonly LIFETIME_LIST: "lifetimeList";
readonly DATA_TABLE: "dataTable";
readonly DATA_TABLE_CONFIG: "dataTableConfig";
readonly LIVE_ONLY: "liveOnly";
readonly AUTO_REFRESH_ONLY: "autoRefreshOnly";
readonly AUTO_REFRESH_ONLY_CONFIG: "autoRefreshOnlyConfig";
readonly HISTORY_ONLY: "historyOnly";
readonly LIFETIME_LIST_CONFIG: "lifetimeListConfig";
readonly DATAPOINTS_GRAPH: "datapointsGraph";
readonly DATAPOINTS_GRAPH_CONFIG: "datapointsGraphConfig";
readonly KPI: "kpi";
readonly KPI_CONFIG: "kpiConfig";
readonly DATA_POINTS_LIST: "dataPointsList";
readonly DATA_POINTS_LIST_CONFIG: "dataPointsListConfig";
};
constructor();
onContextChange(event: {
context: GlobalContextState;
diff: GlobalContextState;
}): void;
onRefresh(): void;
private initializeHtmlWidget;
private applyLegacySvgStyling;
private setupRealtimeSubscription;
private handleFetchError;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ScadaWidgetViewComponent, never>;
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ScadaWidgetViewComponent, "c8y-scada-widget-view", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; "enablePotentialPlaceholders": { "alias": "enablePotentialPlaceholders"; "required": false; "isSignal": true; }; "preview": { "alias": "preview"; "required": false; "isSignal": true; }; }, { "potentialPlaceholderClick": "potentialPlaceholderClick"; }, never, never, true, never>;
}
export { INITIAL_SVG_CODE, SCADA_WIDGET_FEATURE_FLAG_NAME, ScadaWidgetAdvancedEditorComponent, ScadaWidgetConfigService, ScadaWidgetService, ScadaWidgetSvgSelectorComponent, ScadaWidgetViewComponent, defaultAlignment, defaultDisplayOption };
export type { ActiveAlarmsStatus, DisplayOption, HorizontalAlignment, LegacyMapping, LegacyMappingBase, LegacyMappingComputed, LegacyMappingFieldbus, ScadaWidgetConfig, ScadaWidgetConfigLegacy, SvgComputedStyling, SvgDisplaySettings, VerticalAlignment };
//# sourceMappingURL=index.d.ts.map