@c8y/ngx-components 1023.43.3 → 1023.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/ai/agent-chat/index.d.ts +6 -1
  2. package/ai/agent-chat/index.d.ts.map +1 -1
  3. package/ai/ai-chat/index.d.ts.map +1 -1
  4. package/ai/index.d.ts +39 -30
  5. package/ai/index.d.ts.map +1 -1
  6. package/datapoints-export-selector/index.d.ts +2 -1
  7. package/datapoints-export-selector/index.d.ts.map +1 -1
  8. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +24 -9
  9. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
  10. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +5 -4
  11. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -1
  12. package/fesm2022/c8y-ngx-components-ai.mjs +63 -33
  13. package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -1
  14. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +1 -1
  15. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  16. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +6 -3
  17. package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
  18. package/fesm2022/c8y-ngx-components-echart.mjs +5 -4
  19. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  20. package/fesm2022/c8y-ngx-components-global-context.mjs +29 -20
  21. package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
  22. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +1 -5
  23. package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
  24. package/fesm2022/c8y-ngx-components-upgrade.mjs +3 -33
  25. package/fesm2022/c8y-ngx-components-upgrade.mjs.map +1 -1
  26. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs +1203 -34
  27. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs.map +1 -1
  28. package/fesm2022/c8y-ngx-components-widgets-definitions-markdown.mjs +3 -2
  29. package/fesm2022/c8y-ngx-components-widgets-definitions-markdown.mjs.map +1 -1
  30. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +32 -4
  31. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
  32. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +1 -1
  33. package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
  34. package/fesm2022/c8y-ngx-components-widgets-implementations-markdown.mjs +122 -80
  35. package/fesm2022/c8y-ngx-components-widgets-implementations-markdown.mjs.map +1 -1
  36. package/fesm2022/c8y-ngx-components.mjs +55 -6
  37. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  38. package/global-context/index.d.ts.map +1 -1
  39. package/index.d.ts +28 -3
  40. package/index.d.ts.map +1 -1
  41. package/locales/de.po +14 -20
  42. package/locales/es.po +13 -19
  43. package/locales/fr.po +18 -24
  44. package/locales/ja_JP.po +13 -19
  45. package/locales/ko.po +13 -19
  46. package/locales/locales.pot +11 -17
  47. package/locales/nl.po +13 -19
  48. package/locales/pl.po +13 -19
  49. package/locales/pt_BR.po +13 -19
  50. package/locales/zh_CN.po +13 -19
  51. package/locales/zh_TW.po +13 -19
  52. package/package.json +1 -1
  53. package/trusted-certificates/index.d.ts +0 -2
  54. package/trusted-certificates/index.d.ts.map +1 -1
  55. package/upgrade/index.d.ts.map +1 -1
  56. package/widgets/definitions/markdown/index.d.ts +1 -1
  57. package/widgets/implementations/datapoints-graph/index.d.ts +3 -0
  58. package/widgets/implementations/datapoints-graph/index.d.ts.map +1 -1
  59. package/widgets/implementations/markdown/index.d.ts +23 -13
  60. package/widgets/implementations/markdown/index.d.ts.map +1 -1
  61. package/fesm2022/c8y-ngx-components-upgrade-not-found.component-CuCuYAkK.mjs +0 -19
  62. package/fesm2022/c8y-ngx-components-upgrade-not-found.component-CuCuYAkK.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-ai-ai-chat.mjs","sources":["../../ai/ai-chat/ai-chat-message-action.component.ts","../../ai/ai-chat/ai-chat-message-action.component.html","../../ai/ai-chat/ai-chat-message.component.ts","../../ai/ai-chat/ai-chat-message.component.html","../../ai/ai-chat/ai-chat-suggestion.component.ts","../../ai/ai-chat/ai-chat-suggestion.component.html","../../ai/ai-chat/ai-chat.component.ts","../../ai/ai-chat/ai-chat.component.html","../../ai/ai-chat/c8y-ngx-components-ai-ai-chat.ts"],"sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { C8yTranslatePipe, IconDirective } from '@c8y/ngx-components';\nimport { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\n\n/**\n * An action button that can be added to chat messages.\n * Typically used for actions like copying, regenerating, or providing feedback on messages.\n */\n@Component({\n selector: 'c8y-ai-chat-message-action',\n templateUrl: './ai-chat-message-action.component.html',\n standalone: true,\n imports: [TooltipModule, C8yTranslatePipe, IconDirective]\n})\nexport class AiChatMessageActionComponent {\n /**\n * Disables the action button when true.\n */\n @Input()\n disabled = false;\n\n /**\n * Tooltip text displayed when hovering over the action button.\n */\n @Input()\n tooltip = '';\n\n /**\n * Icon to display in the action button.\n */\n @Input()\n icon: SupportedIconsSuggestions = 'cog';\n\n /**\n * Emitted when the action button is clicked.\n */\n @Output()\n click = new EventEmitter<void>();\n}\n","<button\n class=\"btn btn-dot text-muted\"\n [attr.aria-label]=\"tooltip | translate\"\n [tooltip]=\"tooltip | translate\"\n [adaptivePosition]=\"true\"\n [delay]=\"500\"\n (click)=\"click.emit()\"\n [disabled]=\"disabled\"\n>\n <i\n class=\"text-12\"\n [c8yIcon]=\"icon\"\n ></i>\n</button>\n","import { Component, computed, input, inject } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AIMessage } from '@c8y/ngx-components/ai';\nimport { C8yTranslatePipe, DatePipe, MarkdownToHtmlPipe } from '@c8y/ngx-components';\nimport { AsyncPipe, NgClass } from '@angular/common';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { TranslateService } from '@ngx-translate/core';\n\n@Component({\n selector: 'c8y-ai-chat-message',\n templateUrl: './ai-chat-message.component.html',\n standalone: true,\n imports: [MarkdownToHtmlPipe, AsyncPipe, NgClass, TooltipModule, C8yTranslatePipe, DatePipe]\n})\nexport class AiChatMessageComponent {\n readonly role = input<AIMessage['role']>();\n readonly message = input<AIMessage>();\n private readonly translateService = inject(TranslateService);\n\n private readonly roleResolved = computed(() => {\n return this.message()?.role || this.role();\n });\n\n /**\n * Generates an accessible label for the message container.\n * Includes the role (user or assistant) and timestamp if available.\n * @returns The aria-label string for screen readers\n */\n readonly ariaLabel = computed(() => {\n const tpl =\n this.roleResolved() === 'user'\n ? gettext('You said: \"{{ message }}\"')\n : gettext('Assistant said: \"{{ message }}\"');\n const msg = this.message();\n return this.translateService.instant(tpl, { message: msg?.content || gettext('No response.') });\n });\n\n /**\n * Generates an accessible label for the message content.\n * Prefixes the content with contextual information about who sent it.\n * @returns The aria-label string with prefixed role information\n */\n readonly messageContentAriaLabel = computed(() => {\n const msg = this.message();\n const time = msg?.timestamp ? new Date(msg.timestamp).toLocaleTimeString() : '';\n let tpl: string;\n if (time) {\n tpl =\n this.roleResolved() === 'user'\n ? gettext('User message at {{ time }}')\n : gettext('Assistant message at {{ time }}');\n } else {\n tpl = this.roleResolved() === 'user' ? gettext('User message') : gettext('Assistant message');\n }\n return this.translateService.instant(tpl, { time });\n });\n}\n","<div\n class=\"d-col p-b-16\"\n [attr.aria-label]=\"ariaLabel()\"\n role=\"article\"\n>\n <div\n class=\"chat-message text-break-word\"\n [ngClass]=\"{\n 'user-message': message()?.role === 'user' || role() === 'user',\n 'agent-message': message()?.role === 'assistant' || role() === 'assistant'\n }\"\n >\n <div\n class=\"message-content\"\n [attr.aria-label]=\"messageContentAriaLabel()\"\n [innerHTML]=\"message()?.content | markdownToHtml | async\"\n ></div>\n <ng-content select=\":not(c8y-ai-chat-message-action)\"></ng-content>\n @if (message()?.timestamp) {\n <div class=\"message-timestamp\">\n <span [tooltip]=\"message()?.timestamp | c8yDate\">\n {{ message()?.timestamp | c8yDate: 'adaptiveDate' }}\n </span>\n </div>\n }\n </div>\n <div\n class=\"message-action\"\n [attr.aria-label]=\"'Message actions' | translate\"\n role=\"toolbar\"\n [ngClass]=\"{\n 'user-action showOnHover': message()?.role === 'user' || role() === 'user',\n 'agent-action p-l-16': message()?.role === 'assistant' || role() === 'assistant'\n }\"\n >\n <ng-content select=\"c8y-ai-chat-message-action\"></ng-content>\n </div>\n</div>\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { C8yTranslatePipe, IconDirective } from '@c8y/ngx-components';\nimport { AIMessage } from '@c8y/ngx-components/ai';\nimport { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';\n\n/**\n * A suggestion chip that can be displayed in the chat interface.\n * When clicked, it automatically populates and sends a predefined prompt.\n */\n@Component({\n selector: 'c8y-ai-chat-suggestion',\n templateUrl: './ai-chat-suggestion.component.html',\n standalone: true,\n imports: [IconDirective, C8yTranslatePipe]\n})\nexport class AiChatSuggestionComponent {\n /**\n * The visible label text displayed on the suggestion chip.\n */\n @Input()\n label: string;\n\n /**\n * The prompt text that will be sent when the suggestion is clicked.\n */\n @Input()\n prompt: string;\n\n /**\n * Icon to display alongside the suggestion label.\n */\n @Input()\n icon: SupportedIconsSuggestions = 'c8y-bulb';\n\n /**\n * When true, uses AI-styled buttons instead of default styling.\n */\n @Input()\n useAiButtons = false;\n\n /**\n * Disables the suggestion chip when true.\n */\n @Input()\n disabled = false;\n\n /**\n * Emitted when the suggestion is clicked, providing the prompt as an AIMessage.\n */\n @Output()\n suggestionClicked = new EventEmitter<AIMessage>();\n\n /**\n * Handles suggestion click and emits the prompt as a user message.\n */\n suggest() {\n this.suggestionClicked.emit({\n content: this.prompt,\n role: 'user',\n timestamp: new Date().toISOString()\n });\n }\n}\n","@if (!useAiButtons) {\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"prompt | translate\"\n (click)=\"suggest()\"\n [disabled]=\"disabled\"\n >\n <i [c8yIcon]=\"icon\"></i>\n {{ label | translate }}\n </button>\n} @else {\n <button\n class=\"btn btn-sm btn-ai\"\n [title]=\"prompt | translate\"\n (click)=\"suggest()\"\n [disabled]=\"disabled\"\n >\n <span>{{ label | translate }}</span>\n </button>\n}\n","import { NgClass } from '@angular/common';\nimport { Component, ContentChildren, EventEmitter, Input, Output, QueryList } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { C8yTranslatePipe, IconDirective, TextareaAutoresizeDirective } from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AIMessage, ChatConfig } from '@c8y/ngx-components/ai';\nimport { AiChatMessageComponent } from './ai-chat-message.component';\n\n/**\n * An interactive chat interface component for AI-powered conversations.\n * Displays messages in a conversation format with support for loading states,\n * custom configuration, and markdown formatting.\n */\n@Component({\n selector: 'c8y-ai-chat',\n templateUrl: './ai-chat.component.html',\n imports: [C8yTranslatePipe, FormsModule, TextareaAutoresizeDirective, IconDirective, NgClass],\n standalone: true,\n host: { class: 'd-contents' }\n})\nexport class AiChatComponent {\n /**\n * Indicates whether the chat is currently processing a request.\n * When true, displays a cancel button instead of send button and disables the input.\n */\n @Input()\n isLoading = false;\n\n /**\n * Disables the chat input and send button when true.\n */\n @Input()\n disabled = false;\n\n /**\n * The current text in the chat input field. Supports two-way binding.\n */\n @Input()\n prompt = '';\n\n /**\n * Emitted when the user sends a message.\n * Provides an AIMessage object with role, content, and timestamp.\n */\n @Output()\n onMessage = new EventEmitter<AIMessage>();\n\n /**\n * Emitted when the user cancels an ongoing operation during loading state.\n */\n @Output()\n onCancel = new EventEmitter<void>();\n\n /**\n * Child message components displayed in the chat.\n */\n @ContentChildren(AiChatMessageComponent) messages: QueryList<AiChatMessageComponent>;\n\n readonly componentId = `chat-${crypto.randomUUID()}`;\n\n private _config: ChatConfig = {\n headline: gettext('Welcome!'),\n welcomeText: '',\n title: gettext('What can I help you with?'),\n placeholder: gettext('Type your message here...'),\n sendButtonText: gettext('Send'),\n cancelButtonText: gettext('Cancel'),\n disclaimerText: gettext(\n 'AI-generated responses can contain errors. Verify the details before use.'\n ),\n userInterfaceIcons: {\n send: 'arrow-circle-up',\n cancel: 'stop-circle'\n }\n };\n\n /**\n * Configuration object for customizing labels, placeholders, and icons.\n * Accepts partial configuration to override defaults.\n */\n @Input()\n set config(value: Partial<ChatConfig>) {\n this._config = { ...this._config, ...value };\n }\n get config() {\n return this._config;\n }\n\n /**\n * Handles message submission when the user sends a message.\n * Emits the onMessage event and clears the input.\n * @param $event - The event object from the form submission\n */\n sendMessage($event: Event): void {\n $event.preventDefault();\n if (!this.prompt) return;\n this.onMessage.emit({\n role: 'user',\n content: this.prompt,\n timestamp: new Date().toISOString()\n });\n this.prompt = '';\n }\n\n /**\n * Handles cancellation of ongoing operations during loading state.\n * Emits the onCancel event.\n */\n cancel(): void {\n this.onCancel.emit();\n }\n}\n","<div\n class=\"d-col fit-h fit-w flex-grow\"\n [attr.aria-label]=\"config.headline | translate\"\n role=\"region\"\n>\n @if (messages.length > 0) {\n <div\n class=\"inner-scroll flex-grow d-col-reverse min-height-0 bg-level-0\"\n [attr.aria-label]=\"'Chat conversation' | translate\"\n aria-live=\"polite\"\n aria-atomic=\"false\"\n role=\"log\"\n >\n <div class=\"d-col p-l-16 p-r-16\">\n <ng-content select=\"c8y-ai-chat-message\"></ng-content>\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div [ngClass]=\"{ 'd-col fit-h': messages.length === 0 }\">\n @if (messages.length === 0) {\n <div\n class=\"p-24\"\n aria-live=\"polite\"\n role=\"status\"\n >\n <h4 class=\"m-b-16 text-medium\">{{ config.headline | translate }}</h4>\n <p class=\"p-b-8 text-balance\">{{ config.title | translate }}</p>\n <p class=\"text-muted text-balance\">{{ config.welcomeText | translate }}</p>\n </div>\n }\n <div class=\"chat-input bg-level-1\">\n <div class=\"d-flex inner-scroll a-i-center gap-8 p-l-16 p-r-16 p-b-8\">\n <ng-content select=\"c8y-ai-chat-suggestion\"></ng-content>\n </div>\n <div class=\"chat-input-group\">\n <label\n class=\"sr-only\"\n for=\"chat-input-{{ componentId }}\"\n >\n {{ config.placeholder | translate }}\n </label>\n <textarea\n class=\"form-control no-resize\"\n style=\"max-height: 200px !important\"\n [attr.aria-label]=\"config.placeholder | translate\"\n id=\"chat-input-{{ componentId }}\"\n placeholder=\"{{ config.placeholder | translate }}\"\n [attr.aria-describedby]=\"config.disclaimerText ? 'chat-disclaimer-' + componentId : null\"\n [attr.aria-busy]=\"isLoading\"\n [(ngModel)]=\"prompt\"\n (keydown.enter)=\"sendMessage($event)\"\n [disabled]=\"isLoading || disabled\"\n c8y-textarea-autoresize\n ></textarea>\n <div class=\"chat-input-group-btn\">\n @if (!isLoading) {\n <button\n class=\"btn btn-dot\"\n [attr.title]=\"config.sendButtonText | translate\"\n [attr.aria-label]=\"config.sendButtonText | translate\"\n type=\"button\"\n (click)=\"sendMessage($event)\"\n [disabled]=\"disabled || prompt.trim().length === 0\"\n >\n <i [c8yIcon]=\"config.userInterfaceIcons?.send || 'arrow-circle-right'\"></i>\n </button>\n } @else {\n <button\n class=\"btn btn-dot btn-dot--danger\"\n [attr.title]=\"config.cancelButtonText | translate\"\n [attr.aria-label]=\"config.cancelButtonText | translate\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n <i [c8yIcon]=\"config.userInterfaceIcons?.cancel || 'stop'\"></i>\n </button>\n }\n </div>\n </div>\n @if (config.disclaimerText) {\n <div\n class=\"text-muted m-b-8 text-10 p-l-16\"\n id=\"chat-disclaimer-{{ componentId }}\"\n role=\"note\"\n >\n {{ config.disclaimerText | translate }}\n </div>\n }\n </div>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-ai-ai-chat.mjs","sources":["../../ai/ai-chat/ai-chat-message-action.component.ts","../../ai/ai-chat/ai-chat-message-action.component.html","../../ai/ai-chat/ai-chat-message.component.ts","../../ai/ai-chat/ai-chat-message.component.html","../../ai/ai-chat/ai-chat-suggestion.component.ts","../../ai/ai-chat/ai-chat-suggestion.component.html","../../ai/ai-chat/ai-chat.component.ts","../../ai/ai-chat/ai-chat.component.html","../../ai/ai-chat/c8y-ngx-components-ai-ai-chat.ts"],"sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { C8yTranslatePipe, IconDirective } from '@c8y/ngx-components';\nimport { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\n\n/**\n * An action button that can be added to chat messages.\n * Typically used for actions like copying, regenerating, or providing feedback on messages.\n */\n@Component({\n selector: 'c8y-ai-chat-message-action',\n templateUrl: './ai-chat-message-action.component.html',\n standalone: true,\n imports: [TooltipModule, C8yTranslatePipe, IconDirective]\n})\nexport class AiChatMessageActionComponent {\n /**\n * Disables the action button when true.\n */\n @Input()\n disabled = false;\n\n /**\n * Tooltip text displayed when hovering over the action button.\n */\n @Input()\n tooltip = '';\n\n /**\n * Icon to display in the action button.\n */\n @Input()\n icon: SupportedIconsSuggestions = 'cog';\n\n /**\n * Emitted when the action button is clicked.\n */\n @Output()\n click = new EventEmitter<void>();\n}\n","<button\n class=\"btn btn-dot text-muted\"\n [attr.aria-label]=\"tooltip | translate\"\n [tooltip]=\"tooltip | translate\"\n [adaptivePosition]=\"true\"\n [delay]=\"500\"\n (click)=\"click.emit()\"\n [disabled]=\"disabled\"\n>\n <i\n class=\"text-12\"\n [c8yIcon]=\"icon\"\n ></i>\n</button>\n","import { Component, computed, input, inject } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AIMessage } from '@c8y/ngx-components/ai';\nimport { C8yTranslatePipe, DatePipe, MarkdownToHtmlPipe } from '@c8y/ngx-components';\nimport { AsyncPipe, NgClass } from '@angular/common';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { TranslateService } from '@ngx-translate/core';\n\n@Component({\n selector: 'c8y-ai-chat-message',\n templateUrl: './ai-chat-message.component.html',\n standalone: true,\n imports: [MarkdownToHtmlPipe, AsyncPipe, NgClass, TooltipModule, C8yTranslatePipe, DatePipe]\n})\nexport class AiChatMessageComponent {\n readonly role = input<AIMessage['role']>();\n readonly message = input<AIMessage>();\n private readonly translateService = inject(TranslateService);\n\n private readonly roleResolved = computed(() => {\n return this.message()?.role || this.role();\n });\n\n /**\n * Generates an accessible label for the message container.\n * Includes the role (user or assistant) and timestamp if available.\n * @returns The aria-label string for screen readers\n */\n readonly ariaLabel = computed(() => {\n const tpl =\n this.roleResolved() === 'user'\n ? gettext('You said: \"{{ message }}\"')\n : gettext('Assistant said: \"{{ message }}\"');\n const msg = this.message();\n return this.translateService.instant(tpl, { message: msg?.content || gettext('No response.') });\n });\n\n /**\n * Generates an accessible label for the message content.\n * Prefixes the content with contextual information about who sent it.\n * @returns The aria-label string with prefixed role information\n */\n readonly messageContentAriaLabel = computed(() => {\n const msg = this.message();\n const time = msg?.timestamp ? new Date(msg.timestamp).toLocaleTimeString() : '';\n let tpl: string;\n if (time) {\n tpl =\n this.roleResolved() === 'user'\n ? gettext('User message at {{ time }}')\n : gettext('Assistant message at {{ time }}');\n } else {\n tpl = this.roleResolved() === 'user' ? gettext('User message') : gettext('Assistant message');\n }\n return this.translateService.instant(tpl, { time });\n });\n}\n","<div\n class=\"d-col p-b-16\"\n [attr.aria-label]=\"ariaLabel()\"\n role=\"article\"\n>\n <div\n class=\"chat-message text-break-word\"\n [ngClass]=\"{\n 'user-message': message()?.role === 'user' || role() === 'user',\n 'agent-message': message()?.role === 'assistant' || role() === 'assistant'\n }\"\n >\n <div\n class=\"message-content\"\n [attr.aria-label]=\"messageContentAriaLabel()\"\n [innerHTML]=\"message()?.content | markdownToHtml | async\"\n ></div>\n <ng-content select=\":not(c8y-ai-chat-message-action)\"></ng-content>\n @if (message()?.timestamp) {\n <div class=\"message-timestamp\">\n <span [tooltip]=\"message()?.timestamp | c8yDate\">\n {{ message()?.timestamp | c8yDate: 'adaptiveDate' }}\n </span>\n </div>\n }\n </div>\n <div\n class=\"message-action\"\n [attr.aria-label]=\"'Message actions' | translate\"\n role=\"toolbar\"\n [ngClass]=\"{\n 'user-action showOnHover': message()?.role === 'user' || role() === 'user',\n 'agent-action p-l-16': message()?.role === 'assistant' || role() === 'assistant'\n }\"\n >\n <ng-content select=\"c8y-ai-chat-message-action\"></ng-content>\n </div>\n</div>\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { C8yTranslatePipe, IconDirective } from '@c8y/ngx-components';\nimport { AIMessage } from '@c8y/ngx-components/ai';\nimport { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';\n\n/**\n * A suggestion chip that can be displayed in the chat interface.\n * When clicked, it automatically populates and sends a predefined prompt.\n */\n@Component({\n selector: 'c8y-ai-chat-suggestion',\n templateUrl: './ai-chat-suggestion.component.html',\n standalone: true,\n imports: [IconDirective, C8yTranslatePipe]\n})\nexport class AiChatSuggestionComponent {\n /**\n * The visible label text displayed on the suggestion chip.\n */\n @Input()\n label: string;\n\n /**\n * The prompt text that will be sent when the suggestion is clicked.\n */\n @Input()\n prompt: string;\n\n /**\n * Icon to display alongside the suggestion label.\n */\n @Input()\n icon: SupportedIconsSuggestions = 'c8y-bulb';\n\n /**\n * When true, uses AI-styled buttons instead of default styling.\n */\n @Input()\n useAiButtons = false;\n\n /**\n * Disables the suggestion chip when true.\n */\n @Input()\n disabled = false;\n\n /**\n * Emitted when the suggestion is clicked, providing the prompt as an AIMessage.\n */\n @Output()\n suggestionClicked = new EventEmitter<AIMessage>();\n\n /**\n * Handles suggestion click and emits the prompt as a user message.\n */\n suggest() {\n this.suggestionClicked.emit({\n content: this.prompt,\n role: 'user',\n timestamp: new Date().toISOString()\n });\n }\n}\n","@if (!useAiButtons) {\n <button\n class=\"btn btn-default btn-sm\"\n [title]=\"prompt | translate\"\n (click)=\"suggest()\"\n [disabled]=\"disabled\"\n >\n <i [c8yIcon]=\"icon\"></i>\n {{ label | translate }}\n </button>\n} @else {\n <button\n class=\"btn btn-sm btn-ai\"\n [title]=\"prompt | translate\"\n (click)=\"suggest()\"\n [disabled]=\"disabled\"\n >\n <span>{{ label | translate }}</span>\n </button>\n}\n","import { NgClass } from '@angular/common';\nimport { Component, ContentChildren, EventEmitter, Input, Output, QueryList } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { C8yTranslatePipe, IconDirective, TextareaAutoresizeDirective } from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AIMessage, ChatConfig } from '@c8y/ngx-components/ai';\nimport { AiChatMessageComponent } from './ai-chat-message.component';\n\n/**\n * An interactive chat interface component for AI-powered conversations.\n * Displays messages in a conversation format with support for loading states,\n * custom configuration, and markdown formatting.\n */\n@Component({\n selector: 'c8y-ai-chat',\n templateUrl: './ai-chat.component.html',\n imports: [C8yTranslatePipe, FormsModule, TextareaAutoresizeDirective, IconDirective, NgClass],\n standalone: true,\n host: { class: 'd-contents' }\n})\nexport class AiChatComponent {\n /**\n * Indicates whether the chat is currently processing a request.\n * When true, displays a cancel button instead of send button and disables the input.\n */\n @Input()\n isLoading = false;\n\n /**\n * Disables the chat input and send button when true.\n */\n @Input()\n disabled = false;\n\n /**\n * The current text in the chat input field. Supports two-way binding.\n */\n @Input()\n prompt = '';\n\n /**\n * Emitted when the user sends a message.\n * Provides an AIMessage object with role, content, and timestamp.\n */\n @Output()\n onMessage = new EventEmitter<AIMessage>();\n\n /**\n * Emitted when the user cancels an ongoing operation during loading state.\n */\n @Output()\n onCancel = new EventEmitter<void>();\n\n /**\n * Child message components displayed in the chat.\n */\n @ContentChildren(AiChatMessageComponent) messages: QueryList<AiChatMessageComponent>;\n\n readonly componentId = `chat-${crypto.randomUUID()}`;\n\n private _config: ChatConfig = {\n headline: gettext('Welcome!'),\n welcomeText: '',\n title: gettext('What can I help you with?'),\n placeholder: gettext('Type your message here…'),\n placeholderAfterFirstMessage: gettext('Type your next message here…'),\n sendButtonText: gettext('Send'),\n cancelButtonText: gettext('Cancel'),\n disclaimerText: gettext(\n 'AI-generated responses can contain errors. Verify the details before use.'\n ),\n userInterfaceIcons: {\n send: 'arrow-circle-up',\n cancel: 'stop-circle'\n }\n };\n\n /**\n * Configuration object for customizing labels, placeholders, and icons.\n * Accepts partial configuration to override defaults.\n */\n @Input()\n set config(value: Partial<ChatConfig>) {\n this._config = { ...this._config, ...value };\n }\n get config() {\n return this._config;\n }\n\n /**\n * Handles message submission when the user sends a message.\n * Emits the onMessage event and clears the input.\n * @param $event - The event object from the form submission\n */\n sendMessage($event: Event): void {\n $event.preventDefault();\n if (!this.prompt) return;\n this.onMessage.emit({\n role: 'user',\n content: this.prompt,\n timestamp: new Date().toISOString()\n });\n // this.prompt = '';\n }\n\n /**\n * Handles cancellation of ongoing operations during loading state.\n * Emits the onCancel event.\n */\n cancel(): void {\n this.onCancel.emit();\n }\n}\n","<div\n class=\"d-col fit-h fit-w flex-grow\"\n [attr.aria-label]=\"config.headline | translate\"\n role=\"region\"\n>\n @if (messages.length > 0) {\n <div\n class=\"inner-scroll flex-grow d-col-reverse min-height-0 bg-level-0\"\n [attr.aria-label]=\"'Chat conversation' | translate\"\n aria-live=\"polite\"\n aria-atomic=\"false\"\n role=\"log\"\n >\n <div class=\"d-col p-l-16 p-r-16\">\n <ng-content select=\"c8y-ai-chat-message\"></ng-content>\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div [ngClass]=\"{ 'd-col fit-h': messages.length === 0 }\">\n @if (messages.length === 0) {\n <div\n class=\"p-24\"\n aria-live=\"polite\"\n role=\"status\"\n >\n <h4 class=\"m-b-16 text-medium\">{{ config.headline | translate }}</h4>\n <p class=\"p-b-8 text-balance\">{{ config.title | translate }}</p>\n <p class=\"text-muted text-balance\">{{ config.welcomeText | translate }}</p>\n </div>\n }\n <div class=\"chat-input bg-level-1\">\n <div class=\"d-flex inner-scroll a-i-center gap-8 p-l-16 p-r-16 p-b-8\">\n <ng-content select=\"c8y-ai-chat-suggestion\"></ng-content>\n </div>\n <div class=\"chat-input-group\">\n <label\n class=\"sr-only\"\n for=\"chat-input-{{ componentId }}\"\n >\n {{ config.placeholder | translate }}\n </label>\n <textarea\n class=\"form-control no-resize\"\n style=\"max-height: 200px !important\"\n [attr.aria-label]=\"config.placeholder | translate\"\n id=\"chat-input-{{ componentId }}\"\n [attr.aria-describedby]=\"config.disclaimerText ? 'chat-disclaimer-' + componentId : null\"\n [attr.aria-busy]=\"isLoading\"\n [placeholder]=\"\n (messages.length === 0 ? config.placeholder : config.placeholderAfterFirstMessage)\n | translate\n \"\n [(ngModel)]=\"prompt\"\n (keydown.enter)=\"sendMessage($event)\"\n [disabled]=\"isLoading || disabled\"\n c8y-textarea-autoresize\n ></textarea>\n <div class=\"chat-input-group-btn\">\n @if (!isLoading) {\n <button\n class=\"btn btn-dot\"\n [attr.title]=\"config.sendButtonText | translate\"\n [attr.aria-label]=\"config.sendButtonText | translate\"\n type=\"button\"\n (click)=\"sendMessage($event)\"\n [disabled]=\"disabled || prompt.trim().length === 0\"\n >\n <i [c8yIcon]=\"config.userInterfaceIcons?.send || 'arrow-circle-right'\"></i>\n </button>\n } @else {\n <button\n class=\"btn btn-dot btn-dot--danger\"\n [attr.title]=\"config.cancelButtonText | translate\"\n [attr.aria-label]=\"config.cancelButtonText | translate\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n <i [c8yIcon]=\"config.userInterfaceIcons?.cancel || 'stop'\"></i>\n </button>\n }\n </div>\n </div>\n @if (config.disclaimerText) {\n <div\n class=\"text-muted m-b-8 text-10 p-l-16\"\n id=\"chat-disclaimer-{{ componentId }}\"\n role=\"note\"\n >\n {{ config.disclaimerText | translate }}\n </div>\n }\n </div>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
@@ -1,12 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable } from '@angular/core';
3
- import * as i1 from '@c8y/client';
2
+ import { inject, Injectable } from '@angular/core';
3
+ import { FetchClient } from '@c8y/client';
4
4
  import { Observable } from 'rxjs';
5
5
 
6
6
  var DataStreamType;
7
7
  (function (DataStreamType) {
8
8
  DataStreamType["TEXT_DELTA"] = "text-delta";
9
9
  DataStreamType["TOOL_CALL"] = "tool-call";
10
+ DataStreamType["TOOL_INPUT_START"] = "tool-input-start";
11
+ DataStreamType["TOOL_INPUT_DELTA"] = "tool-input-delta";
10
12
  DataStreamType["TOOL_CALL_STREAMING"] = "tool-call-streaming";
11
13
  DataStreamType["TOOL_CALL_DELTA"] = "tool-call-delta";
12
14
  DataStreamType["TOOL_RESULT"] = "tool-result";
@@ -29,36 +31,39 @@ var DataStreamType;
29
31
  })(DataStreamType || (DataStreamType = {}));
30
32
 
31
33
  class AIService {
32
- constructor(client) {
33
- this.client = client;
34
+ constructor() {
34
35
  this.baseUrl = '/service/ai';
36
+ this.client = inject(FetchClient);
35
37
  }
36
- async createOrUpdateAgent(agentsDef) {
37
- for (const def of agentsDef.definitions) {
38
- const health = await this.getAgentHealth(def.name);
39
- let resource = `${this.baseUrl}/agent/${def.type}`;
40
- let method = 'POST';
41
- if (health.exists) {
42
- resource = `${this.baseUrl}/agent/${def.type}/${def.name}`;
43
- method = 'PUT';
44
- }
45
- const response = await this.client.fetch(resource, {
46
- body: JSON.stringify(def),
47
- method,
48
- headers: { 'Content-Type': 'application/json' }
49
- });
50
- if (!response.ok) {
51
- throw new Error(`Failed to create agent: ${response.statusText}`);
52
- }
38
+ /**
39
+ * Creates or updates an agent.
40
+ * @param def The agent definition
41
+ */
42
+ async createOrUpdateAgent(def) {
43
+ const health = await this.getAgentHealth(def.name);
44
+ let resource = `${this.baseUrl}/agent/${def.type}`;
45
+ let method = 'POST';
46
+ if (health.exists) {
47
+ resource = `${this.baseUrl}/agent/${def.type}/${def.name}`;
48
+ method = 'PUT';
49
+ }
50
+ const response = await this.client.fetch(resource, {
51
+ body: JSON.stringify(def),
52
+ method,
53
+ headers: { 'Content-Type': 'application/json' }
54
+ });
55
+ if (!response.ok) {
56
+ throw new Error(`Failed to create agent: ${response.statusText}`);
53
57
  }
54
58
  }
55
59
  /**
56
60
  * Check if an agent exists.
57
- * @param name Agent name
61
+ * @param name Agent name (optional)
62
+ * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).
58
63
  * @returns Agent health check response.
59
64
  */
60
- async getAgentHealth(name) {
61
- const response = await this.client.fetch(`${this.baseUrl}/agent/test/${name}`, {
65
+ async getAgentHealth(name = '', fromApp) {
66
+ const response = await this.client.fetch(`${this.baseUrl}/agent/test/${name || crypto.randomUUID()}${fromApp ? `?fromApp=${fromApp}` : ''}`, {
62
67
  method: 'GET',
63
68
  headers: { 'Content-Type': 'application/json' }
64
69
  });
@@ -77,11 +82,12 @@ class AIService {
77
82
  * @param name Agent name
78
83
  * @param messages Messages to send
79
84
  * @param variables Variables to include
85
+ * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).
80
86
  * @returns Text response from the agent.
81
87
  */
82
- async text(name, messages, variables) {
88
+ async text(name, messages, variables, fromApp) {
83
89
  const parsedMessages = this.parseMessages(messages);
84
- const data = this.client.fetch(`${this.baseUrl}/agent/text/${name}`, {
90
+ const data = this.client.fetch(`${this.baseUrl}/agent/text/${name}${fromApp ? `?fromApp=${fromApp}` : ''}`, {
85
91
  body: JSON.stringify({ messages: parsedMessages, variables }),
86
92
  method: 'POST',
87
93
  headers: { 'Content-Type': 'application/json' }
@@ -95,10 +101,11 @@ class AIService {
95
101
  }
96
102
  /**
97
103
  * Stream a text message to the agent.
98
- * @param agentName Agent name
104
+ * @param agent Agent name or an agent definition.
99
105
  * @param messages Messages to send
100
106
  * @param variables Variables to include
101
107
  * @param abortController An AbortController to cancel the request.
108
+ * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).
102
109
  * @returns An observable that emits partial AIMessage objects as they are received. The observable can be cancelled using the provided AbortController.
103
110
  * The observable will emit an error if the request fails or is aborted.
104
111
  * The observable will complete when the stream is finished.
@@ -127,11 +134,25 @@ class AIService {
127
134
  * subscription.unsubscribe();
128
135
  * ```
129
136
  */
130
- async stream$(agentName, messages, variables, abortController) {
137
+ async stream$(agent, messages, variables, abortController, fromApp) {
131
138
  const parsedMessages = this.parseMessages(messages);
132
- const response = await this.client.fetch(`${this.baseUrl}/agent/text/${agentName}?fullResponse=true`, {
139
+ const agentName = typeof agent === 'string' ? agent : agent.definition.name;
140
+ const useTest = typeof agent !== 'string' && agent.snapshot;
141
+ const baseUrl = useTest
142
+ ? `${this.baseUrl}/agent/test/text`
143
+ : `${this.baseUrl}/agent/text/${agentName}`;
144
+ let body = JSON.stringify({ messages: parsedMessages, variables });
145
+ if (useTest) {
146
+ const agentCopy = {
147
+ ...agent.definition
148
+ };
149
+ agentCopy.agent.messages = parsedMessages;
150
+ agentCopy.agent.variables = variables;
151
+ body = JSON.stringify(agentCopy);
152
+ }
153
+ const response = await this.client.fetch(`${baseUrl}?fullResponse=true${fromApp ? `&fromApp=${fromApp}` : ''}`, {
133
154
  method: 'POST',
134
- body: JSON.stringify({ messages: parsedMessages, variables }),
155
+ body,
135
156
  headers: {
136
157
  ...this.client.defaultHeaders,
137
158
  'content-type': 'application/json',
@@ -207,7 +228,12 @@ class AIService {
207
228
  if (!line.trim()) {
208
229
  return;
209
230
  }
210
- const lastStep = message.steps?.[message.steps.length - 1];
231
+ const lastStep = message.steps?.[message.steps.length - 1] || {
232
+ type: 'text',
233
+ toolCalls: [],
234
+ toolResults: [],
235
+ text: ''
236
+ };
211
237
  try {
212
238
  let data = {};
213
239
  let type = '';
@@ -241,6 +267,10 @@ class AIService {
241
267
  message.content += data.text || data.textDelta;
242
268
  observer.next(message);
243
269
  return;
270
+ case DataStreamType.TOOL_INPUT_START:
271
+ lastStep.toolCalls = [data];
272
+ observer.next(message);
273
+ return;
244
274
  case DataStreamType.TOOL_CALL:
245
275
  lastStep.toolCalls = [data];
246
276
  observer.next(message);
@@ -275,7 +305,7 @@ class AIService {
275
305
  observer.error(e);
276
306
  }
277
307
  }
278
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AIService, deps: [{ token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
308
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AIService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
279
309
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AIService, providedIn: 'root' }); }
280
310
  }
281
311
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AIService, decorators: [{
@@ -283,7 +313,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
283
313
  args: [{
284
314
  providedIn: 'root'
285
315
  }]
286
- }], ctorParameters: () => [{ type: i1.FetchClient }] });
316
+ }] });
287
317
 
288
318
  /**
289
319
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-ai.mjs","sources":["../../ai/ai.model.ts","../../ai/ai.service.ts","../../ai/c8y-ngx-components-ai.ts"],"sourcesContent":["import { Type } from '@angular/core';\nimport { Observable } from 'rxjs';\n\nexport interface AIMessageStreamSteps extends AIMessage {\n componentSteps$?: Observable<{ content: Type<any> | string; origin: AgentStep }[]>;\n}\n\nexport interface AIMessage {\n role: 'user' | 'assistant';\n content: string;\n options?: AIMessageOptions;\n steps?: Array<AgentStep>;\n finishReason?: 'stop' | 'error' | 'tool_use';\n timestamp?: string;\n}\n\nexport interface AIMessageOptions {\n skipToLLM?: boolean;\n hiddenContent?: string;\n variables?: { [key: string]: any };\n}\n\nexport enum DataStreamType {\n TEXT_DELTA = 'text-delta',\n TOOL_CALL = 'tool-call',\n TOOL_CALL_STREAMING = 'tool-call-streaming',\n TOOL_CALL_DELTA = 'tool-call-delta',\n TOOL_RESULT = 'tool-result',\n REASONING = 'reasoning',\n REASONING_DELTA = 'reasoning-delta',\n REDACTED_REASONING = 'redacted-reasoning',\n REASONING_SIGNATURE = 'reasoning-signature',\n FINISH_REASONING = 'finish-reasoning',\n FINISH = 'finish',\n FINISH_STEP = 'finish-step',\n ERROR = 'error',\n DATA = 'data',\n MESSAGE_ANNOTATIONS = 'message-annotations',\n SOURCE = 'source',\n FILE = 'file',\n STEP_START = 'start-step',\n STEP_FINISH = 'finish-step',\n STEP_START_V4 = 'step-start',\n STEP_FINISH_V4 = 'step-finish'\n}\n\nexport type AgentStep = {\n type: 'text' | 'reasoning' | string;\n text: string;\n reasoning?: string;\n textDelta?: string;\n toolCalls?: Array<ToolCall>;\n toolResults?: Array<ToolResult>;\n aborted?: boolean;\n};\n\nexport interface Tool {\n toolName: string;\n toolId: string;\n type: 'tool-call' | 'tool-result';\n}\n\nexport interface ToolCall extends Tool {\n arguments: { [key: string]: any };\n}\n\nexport interface ToolResult extends Tool {\n result: {\n content: {\n text: string;\n type: string;\n }[];\n };\n}\n\nexport interface ClientAgentDefinition {\n /**\n * If set to true, the agent will be created each time. This is useful for development.\n */\n snapshot: boolean;\n /**\n * The label of the agent that is shown to the user.\n */\n label: string;\n /**\n * The definitions of the agent.\n *\n * You can use multiple definitions that can be used in an agent-2-agent scenario\n * The first definition is the entry point.\n */\n definitions: {\n name: string;\n type: 'object' | 'text';\n agent: {\n system: string;\n [key: string]: any;\n };\n mcp: Array<{ serverName: string; tools: string[] }>;\n }[];\n}\n\nexport interface ChatConfig {\n title: string;\n headline: string;\n welcomeText: string;\n placeholder: string;\n sendButtonText: string;\n cancelButtonText: string;\n disclaimerText: string;\n userInterfaceIcons: { send: string; cancel: string };\n}\n\nexport interface AgentHealthCheckResponse {\n /**\n * Indicates if the agent exists and can be used.\n * If false, the agent was not found.\n */\n exists: boolean;\n /**\n * Indicates if the user can create the agent, and if a global provider is configured.\n */\n canCreate: boolean;\n /**\n * Indicates if the provider is configured.\n * If false, the agent cannot be created as the provider is not configured.\n */\n isProviderConfigured: boolean;\n /**\n * If canCreate or exist is false, this array contains messages\n * that explain why the agent cannot be used or created.\n */\n messages?: string[];\n}\n","import { Injectable } from '@angular/core';\nimport {\n AgentHealthCheckResponse,\n AIMessage,\n ClientAgentDefinition,\n DataStreamType\n} from './ai.model';\nimport { FetchClient } from '@c8y/client';\nimport { Observable } from 'rxjs';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AIService {\n private baseUrl = '/service/ai';\n\n constructor(private client: FetchClient) {}\n\n async createOrUpdateAgent(agentsDef: ClientAgentDefinition): Promise<void> {\n for (const def of agentsDef.definitions) {\n const health = await this.getAgentHealth(def.name);\n let resource = `${this.baseUrl}/agent/${def.type}`;\n let method = 'POST';\n if (health.exists) {\n resource = `${this.baseUrl}/agent/${def.type}/${def.name}`;\n method = 'PUT';\n }\n const response = await this.client.fetch(resource, {\n body: JSON.stringify(def),\n method,\n headers: { 'Content-Type': 'application/json' }\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create agent: ${response.statusText}`);\n }\n }\n }\n\n /**\n * Check if an agent exists.\n * @param name Agent name\n * @returns Agent health check response.\n */\n async getAgentHealth(name: string): Promise<AgentHealthCheckResponse> {\n const response = await this.client.fetch(`${this.baseUrl}/agent/test/${name}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n });\n\n if (!response.ok) {\n return {\n exists: false,\n canCreate: false,\n isProviderConfigured: false\n };\n }\n const json = await response.json();\n return json;\n }\n\n /**\n * Send a text message to the agent.\n * @param name Agent name\n * @param messages Messages to send\n * @param variables Variables to include\n * @returns Text response from the agent.\n */\n async text(\n name: string,\n messages: AIMessage[],\n variables: { [key: string]: any }\n ): Promise<string> {\n const parsedMessages = this.parseMessages(messages);\n\n const data = this.client.fetch(`${this.baseUrl}/agent/text/${name}`, {\n body: JSON.stringify({ messages: parsedMessages, variables }),\n method: 'POST',\n headers: { 'Content-Type': 'application/json' }\n });\n\n const response = await data;\n if (!response.ok) {\n throw new Error(`Failed to talk with agent: ${response.statusText}`);\n }\n const text = await response.text();\n return text;\n }\n\n /**\n * Stream a text message to the agent.\n * @param agentName Agent name\n * @param messages Messages to send\n * @param variables Variables to include\n * @param abortController An AbortController to cancel the request.\n * @returns An observable that emits partial AIMessage objects as they are received. The observable can be cancelled using the provided AbortController.\n * The observable will emit an error if the request fails or is aborted.\n * The observable will complete when the stream is finished.\n *\n * The messages sent to the agent can include special options:\n * - `hiddenContent`: If set, this content will be sent to the agent instead of the `content` field.\n * - `skipToLLM`: If set to true, this message will be skipped when sending to the agent.\n *\n * Example usage:\n * ```typescript\n * const abortController = new AbortController();\n * const messages: AIMessage[] = [\n * { role: 'user', content: 'Hello' },\n * { role: 'assistant', content: 'Hi there!' },\n * { role: 'user', content: 'Tell me a joke.', options: { hiddenContent: 'Tell me a joke about cats.' } }\n * ];\n * const observable = aiService.stream$('my-agent', messages, {}, abortController);\n * const subscription = observable.subscribe({\n * next: (message) => console.log('Received message part:', message),\n * error: (err) => console.error('Error:', err),\n * complete: () => console.log('Stream complete')\n * });\n *\n * // To cancel the request:\n * abortController.abort();\n * subscription.unsubscribe();\n * ```\n */\n async stream$(\n agentName: string,\n messages: AIMessage[],\n variables: { [key: string]: any },\n abortController: AbortController\n ): Promise<Observable<AIMessage>> {\n const parsedMessages = this.parseMessages(messages);\n const response = await this.client.fetch(\n `${this.baseUrl}/agent/text/${agentName}?fullResponse=true`,\n {\n method: 'POST',\n body: JSON.stringify({ messages: parsedMessages, variables }),\n headers: {\n ...this.client.defaultHeaders,\n 'content-type': 'application/json',\n accept: 'text/event-stream'\n },\n signal: abortController.signal\n }\n );\n\n if (response.status > 300) {\n const data = await response.json();\n throw new Error(JSON.stringify(data, null, 2));\n }\n\n const stream = response.body;\n const decoder = new TextDecoder();\n\n return new Observable<AIMessage>(observer => {\n if (!stream) {\n observer.error('No response body');\n throw 'No response body';\n }\n\n const reader = stream.getReader();\n const message: AIMessage = {\n role: 'assistant',\n content: '',\n steps: []\n };\n\n const abortHandler = () => {\n reader.cancel();\n observer.error(new DOMException('Aborted', 'AbortError'));\n };\n\n abortController.signal.addEventListener('abort', abortHandler);\n\n let buffer = '';\n\n const read = () => {\n reader.read().then(({ done, value }) => {\n if (done) {\n if (buffer.trim()) this.processLine(buffer, observer, message); // process any remaining data\n observer.complete();\n return;\n }\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n\\n');\n buffer = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) this.processLine(line, observer, message);\n }\n read();\n });\n };\n\n read();\n return () => {\n abortController.signal.removeEventListener('abort', abortHandler);\n reader.cancel();\n };\n });\n }\n\n private parseMessages(messages: AIMessage[]) {\n return messages\n .filter(message => !message.options?.skipToLLM)\n .map(message => {\n if (message.options?.hiddenContent) {\n return {\n role: message.role,\n content: message.options.hiddenContent\n };\n }\n return {\n role: message.role,\n content: message.content\n };\n });\n }\n\n private processLine(line: string, observer: any, message: AIMessage) {\n if (!line.trim()) {\n return;\n }\n const lastStep = message.steps?.[message.steps.length - 1];\n try {\n let data: any = {};\n let type = '';\n try {\n data = JSON.parse(line.replace('data: ', ''));\n type = data.type;\n } catch (e) {\n console.error('Error parsing line', line, e);\n return;\n }\n\n switch (type) {\n case DataStreamType.STEP_START || DataStreamType.STEP_START_V4:\n message.steps = message.steps || [];\n message.steps.push({\n type: 'text',\n toolCalls: [],\n toolResults: [],\n text: ''\n });\n return;\n\n case DataStreamType.REASONING:\n if (lastStep!.reasoning === undefined) {\n lastStep!.reasoning = '';\n }\n lastStep!.reasoning += data.text || data.textDelta;\n observer.next(message);\n return;\n\n case DataStreamType.TEXT_DELTA:\n lastStep!.text += data.text || data.textDelta;\n message.content += data.text || data.textDelta;\n observer.next(message);\n return;\n\n case DataStreamType.TOOL_CALL:\n lastStep!.toolCalls = [data];\n observer.next(message);\n return;\n\n case DataStreamType.TOOL_RESULT:\n lastStep!.toolResults = [data];\n observer.next(message);\n return;\n\n case DataStreamType.FINISH:\n message.finishReason = data.finishReason;\n observer.next(message);\n observer.complete();\n return;\n\n case DataStreamType.ERROR:\n message.finishReason = 'error';\n const errorMessage = `<div\n class=\"alert alert-danger\"\n role=\"alert\"\n >\n <strong>Error</strong>\n ${data.message || 'An unknown error occurred'}\n </div>`;\n message.content += errorMessage;\n lastStep!.text += errorMessage;\n observer.next(message);\n observer.error(data);\n observer.complete();\n return;\n }\n } catch (e) {\n observer.error(e);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-ai.mjs","sources":["../../ai/ai.model.ts","../../ai/ai.service.ts","../../ai/c8y-ngx-components-ai.ts"],"sourcesContent":["import { Type } from '@angular/core';\nimport { Observable } from 'rxjs';\n\nexport interface AIMessageStreamSteps extends AIMessage {\n componentSteps$?: Observable<{ content: Type<any> | string; origin: AgentStep }[]>;\n}\n\nexport interface AIMessage {\n role: 'user' | 'assistant';\n content: string;\n options?: AIMessageOptions;\n steps?: Array<AgentStep>;\n finishReason?: 'stop' | 'error' | 'tool_use';\n timestamp?: string;\n}\n\nexport interface AIMessageOptions {\n skipToLLM?: boolean;\n hiddenContent?: string;\n variables?: { [key: string]: any };\n}\n\nexport enum DataStreamType {\n TEXT_DELTA = 'text-delta',\n TOOL_CALL = 'tool-call',\n TOOL_INPUT_START = 'tool-input-start',\n TOOL_INPUT_DELTA = 'tool-input-delta',\n TOOL_CALL_STREAMING = 'tool-call-streaming',\n TOOL_CALL_DELTA = 'tool-call-delta',\n TOOL_RESULT = 'tool-result',\n REASONING = 'reasoning',\n REASONING_DELTA = 'reasoning-delta',\n REDACTED_REASONING = 'redacted-reasoning',\n REASONING_SIGNATURE = 'reasoning-signature',\n FINISH_REASONING = 'finish-reasoning',\n FINISH = 'finish',\n FINISH_STEP = 'finish-step',\n ERROR = 'error',\n DATA = 'data',\n MESSAGE_ANNOTATIONS = 'message-annotations',\n SOURCE = 'source',\n FILE = 'file',\n STEP_START = 'start-step',\n STEP_FINISH = 'finish-step',\n STEP_START_V4 = 'step-start',\n STEP_FINISH_V4 = 'step-finish'\n}\n\nexport type AgentStep = {\n type: 'text' | 'reasoning' | string;\n text: string;\n reasoning?: string;\n textDelta?: string;\n toolCalls?: Array<ToolCall>;\n toolResults?: Array<ToolResult>;\n aborted?: boolean;\n};\n\nexport interface Tool {\n toolName: string;\n toolCallId: string;\n type: 'tool-call' | 'tool-result';\n}\n\nexport interface ToolCall extends Tool {\n arguments: { [key: string]: any };\n}\n\nexport interface ToolResult extends Tool {\n input: any;\n output: {\n content: {\n text: string;\n type: string;\n }[];\n };\n}\n\nexport interface ClientAgentDefinition {\n /**\n * If set to true, the agent will use the test endpoint to generate responses.\n * This is useful for development and testing purposes, but requires agent admin\n * privileges.\n */\n snapshot: boolean;\n /**\n * The label of the agent that is shown to the user.\n */\n label: string;\n /**\n * The definition of the agent to use\n */\n definition: AgentDefinition;\n}\n\nexport interface AgentDefinition {\n name: string;\n type: 'object' | 'text';\n agent: {\n system: string;\n [key: string]: any;\n };\n mcp: Array<{ serverName: string; tools: string[] }>;\n}\n\nexport interface ChatConfig {\n title: string;\n headline: string;\n welcomeText: string;\n placeholder: string;\n placeholderAfterFirstMessage: string;\n sendButtonText: string;\n cancelButtonText: string;\n disclaimerText: string;\n userInterfaceIcons: { send: string; cancel: string };\n}\n\nexport interface AgentHealthCheckResponse {\n /**\n * Indicates if the agent exists and can be used.\n * If false, the agent was not found.\n */\n exists: boolean;\n /**\n * Indicates if the user can create the agent, and if a global provider is configured.\n */\n canCreate: boolean;\n /**\n * Indicates if the provider is configured.\n * If false, the agent cannot be created as the provider is not configured.\n */\n isProviderConfigured: boolean;\n /**\n * If canCreate or exist is false, this array contains messages\n * that explain why the agent cannot be used or created.\n */\n messages?: string[];\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FetchClient } from '@c8y/client';\nimport { Observable } from 'rxjs';\nimport {\n AgentDefinition,\n AgentHealthCheckResponse,\n AIMessage,\n ClientAgentDefinition,\n DataStreamType\n} from './ai.model';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AIService {\n private baseUrl = '/service/ai';\n\n private client = inject(FetchClient);\n\n /**\n * Creates or updates an agent.\n * @param def The agent definition\n */\n async createOrUpdateAgent(def: AgentDefinition): Promise<void> {\n const health = await this.getAgentHealth(def.name);\n let resource = `${this.baseUrl}/agent/${def.type}`;\n let method = 'POST';\n if (health.exists) {\n resource = `${this.baseUrl}/agent/${def.type}/${def.name}`;\n method = 'PUT';\n }\n const response = await this.client.fetch(resource, {\n body: JSON.stringify(def),\n method,\n headers: { 'Content-Type': 'application/json' }\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create agent: ${response.statusText}`);\n }\n }\n\n /**\n * Check if an agent exists.\n * @param name Agent name (optional)\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns Agent health check response.\n */\n async getAgentHealth(name = '', fromApp?: string): Promise<AgentHealthCheckResponse> {\n const response = await this.client.fetch(\n `${this.baseUrl}/agent/test/${name || crypto.randomUUID()}${fromApp ? `?fromApp=${fromApp}` : ''}`,\n {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n if (!response.ok) {\n return {\n exists: false,\n canCreate: false,\n isProviderConfigured: false\n };\n }\n const json = await response.json();\n return json;\n }\n\n /**\n * Send a text message to the agent.\n * @param name Agent name\n * @param messages Messages to send\n * @param variables Variables to include\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns Text response from the agent.\n */\n async text(\n name: string,\n messages: AIMessage[],\n variables: { [key: string]: any },\n fromApp?: string\n ): Promise<string> {\n const parsedMessages = this.parseMessages(messages);\n\n const data = this.client.fetch(\n `${this.baseUrl}/agent/text/${name}${fromApp ? `?fromApp=${fromApp}` : ''}`,\n {\n body: JSON.stringify({ messages: parsedMessages, variables }),\n method: 'POST',\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n const response = await data;\n if (!response.ok) {\n throw new Error(`Failed to talk with agent: ${response.statusText}`);\n }\n const text = await response.text();\n return text;\n }\n\n /**\n * Stream a text message to the agent.\n * @param agent Agent name or an agent definition.\n * @param messages Messages to send\n * @param variables Variables to include\n * @param abortController An AbortController to cancel the request.\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns An observable that emits partial AIMessage objects as they are received. The observable can be cancelled using the provided AbortController.\n * The observable will emit an error if the request fails or is aborted.\n * The observable will complete when the stream is finished.\n *\n * The messages sent to the agent can include special options:\n * - `hiddenContent`: If set, this content will be sent to the agent instead of the `content` field.\n * - `skipToLLM`: If set to true, this message will be skipped when sending to the agent.\n *\n * Example usage:\n * ```typescript\n * const abortController = new AbortController();\n * const messages: AIMessage[] = [\n * { role: 'user', content: 'Hello' },\n * { role: 'assistant', content: 'Hi there!' },\n * { role: 'user', content: 'Tell me a joke.', options: { hiddenContent: 'Tell me a joke about cats.' } }\n * ];\n * const observable = aiService.stream$('my-agent', messages, {}, abortController);\n * const subscription = observable.subscribe({\n * next: (message) => console.log('Received message part:', message),\n * error: (err) => console.error('Error:', err),\n * complete: () => console.log('Stream complete')\n * });\n *\n * // To cancel the request:\n * abortController.abort();\n * subscription.unsubscribe();\n * ```\n */\n async stream$(\n agent: string | ClientAgentDefinition,\n messages: AIMessage[],\n variables: { [key: string]: any },\n abortController: AbortController,\n fromApp?: string\n ): Promise<Observable<AIMessage>> {\n const parsedMessages = this.parseMessages(messages);\n const agentName = typeof agent === 'string' ? agent : agent.definition.name;\n const useTest = typeof agent !== 'string' && agent.snapshot;\n const baseUrl = useTest\n ? `${this.baseUrl}/agent/test/text`\n : `${this.baseUrl}/agent/text/${agentName}`;\n let body = JSON.stringify({ messages: parsedMessages, variables });\n if (useTest) {\n const agentCopy = {\n ...agent.definition\n };\n agentCopy.agent.messages = parsedMessages;\n agentCopy.agent.variables = variables;\n body = JSON.stringify(agentCopy);\n }\n\n const response = await this.client.fetch(\n `${baseUrl}?fullResponse=true${fromApp ? `&fromApp=${fromApp}` : ''}`,\n {\n method: 'POST',\n body,\n headers: {\n ...this.client.defaultHeaders,\n 'content-type': 'application/json',\n accept: 'text/event-stream'\n },\n signal: abortController.signal\n }\n );\n\n if (response.status > 300) {\n const data = await response.json();\n throw new Error(JSON.stringify(data, null, 2));\n }\n\n const stream = response.body;\n const decoder = new TextDecoder();\n\n return new Observable<AIMessage>(observer => {\n if (!stream) {\n observer.error('No response body');\n throw 'No response body';\n }\n\n const reader = stream.getReader();\n const message: AIMessage = {\n role: 'assistant',\n content: '',\n steps: []\n };\n\n const abortHandler = () => {\n reader.cancel();\n observer.error(new DOMException('Aborted', 'AbortError'));\n };\n\n abortController.signal.addEventListener('abort', abortHandler);\n\n let buffer = '';\n\n const read = () => {\n reader.read().then(({ done, value }) => {\n if (done) {\n if (buffer.trim()) this.processLine(buffer, observer, message); // process any remaining data\n observer.complete();\n return;\n }\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n\\n');\n buffer = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) this.processLine(line, observer, message);\n }\n read();\n });\n };\n\n read();\n return () => {\n abortController.signal.removeEventListener('abort', abortHandler);\n reader.cancel();\n };\n });\n }\n\n private parseMessages(messages: AIMessage[]) {\n return messages\n .filter(message => !message.options?.skipToLLM)\n .map(message => {\n if (message.options?.hiddenContent) {\n return {\n role: message.role,\n content: message.options.hiddenContent\n };\n }\n return {\n role: message.role,\n content: message.content\n };\n });\n }\n\n private processLine(line: string, observer: any, message: AIMessage) {\n if (!line.trim()) {\n return;\n }\n const lastStep = message.steps?.[message.steps.length - 1] || {\n type: 'text',\n toolCalls: [],\n toolResults: [],\n text: ''\n };\n try {\n let data: any = {};\n let type = '';\n try {\n data = JSON.parse(line.replace('data: ', ''));\n type = data.type;\n } catch (e) {\n console.error('Error parsing line', line, e);\n return;\n }\n\n switch (type) {\n case DataStreamType.STEP_START || DataStreamType.STEP_START_V4:\n message.steps = message.steps || [];\n message.steps.push({\n type: 'text',\n toolCalls: [],\n toolResults: [],\n text: ''\n });\n return;\n\n case DataStreamType.REASONING:\n if (lastStep!.reasoning === undefined) {\n lastStep!.reasoning = '';\n }\n lastStep!.reasoning += data.text || data.textDelta;\n observer.next(message);\n return;\n\n case DataStreamType.TEXT_DELTA:\n lastStep!.text += data.text || data.textDelta;\n message.content += data.text || data.textDelta;\n observer.next(message);\n return;\n\n case DataStreamType.TOOL_INPUT_START:\n lastStep!.toolCalls = [data];\n observer.next(message);\n return;\n\n case DataStreamType.TOOL_CALL:\n lastStep!.toolCalls = [data];\n observer.next(message);\n return;\n\n case DataStreamType.TOOL_RESULT:\n lastStep!.toolResults = [data];\n observer.next(message);\n return;\n\n case DataStreamType.FINISH:\n message.finishReason = data.finishReason;\n observer.next(message);\n observer.complete();\n return;\n\n case DataStreamType.ERROR:\n message.finishReason = 'error';\n const errorMessage = `<div\n class=\"alert alert-danger\"\n role=\"alert\"\n >\n <strong>Error</strong>\n ${data.message || 'An unknown error occurred'}\n </div>`;\n message.content += errorMessage;\n lastStep!.text += errorMessage;\n observer.next(message);\n observer.error(data);\n observer.complete();\n return;\n }\n } catch (e) {\n observer.error(e);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1197,7 +1197,7 @@ class DatapointExplorerComponent {
1197
1197
  ChartAlarmsService,
1198
1198
  ChartHelpersService,
1199
1199
  WidgetTimeContextDateRangeService
1200
- ], viewQueries: [{ propertyName: "chart", first: true, predicate: ["chart"], descendants: true }, { propertyName: "timeContext", first: true, predicate: ["timeContext"], descendants: true }], ngImport: i0, template: "<c8y-title>{{ 'Data explorer' | translate }}</c8y-title>\n\n<c8y-time-context\n #timeContext\n (contextChange)=\"onTimeContextChange($event)\"\n [changedDateContext]=\"timeProps\"\n [timeContext]=\"(settings$ | async)?.timeContext\"\n [timePickerConfig]=\"TIME_PICKER_CONFIG\"\n></c8y-time-context>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n <c8y-workspace-config\n [updatedConfig]=\"config\"\n [silent]=\"(settings$ | async)?.hideWorkspaceConfig\"\n (onConfigurationChange)=\"onConfigurationChange($event)\"\n ></c8y-workspace-config>\n</c8y-action-bar-item>\n\n@if (!(settings$ | async)?.hideExportSelector) {\n <c8y-action-bar-item [placement]=\"'right'\">\n <c8y-datapoints-export-selector\n [exportConfig]=\"exportConfig\"\n [containerClass]=\"'d-contents'\"\n ></c8y-datapoints-export-selector>\n </c8y-action-bar-item>\n}\n\n@if (!(settings$ | async)?.hideWidgetActions) {\n @if (contextAsset) {\n <c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-2000\"\n >\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Send as widget to dashboard' | translate }}\"\n type=\"button\"\n data-cy=\"widgets-dashboard--copy-dashboard\"\n (click)=\"sendAsWidgetToDashboard()\"\n [disabled]=\"config?.datapoints?.length === 0 || !canAddReport\"\n >\n <i c8yIcon=\"th\"></i>\n <span>{{ 'Send as widget to dashboard' | translate }}</span>\n </button>\n </c8y-action-bar-item>\n } @else {\n <c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-2000\"\n >\n <button\n title=\"{{ 'Send as widget to report' | translate }}\"\n type=\"button\"\n data-cy=\"widgets-dashboard--copy-dashboard\"\n (click)=\"sendAsWidgetToReport()\"\n [disabled]=\"config?.datapoints?.length === 0 || !canAddReport\"\n >\n <i c8yIcon=\"c8y-reports\"></i>\n <span>{{ 'Send as widget to report' | translate }}</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-2000\"\n >\n <button\n title=\"{{ 'Create a new report with widget' | translate }}\"\n type=\"button\"\n data-cy=\"widgets-dashboard--copy-dashboard\"\n (click)=\"createNewReportWithWidget()\"\n [disabled]=\"config?.datapoints?.length === 0 || !canAddReport\"\n >\n <i c8yIcon=\"c8y-reports\"></i>\n <span>{{ 'Create a new report with widget' | translate }}</span>\n </button>\n </c8y-action-bar-item>\n }\n}\n\n<div class=\"content-fullpage d-grid grid__col--auto-360 gap-24\">\n <div class=\"d-col gap-16\">\n <c8y-charts\n class=\"flex-grow data-point-explorer\"\n #chart\n [config]=\"config\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"onSliderZoom($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (updateActiveDatapoints)=\"updateActiveDatapoints($event)\"\n (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n ></c8y-charts>\n <form\n class=\"m-l-48 m-r-48\"\n [formGroup]=\"formGroup\"\n >\n <div class=\"d-grid-lg grid__col--4-4-4 gap-16\">\n <fieldset class=\"c8y-fieldset form-group-sm m-t-md-0 p-b-8\">\n <legend>{{ 'Axis' | translate }}</legend>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Y-axis helper lines' | translate\"\n >\n <input\n name=\"yAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"yAxisSplitLines\"\n />\n <span></span>\n <span translate>Y-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'X-axis helper lines' | translate\"\n >\n <input\n name=\"xAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"xAxisSplitLines\"\n />\n <span></span>\n <span translate>X-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Merge matching data points into single axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching data points into single axis</span>\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n [tooltip]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Force merge all data points into single axis' | translate\"\n >\n <input\n name=\"forceMergeDatapoints\"\n type=\"checkbox\"\n formControlName=\"forceMergeDatapoints\"\n />\n <span></span>\n <span translate>Force merge all data points into single axis</span>\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n [tooltip]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Set Y-axis start to 0' | translate\"\n >\n <input\n name=\"setYaxisStartToZero\"\n type=\"checkbox\"\n formControlName=\"setYaxisStartToZero\"\n />\n <span></span>\n <span translate>Set Y-axis start to 0</span>\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n [popover]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n </fieldset>\n <fieldset class=\"c8y-fieldset form-group-sm m-t-md-0 p-b-8\">\n <legend>{{ 'Alarms & events' | translate }}</legend>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show vertical line when alarm occurs' | translate\"\n >\n <input\n name=\"displayMarkedLine\"\n type=\"checkbox\"\n formControlName=\"displayMarkedLine\"\n />\n <span></span>\n <span translate>Show vertical line on every occurrence</span>\n </label>\n\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show icon when alarm or event occurs' | translate\"\n >\n <input\n name=\"displayMarkedPoint\"\n type=\"checkbox\"\n formControlName=\"displayMarkedPoint\"\n />\n <span></span>\n <span>\n {{\n 'Show icon when triggered`When alarms and events occur the icon will be shown`'\n | translate\n }}\n </span>\n @if (alarmsOrEventsHaveNoMatchingDps) {\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n [tooltip]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n }\n </label>\n </fieldset>\n <fieldset class=\"c8y-fieldset form-group-sm m-t-md-0 p-b-8\">\n <legend>{{ 'Chart' | translate }}</legend>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show labels and units' | translate\"\n >\n <input\n name=\"showLabelAndUnit\"\n type=\"checkbox\"\n formControlName=\"showLabelAndUnit\"\n />\n <span></span>\n <span translate>Display labels and units on Y-axis</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show slider' | translate\"\n >\n <input\n name=\"showSlider\"\n type=\"checkbox\"\n formControlName=\"showSlider\"\n />\n <span></span>\n <span translate>Show slider</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show smooth lines' | translate\"\n >\n <input\n name=\"smoothLines\"\n type=\"checkbox\"\n formControlName=\"smoothLines\"\n />\n <span></span>\n <span translate>Show smooth lines</span>\n </label>\n </fieldset>\n </div>\n </form>\n </div>\n <div class=\"card inner-scroll bg-level-1\">\n <form\n class=\"bg-inherit\"\n [formGroup]=\"formGroup\"\n >\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top d-block\"\n name=\"datapoints\"\n [minActiveCount]=\"0\"\n [defaultFormOptions]=\"datapointSelectDefaultFormOptions\"\n [config]=\"{ contextAsset: contextAsset }\"\n formControlName=\"datapoints\"\n [allowDragAndDrop]=\"true\"\n ></c8y-datapoint-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"alarms\"\n formControlName=\"alarms\"\n [timelineType]=\"'ALARM'\"\n [datapoints]=\"config.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"events\"\n formControlName=\"events\"\n [timelineType]=\"'EVENT'\"\n [datapoints]=\"config.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <div class=\"p-l-16 p-r-16 form-group p-b-16\">\n <label\n [title]=\"'Number of decimal places' | translate\"\n translate\n >\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n formControlName=\"numberOfDecimalPlaces\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n />\n <c8y-messages\n [show]=\"\n formGroup.controls?.numberOfDecimalPlaces?.touched &&\n formGroup?.controls?.numberOfDecimalPlaces?.errors\n \"\n ></c8y-messages>\n </div>\n </form>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i3$1.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: i4$1.AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: ["timelineType", "canRemove", "canEdit", "canDragAndDrop", "title", "addButtonLabel", "hideSource", "inline", "activeToggleAsSwitch", "omitProperties", "datapoints", "config"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i6$1.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: TimeContextComponent, selector: "c8y-time-context", inputs: ["changedDateContext", "controlsAvailable", "timeContext", "timePickerConfig", "context"], outputs: ["contextChange"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: A11yModule }, { kind: "component", type: DatapointsExportSelectorComponent, selector: "c8y-datapoints-export-selector", inputs: ["containerClass", "exportConfig"], outputs: ["isOpen"] }, { kind: "component", type: WorkspaceConfigComponent, selector: "c8y-workspace-config", inputs: ["updatedConfig", "silent", "defaultConfigurationId"], outputs: ["onConfigurationChange"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
1200
+ ], viewQueries: [{ propertyName: "chart", first: true, predicate: ["chart"], descendants: true }, { propertyName: "timeContext", first: true, predicate: ["timeContext"], descendants: true }], ngImport: i0, template: "<c8y-title>{{ 'Data explorer' | translate }}</c8y-title>\n\n<c8y-time-context\n #timeContext\n (contextChange)=\"onTimeContextChange($event)\"\n [changedDateContext]=\"timeProps\"\n [timeContext]=\"(settings$ | async)?.timeContext\"\n [timePickerConfig]=\"TIME_PICKER_CONFIG\"\n></c8y-time-context>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n <c8y-workspace-config\n [updatedConfig]=\"config\"\n [silent]=\"(settings$ | async)?.hideWorkspaceConfig\"\n (onConfigurationChange)=\"onConfigurationChange($event)\"\n ></c8y-workspace-config>\n</c8y-action-bar-item>\n\n@if (!(settings$ | async)?.hideExportSelector) {\n <c8y-action-bar-item [placement]=\"'right'\">\n <c8y-datapoints-export-selector\n [exportConfig]=\"exportConfig\"\n [containerClass]=\"'d-contents'\"\n ></c8y-datapoints-export-selector>\n </c8y-action-bar-item>\n}\n\n@if (!(settings$ | async)?.hideWidgetActions) {\n @if (contextAsset) {\n <c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-2000\"\n >\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Send as widget to dashboard' | translate }}\"\n type=\"button\"\n data-cy=\"widgets-dashboard--copy-dashboard\"\n (click)=\"sendAsWidgetToDashboard()\"\n [disabled]=\"config?.datapoints?.length === 0 || !canAddReport\"\n >\n <i c8yIcon=\"th\"></i>\n <span>{{ 'Send as widget to dashboard' | translate }}</span>\n </button>\n </c8y-action-bar-item>\n } @else {\n <c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-2000\"\n >\n <button\n title=\"{{ 'Send as widget to report' | translate }}\"\n type=\"button\"\n data-cy=\"widgets-dashboard--copy-dashboard\"\n (click)=\"sendAsWidgetToReport()\"\n [disabled]=\"config?.datapoints?.length === 0 || !canAddReport\"\n >\n <i c8yIcon=\"c8y-reports\"></i>\n <span>{{ 'Send as widget to report' | translate }}</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item\n [placement]=\"'more'\"\n [priority]=\"-2000\"\n >\n <button\n title=\"{{ 'Create a new report with widget' | translate }}\"\n type=\"button\"\n data-cy=\"widgets-dashboard--copy-dashboard\"\n (click)=\"createNewReportWithWidget()\"\n [disabled]=\"config?.datapoints?.length === 0 || !canAddReport\"\n >\n <i c8yIcon=\"c8y-reports\"></i>\n <span>{{ 'Create a new report with widget' | translate }}</span>\n </button>\n </c8y-action-bar-item>\n }\n}\n\n<div class=\"content-fullpage d-grid grid__col--auto-360 gap-24\">\n <div class=\"d-col gap-16\">\n <c8y-charts\n class=\"flex-grow data-point-explorer\"\n #chart\n [config]=\"config\"\n [alerts]=\"alerts\"\n [chartViewContext]=\"chartViewContext\"\n (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n (configChangeOnZoomOut)=\"onSliderZoom($event)\"\n (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n (updateActiveDatapoints)=\"updateActiveDatapoints($event)\"\n (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n ></c8y-charts>\n <form\n class=\"m-l-48 m-r-48\"\n [formGroup]=\"formGroup\"\n >\n <div class=\"d-grid-lg grid__col--4-4-4 gap-16\">\n <fieldset class=\"c8y-fieldset form-group-sm m-t-md-0 p-b-8\">\n <legend>{{ 'Axis' | translate }}</legend>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Y-axis helper lines' | translate\"\n >\n <input\n name=\"yAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"yAxisSplitLines\"\n />\n <span></span>\n <span translate>Y-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'X-axis helper lines' | translate\"\n >\n <input\n name=\"xAxisSplitLines\"\n type=\"checkbox\"\n formControlName=\"xAxisSplitLines\"\n />\n <span></span>\n <span translate>X-axis helper lines</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Merge matching data points into single axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching data points into single axis</span>\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n [tooltip]=\"\n 'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Force merge all data points into single axis' | translate\"\n >\n <input\n name=\"forceMergeDatapoints\"\n type=\"checkbox\"\n formControlName=\"forceMergeDatapoints\"\n />\n <span></span>\n <span translate>Force merge all data points into single axis</span>\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n [tooltip]=\"\n 'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Set Y-axis start to 0' | translate\"\n >\n <input\n name=\"setYaxisStartToZero\"\n type=\"checkbox\"\n formControlName=\"setYaxisStartToZero\"\n />\n <span></span>\n <span translate>Set Y-axis start to 0</span>\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n [popover]=\"\n 'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n </fieldset>\n <fieldset class=\"c8y-fieldset form-group-sm m-t-md-0 p-b-8\">\n <legend>{{ 'Alarms & events' | translate }}</legend>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show vertical line when alarm occurs' | translate\"\n >\n <input\n name=\"displayMarkedLine\"\n type=\"checkbox\"\n formControlName=\"displayMarkedLine\"\n />\n <span></span>\n <span translate>Show vertical line on every occurrence</span>\n </label>\n\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show icon when alarm or event occurs' | translate\"\n >\n <input\n name=\"displayMarkedPoint\"\n type=\"checkbox\"\n formControlName=\"displayMarkedPoint\"\n />\n <span></span>\n <span>\n {{\n 'Show icon when triggered`When alarms and events occur the icon will be shown`'\n | translate\n }}\n </span>\n @if (alarmsOrEventsHaveNoMatchingDps) {\n <button\n class=\"btn-dot m-l-8\"\n [attr.aria-label]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n [tooltip]=\"\n 'Some alarms or events have no matching data points. No icons will be shown for them.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n }\n </label>\n </fieldset>\n <fieldset class=\"c8y-fieldset form-group-sm m-t-md-0 p-b-8\">\n <legend>{{ 'Chart' | translate }}</legend>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show labels and units' | translate\"\n >\n <input\n name=\"showLabelAndUnit\"\n type=\"checkbox\"\n formControlName=\"showLabelAndUnit\"\n />\n <span></span>\n <span translate>Display labels and units on Y-axis</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show slider' | translate\"\n >\n <input\n name=\"showSlider\"\n type=\"checkbox\"\n formControlName=\"showSlider\"\n />\n <span></span>\n <span translate>Show slider</span>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Show smooth lines' | translate\"\n >\n <input\n name=\"smoothLines\"\n type=\"checkbox\"\n formControlName=\"smoothLines\"\n />\n <span></span>\n <span translate>Show smooth lines</span>\n </label>\n </fieldset>\n </div>\n </form>\n </div>\n <div class=\"card inner-scroll bg-level-1\">\n <form\n class=\"bg-inherit\"\n [formGroup]=\"formGroup\"\n >\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top d-block\"\n name=\"datapoints\"\n [minActiveCount]=\"0\"\n [defaultFormOptions]=\"datapointSelectDefaultFormOptions\"\n [config]=\"{ contextAsset: contextAsset }\"\n formControlName=\"datapoints\"\n [allowDragAndDrop]=\"true\"\n ></c8y-datapoint-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"alarms\"\n formControlName=\"alarms\"\n [timelineType]=\"'ALARM'\"\n [datapoints]=\"config.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"events\"\n formControlName=\"events\"\n [timelineType]=\"'EVENT'\"\n [datapoints]=\"config.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <div class=\"p-l-16 p-r-16 form-group p-b-16\">\n <label\n [title]=\"'Number of decimal places' | translate\"\n translate\n >\n Number of decimal places\n </label>\n <input\n class=\"form-control\"\n name=\"numberOfDecimalPlaces\"\n type=\"number\"\n formControlName=\"numberOfDecimalPlaces\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n />\n <c8y-messages\n [show]=\"\n formGroup.controls?.numberOfDecimalPlaces?.touched &&\n formGroup?.controls?.numberOfDecimalPlaces?.errors\n \"\n ></c8y-messages>\n </div>\n </form>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i3$1.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: i4$1.AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: ["timelineType", "canRemove", "canEdit", "canDragAndDrop", "title", "addButtonLabel", "hideSource", "inline", "activeToggleAsSwitch", "omitProperties", "datapoints", "config"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i6$1.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: TimeContextComponent, selector: "c8y-time-context", inputs: ["changedDateContext", "controlsAvailable", "timeContext", "timePickerConfig", "context"], outputs: ["contextChange"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: A11yModule }, { kind: "component", type: DatapointsExportSelectorComponent, selector: "c8y-datapoints-export-selector", inputs: ["displayMode", "containerClass", "exportConfig"], outputs: ["isOpen"] }, { kind: "component", type: WorkspaceConfigComponent, selector: "c8y-workspace-config", inputs: ["updatedConfig", "silent", "defaultConfigurationId"], outputs: ["onConfigurationChange"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
1201
1201
  }
1202
1202
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DatapointExplorerComponent, decorators: [{
1203
1203
  type: Component,