From 7560f67fa8e9f51b5bf3c490e2cc1ac487007290 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 15:02:43 +0200 Subject: [PATCH 01/42] Migrate barchart settings in Insights UI to or-vaadin-dialog and or-vaadin-checkbox-group --- .../src/settings/barchart-settings.ts | 114 +++++++++--------- 1 file changed, 54 insertions(+), 60 deletions(-) diff --git a/ui/component/or-dashboard-builder/src/settings/barchart-settings.ts b/ui/component/or-dashboard-builder/src/settings/barchart-settings.ts index b63e15a5d8..7370c18230 100644 --- a/ui/component/or-dashboard-builder/src/settings/barchart-settings.ts +++ b/ui/component/or-dashboard-builder/src/settings/barchart-settings.ts @@ -33,9 +33,8 @@ import type { BarChartWidgetConfig } from "../widgets/barchart-widget"; import type { OrVaadinToggle } from "@openremote/or-vaadin-components/or-vaadin-toggle"; import { when } from "lit/directives/when.js"; import type moment from "moment/moment"; -import { type ListItem, ListType, type OrMwcList } from "@openremote/or-mwc-components/or-mwc-list"; import type { OrVaadinSelect, SelectItem } from "@openremote/or-vaadin-components/or-vaadin-select"; -import { showDialog, OrMwcDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { type BarChartAttributeConfig, type BarChartInterval, @@ -48,6 +47,7 @@ import { createRef, type Ref, ref } from "lit/directives/ref.js"; import type { AttributesChartPanel } from "../panels/attributes-chart-panel"; import debounce from "lodash.debounce"; import type { OrVaadinNumberField } from "@openremote/or-vaadin-components/or-vaadin-number-field"; +import type { OrVaadinCheckboxGroup } from "@openremote/or-vaadin-components/or-vaadin-checkbox-group"; const styling = css` .switch-container { @@ -640,66 +640,60 @@ export class BarChartSettings extends WidgetSettings { "methodModeAttributes", "methodSumAttributes", ]; - const methodList: ListItem[] = methodKeys.map((key) => { - const attributeRefs = this.widgetConfig.attributeSettings[key]; - const isActive = attributeRefs?.some( - (attrRef) => attrRef.id === attributeRef.id && attrRef.name === attributeRef.name - ); - return { - text: key, - value: key, - data: isActive ? key : undefined, - translate: true, - }; - }); + const activeKeys = methodKeys.filter((key) => + this.widgetConfig?.attributeSettings?.[key]?.find( + (ref) => ref.id === attributeRef.id && ref.name === attributeRef.name + ) + ); + + const groupRef: Ref = createRef(); + let dialog: OrVaadinDialog | undefined; + + const onCancel = () => { + dialog?.close(); + }; + const onOk = () => { + const groupElem = groupRef.value; + if (groupElem) { + // Find all "active" methods for this AttributeRef, and remove them all. (so they become empty arrays) + activeKeys.forEach((key) => { + this.toggleAttributeSetting(key, attributeRef, false); + }); + // Add the methods that were checked in the checkbox list + groupElem.value.forEach((key) => { + this.toggleAttributeSetting(key as keyof BarChartAttributeConfig, attributeRef, false); + }); + this.notifyConfigUpdate(); + dialog?.close(); + } + }; - const listRef: Ref = createRef(); - - showDialog( - new OrMwcDialog() - .setContent(html` -
- + dialog = showDialog( + this.shadowRoot!, + html` + +

+ +

+ + ${methodKeys.map( + (method) => html` + + + + ` + )} + +
+ + + + + +
- `) - .setHeading(i18next.t("algorithmMethod")) - .setActions([ - { - actionName: "cancel", - content: "cancel", - }, - { - default: true, - actionName: "ok", - action: () => { - if (listRef.value) { - // Find all "active" methods for this AttributeRef, and remove them all. (so they become empty arrays) - methodKeys - .filter( - (oldKey) => - !!this.widgetConfig.attributeSettings[oldKey]?.find( - (attrRef) => attrRef.id === attributeRef.id && attrRef.name === attributeRef.name - ) - ) - .forEach((oldKey) => this.toggleAttributeSetting(oldKey, attributeRef, false)); - - // Add the methods that were checked in the checkbox list - (listRef.value.values as (keyof BarChartAttributeConfig)[] | undefined)?.forEach((s) => { - this.toggleAttributeSetting(s, attributeRef, false); - }); - this.notifyConfigUpdate(); - } - }, - content: "ok", - }, - ]) - .setDismissAction(null) +
+ ` ); } From 51e699150c356cacedc0ab24f8017f526071af9d Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 15:23:55 +0200 Subject: [PATCH 02/42] Replace attribute selector of group asset with or-vaadin-dialog and or-vaadin-checkbox-group --- ui/component/or-asset-viewer/src/index.ts | 75 +++++++++++++---------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/ui/component/or-asset-viewer/src/index.ts b/ui/component/or-asset-viewer/src/index.ts index f35a9c08b3..4f366e04d5 100644 --- a/ui/component/or-asset-viewer/src/index.ts +++ b/ui/component/or-asset-viewer/src/index.ts @@ -28,12 +28,10 @@ import "@openremote/or-attribute-history"; import "@openremote/or-chart"; import "@openremote/or-mwc-components/or-mwc-table"; import "@openremote/or-components/or-panel"; -import "@openremote/or-mwc-components/or-mwc-dialog"; -import { showOkCancelDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; -import "@openremote/or-mwc-components/or-mwc-list"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { type OrTranslate, translate } from "@openremote/or-translate"; -import { InputType, OrInputChangedEvent, OrMwcInput } from "@openremote/or-mwc-components/or-mwc-input"; -import manager, { OPENREMOTE_CLIENT_ID, RESTRICTED_USER_REALM_ROLE, subscribe, Util } from "@openremote/core"; +import { InputType } from "@openremote/or-mwc-components/or-mwc-input"; +import manager, { RESTRICTED_USER_REALM_ROLE, subscribe, Util } from "@openremote/core"; import type { OrMwcTable, OrMwcTableRowClickEvent } from "@openremote/or-mwc-components/or-mwc-table"; import type { OrChartConfig } from "@openremote/or-chart"; import type { HistoryConfig, OrAttributeHistory } from "@openremote/or-attribute-history"; @@ -67,9 +65,10 @@ import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import { progressCircular } from "@openremote/or-mwc-components/style"; import { when } from "lit/directives/when.js"; import { ifDefined } from "lit/directives/if-defined.js"; -import type { OrVaadinCheckbox } from "@openremote/or-vaadin-components/or-vaadin-checkbox"; import type { OrVaadinInput } from "@openremote/or-vaadin-components/or-vaadin-input"; import { getConfirmDialogContent, showConfirmDialog } from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; +import type { OrVaadinCheckboxGroup } from "@openremote/or-vaadin-components/or-vaadin-checkbox-group"; +import { createRef, type Ref, ref } from "lit/directives/ref.js"; declare function require(name: string): any; @@ -840,36 +839,46 @@ function getPanelContent( }; const attributePickerModalOpen = () => { - const newlySelectedAttributes = [...selectedAttributes]; + let dialog: OrVaadinDialog | undefined; + const groupRef: Ref = createRef(); + const onCancel = () => { + dialog?.close(); + }; + const onOk = () => { + const groupElem = groupRef.value; + if (groupElem) { + updateSelectedAttributes(groupElem.value); + dialog?.close(); + } + }; - // TODO: Replace with or-vaadin-dialog, see https://github.com/openremote/openremote/issues/2594 - showOkCancelDialog( - i18next.t("addRemoveAttributes"), + dialog = showDialog( + document.body, html` -
- ${availableAttributes.sort().map( - (attribute) => html` - selected === attribute)} - @change=${(ev: Event) => { - if ((ev.currentTarget as OrVaadinCheckbox).checked) { - newlySelectedAttributes.push(attribute); - } else { - newlySelectedAttributes.splice(newlySelectedAttributes.indexOf(attribute), 1); - } - }} - > - ` - )} -
+ +

+ +

+ + ${availableAttributes.map( + (attr) => html` + + + + ` + )} + +
+ + + + + + +
+
` - ).then((ok) => { - if (ok) { - updateSelectedAttributes(newlySelectedAttributes); - } - }); + ); }; const headersAndRows = getHeadersAndRows(); From 28d7c6f75bb0d3127e4f8d8647cc6a7773c280f5 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 16:13:56 +0200 Subject: [PATCH 03/42] Migrate map/realm styling delete prompts on appearance page to Vaadin. Fix for attribute list in group asset not being sorted nor formatted. --- .../or-conf-map/or-conf-map-card.ts | 40 ++++--------------- .../or-conf-realm/or-conf-realm-card.ts | 40 ++++--------------- ui/component/or-asset-viewer/src/index.ts | 6 +-- 3 files changed, 19 insertions(+), 67 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts index afc104bd70..8c7b997f32 100644 --- a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts +++ b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts @@ -23,7 +23,7 @@ import { when } from "lit/directives/when.js"; import "@openremote/or-components/or-file-uploader"; import { i18next } from "@openremote/or-translate"; import type { MapRealmConfig } from "@openremote/model"; -import { type DialogAction, OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import {getConfirmDialogContent, showConfirmDialog} from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; import type { OrVaadinToggle } from "@openremote/or-vaadin-components/or-vaadin-toggle"; import type { OrMapLongPressEvent } from "@openremote/or-map"; import type { LngLat } from "maplibre-gl"; @@ -57,37 +57,13 @@ export class OrConfMapCard extends OrElement { } protected _showRemoveMapDialog() { - const dialogActions: DialogAction[] = [ - { - actionName: "cancel", - content: "cancel", - }, - { - default: true, - actionName: "ok", - content: "yes", - action: () => { - this.dispatchEvent(new CustomEvent("remove")); - }, - }, - ]; - showDialog( - new OrMwcDialog() - .setHeading(i18next.t("delete")) - .setActions(dialogActions) - .setContent(html` ${i18next.t("configuration.deleteMapCustomizationConfirm")} `) - .setStyles(html` - - `) - .setDismissAction(null) + showConfirmDialog( + this.shadowRoot!, + html` + this.dispatchEvent(new CustomEvent("remove"))}> + ${getConfirmDialogContent("error", "delete", "configuration.deleteMapCustomizationConfirm", "delete", "cancel")} + + ` ); } diff --git a/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts b/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts index 52daf63539..3331f6f2c4 100644 --- a/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts +++ b/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts @@ -35,10 +35,10 @@ import { } from "@openremote/core"; import { i18next, translate } from "@openremote/or-translate"; import type { FileInfo, ManagerAppRealmConfig } from "@openremote/model"; -import { type DialogAction, OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; import { when } from "lit/directives/when.js"; import { DefaultHeaderMainMenu, DefaultHeaderSecondaryMenu } from "../../../index"; import type { OrVaadinMultiSelectComboBox } from "@openremote/or-vaadin-components/or-vaadin-multi-select-combo-box"; +import {getConfirmDialogContent, showConfirmDialog} from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; @customElement("or-conf-realm-card") export class OrConfRealmCard extends translate(i18next)(OrElement) { @@ -229,37 +229,13 @@ export class OrConfRealmCard extends translate(i18next)(OrElement) { } protected _showRemoveRealmDialog() { - const dialogActions: DialogAction[] = [ - { - actionName: "cancel", - content: "cancel", - }, - { - default: true, - actionName: "ok", - content: "yes", - action: () => { - this.dispatchEvent(new CustomEvent("remove")); - }, - }, - ]; - showDialog( - new OrMwcDialog() - .setHeading(i18next.t("delete")) - .setActions(dialogActions) - .setContent(html` ${i18next.t("configuration.deleteRealmCustomizationConfirm")} `) - .setStyles(html` - - `) - .setDismissAction(null) + showConfirmDialog( + this.shadowRoot!, + html` + this.dispatchEvent(new CustomEvent("remove"))}> + ${getConfirmDialogContent("error", "delete", "configuration.deleteRealmCustomizationConfirm", "delete", "cancel")} + + ` ); } diff --git a/ui/component/or-asset-viewer/src/index.ts b/ui/component/or-asset-viewer/src/index.ts index 4f366e04d5..4b30163f07 100644 --- a/ui/component/or-asset-viewer/src/index.ts +++ b/ui/component/or-asset-viewer/src/index.ts @@ -853,17 +853,17 @@ function getPanelContent( }; dialog = showDialog( - document.body, + hostElement, html`

- ${availableAttributes.map( + ${availableAttributes.sort().map( (attr) => html` - + ` )} From d078604add3009ec4b17eb31dbaea666a629f501 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 16:16:40 +0200 Subject: [PATCH 04/42] Apply spotless --- .../components/configuration/or-conf-map/or-conf-map-card.ts | 2 +- .../configuration/or-conf-realm/or-conf-realm-card.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts index 8c7b997f32..c5d645aa93 100644 --- a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts +++ b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-card.ts @@ -23,7 +23,7 @@ import { when } from "lit/directives/when.js"; import "@openremote/or-components/or-file-uploader"; import { i18next } from "@openremote/or-translate"; import type { MapRealmConfig } from "@openremote/model"; -import {getConfirmDialogContent, showConfirmDialog} from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; +import { getConfirmDialogContent, showConfirmDialog } from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; import type { OrVaadinToggle } from "@openremote/or-vaadin-components/or-vaadin-toggle"; import type { OrMapLongPressEvent } from "@openremote/or-map"; import type { LngLat } from "maplibre-gl"; diff --git a/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts b/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts index 3331f6f2c4..3486bccdf5 100644 --- a/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts +++ b/ui/app/manager/src/components/configuration/or-conf-realm/or-conf-realm-card.ts @@ -38,7 +38,7 @@ import type { FileInfo, ManagerAppRealmConfig } from "@openremote/model"; import { when } from "lit/directives/when.js"; import { DefaultHeaderMainMenu, DefaultHeaderSecondaryMenu } from "../../../index"; import type { OrVaadinMultiSelectComboBox } from "@openremote/or-vaadin-components/or-vaadin-multi-select-combo-box"; -import {getConfirmDialogContent, showConfirmDialog} from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; +import { getConfirmDialogContent, showConfirmDialog } from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; @customElement("or-conf-realm-card") export class OrConfRealmCard extends translate(i18next)(OrElement) { From 4b01ac87e01a5ac744470b79bdac69f765c3706d Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 17:17:44 +0200 Subject: [PATCH 05/42] Migrate map dialogs of Rules page its When clause to Vaadin --- .../modals/or-rule-radial-modal.ts | 174 ++++++++---------- .../src/json-viewer/or-rule-trigger-query.ts | 166 ++++++++--------- 2 files changed, 150 insertions(+), 190 deletions(-) diff --git a/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts b/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts index 2ee9629cd8..8aa4077eab 100644 --- a/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts +++ b/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts @@ -18,21 +18,16 @@ */ import { html } from "lit"; import { OrElement } from "@openremote/or-element"; -import { customElement, property } from "lit/decorators.js"; +import { customElement, property, query } from "lit/decorators.js"; import type { AssetDescriptor, AttributePredicate, AssetQuery, RadialGeofencePredicate } from "@openremote/model"; -import { getAssetTypeFromQuery } from "../../index"; +import type { OrVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import "@openremote/or-mwc-components/or-mwc-input"; -import { InputType } from "@openremote/or-mwc-components/or-mwc-input"; import { i18next, translate } from "@openremote/or-translate"; import { OrRulesJsonRuleChangedEvent } from "../or-rule-json-viewer"; - -import { - type DialogAction, - type OrMwcDialog, - OrMwcDialogOpenedEvent, -} from "@openremote/or-mwc-components/or-mwc-dialog"; import { type OrMap, OrMapClickedEvent, type LngLatLike } from "@openremote/or-map"; import "@openremote/or-map"; +import type { OrVaadinNumberField } from "@openremote/or-vaadin-components/or-vaadin-number-field"; +import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; @customElement("or-rule-radial-modal") export class OrRuleRadialModal extends translate(i18next)(OrElement) { @@ -48,21 +43,24 @@ export class OrRuleRadialModal extends translate(i18next)(OrElement) { @property({ type: Object }) public query?: AssetQuery; - constructor() { - super(); - this.addEventListener(OrMwcDialogOpenedEvent.NAME, this.initRadialMap); - } + @query("#radial-modal") + protected _mapDialogElem?: OrVaadinDialog; + + @query("#radial-modal-button") + protected _mapDialogButton?: OrVaadinButton; initRadialMap() { - const modal = this.shadowRoot!.getElementById("radial-modal"); - if (!modal) return; + if (!this._mapDialogElem) { + console.warn("Could not find radial map dialog element!"); + return; + } - const map = modal.shadowRoot!.querySelector(".or-map") as OrMap; + const map = this._mapDialogElem!.querySelector(".or-map") as OrMap; if (map) { map.addEventListener(OrMapClickedEvent.NAME, (evt: CustomEvent) => { const lngLat: any = evt.detail.lngLat; - const latElement = modal.shadowRoot!.querySelector(".location-lat") as HTMLInputElement; - const lngElement = modal.shadowRoot!.querySelector(".location-lng") as HTMLInputElement; + const latElement = this._mapDialogElem!.querySelector(".location-lat") as HTMLInputElement; + const lngElement = this._mapDialogElem!.querySelector(".location-lng") as HTMLInputElement; latElement.value = lngLat.lat; lngElement.value = lngLat.lng; @@ -73,8 +71,8 @@ export class OrRuleRadialModal extends translate(i18next)(OrElement) { this.setValuePredicateProperty("lng", lngLat.lng); }); - const latElement = modal.shadowRoot!.querySelector(".location-lat") as HTMLInputElement; - const lngElement = modal.shadowRoot!.querySelector(".location-lng") as HTMLInputElement; + const latElement = this._mapDialogElem!.querySelector(".location-lat") as HTMLInputElement; + const lngElement = this._mapDialogElem!.querySelector(".location-lng") as HTMLInputElement; if (lngElement.value && latElement.value) { const LngLat: LngLatLike = [parseFloat(lngElement.value), parseFloat(latElement.value)]; map.flyTo(LngLat, 15); @@ -84,10 +82,6 @@ export class OrRuleRadialModal extends translate(i18next)(OrElement) { } } - protected getAttributeName(attributePredicate: AttributePredicate): string | undefined { - return attributePredicate && attributePredicate.name ? attributePredicate.name.value : undefined; - } - protected setValuePredicateProperty(propertyName: string, value: any) { if (!this.attributePredicate) return; if (!this.attributePredicate.value) return; @@ -100,57 +94,54 @@ export class OrRuleRadialModal extends translate(i18next)(OrElement) { this.requestUpdate(); } - renderDialogHTML(value: RadialGeofencePredicate) { - const dialog: OrMwcDialog = this.shadowRoot!.getElementById("radial-modal") as OrMwcDialog; - - if (dialog) { - dialog.content = html`
- - - - -
- - -
- - + getDialogHTML(value: RadialGeofencePredicate) { + return html`
+ + + + +
-
`; - } + +
+ + { + const elem = ev.currentTarget as OrVaadinNumberField; + if (elem.checkValidity()) { + this.setValuePredicateProperty("radius", parseInt(elem.value)); + } + this._mapDialogButton!.disabled = !elem.checkValidity(); + }} + > + + +
`; } protected render() { @@ -161,44 +152,29 @@ export class OrRuleRadialModal extends translate(i18next)(OrElement) { if (!this.assetDescriptor || !valuePredicate) { return html``; } - - const attributeName = this.getAttributeName(this.attributePredicate); - const assetType = getAssetTypeFromQuery(this.query); // @ts-ignore const value: RadialGeofencePredicate = valuePredicate || undefined; - const radiusPickerModalActions: DialogAction[] = [ - { - actionName: "cancel", - content: html``, - action: () => { - // Nothing to do here - }, - }, - { - actionName: "ok", - default: true, - content: html``, - action: () => {}, - }, - ]; - const radialPickerModalOpen = () => { - const dialog: OrMwcDialog = this.shadowRoot!.getElementById("radial-modal") as OrMwcDialog; - if (dialog) { - dialog.dismissAction = null; - dialog.open(); - this.renderDialogHTML(value); - } + this._mapDialogElem?.open(); + this.initRadialMap(); }; - this.renderDialogHTML(value); - return html` radialPickerModalOpen()}> - + +

+ +

+ ${this.getDialogHTML(value)} +
+ this._mapDialogElem?.close()}> + + +
+
`; } } diff --git a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts index b157904698..2064be8f33 100644 --- a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts +++ b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts @@ -17,26 +17,21 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import { type GeoJSONPoint, type RuleCondition, SunPositionTriggerPosition } from "@openremote/model"; -import { InputType, OrInputChangedEvent } from "@openremote/or-mwc-components/or-mwc-input"; -import { css, html, type PropertyValues } from "lit"; +import { css, html, type TemplateResult, type PropertyValues } from "lit"; import { OrElement } from "@openremote/or-element"; -import { customElement, property, state } from "lit/decorators.js"; +import { customElement, property, query, state } from "lit/decorators.js"; import moment from "moment"; import { buttonStyle } from "../style"; import { OrRulesJsonRuleChangedEvent } from "./or-rule-json-viewer"; import { TimeTriggerType } from "../index"; import { Util } from "@openremote/core"; -import { - type DialogAction, - type OrMwcDialog, - OrMwcDialogOpenedEvent, -} from "@openremote/or-mwc-components/or-mwc-dialog"; import { type OrMap, OrMapClickedEvent } from "@openremote/or-map"; import { i18next } from "@openremote/or-translate"; import type { OrVaadinSelect } from "@openremote/or-vaadin-components/or-vaadin-select"; import { when } from "lit/directives/when.js"; import { ifDefined } from "lit/directives/if-defined.js"; import type { OrVaadinTimePicker } from "@openremote/or-vaadin-components/or-vaadin-time-picker"; +import type { OrVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; // language=CSS const style = css` @@ -90,6 +85,9 @@ export class OrRuleTriggerQuery extends OrElement { @state() protected triggerOptions: TimeTrigger[]; + @query("#map-modal") + protected _mapDialogElem?: OrVaadinDialog; + constructor() { super(); this.triggerOptions = []; @@ -100,8 +98,6 @@ export class OrRuleTriggerQuery extends OrElement { this.triggerOptions.push({ key: opt, value: this.triggerToString(opt) }); }); this.selectedTrigger = this.triggerOptions[0]; - - this.addEventListener(OrMwcDialogOpenedEvent.NAME, this.initMap); } updated(changedProperties: PropertyValues) { @@ -123,91 +119,73 @@ export class OrRuleTriggerQuery extends OrElement { /* ---------------------- */ initMap() { - const modal = this.shadowRoot!.getElementById("map-modal"); - if (!modal) return; - - const map = modal.shadowRoot!.querySelector(".or-map") as OrMap; - if (map) { - map.addEventListener(OrMapClickedEvent.NAME, (evt: CustomEvent) => { - const lngLat: any = evt.detail.lngLat; - this.setLocation({ type: "Point", coordinates: [lngLat.lat, lngLat.lng] }); - const latElement = modal.shadowRoot!.querySelector(".location-lat") as HTMLInputElement; - const lngElement = modal.shadowRoot!.querySelector(".location-lng") as HTMLInputElement; - latElement.value = lngLat.lat; - lngElement.value = lngLat.lng; - }); + if (!this._mapDialogElem) { + console.warn("Could not find map dialog element!"); + return; + } + const map = this._mapDialogElem.querySelector(".or-map") as OrMap; + if (!map) { + console.warn("Could not find map within dialog element!"); + return; } + map.addEventListener(OrMapClickedEvent.NAME, (evt: CustomEvent) => { + const lngLat: any = evt.detail.lngLat; + this.setLocation({ type: "Point", coordinates: [lngLat.lat, lngLat.lng] }); + const latElement = this._mapDialogElem!.querySelector(".location-lat") as HTMLInputElement; + const lngElement = this._mapDialogElem!.querySelector(".location-lng") as HTMLInputElement; + latElement.value = lngLat.lat; + lngElement.value = lngLat.lng; + }); } - renderDialogHTML(point: GeoJSONPoint | undefined) { - const dialog: OrMwcDialog = this.shadowRoot!.getElementById("map-modal") as OrMwcDialog; - if (dialog) { - dialog.content = html` -
- - ${ - point && point.coordinates - ? html` - - ` - : undefined - } - -
- - -
+ renderDialogHTML(point: GeoJSONPoint | undefined): TemplateResult { + return html` +
+ + ${ + point && point.coordinates + ? html` + + ` + : undefined + } + +
+ +
- `; - } +
+ `; } /* ----------------------------- */ render() { - const modalActions: DialogAction[] = [ - { - actionName: "close", - default: true, - content: html``, - action: () => {}, - }, - ]; - const onMapModalOpen = () => { - const dialog: OrMwcDialog = this.shadowRoot!.getElementById("map-modal") as OrMwcDialog; - if (dialog) { - dialog.dismissAction = null; - dialog.open(); - this.renderDialogHTML(this.condition.sun?.location); - } + const openModal = () => { + this._mapDialogElem?.open(); + this.initMap(); }; - // Render dialog on every update (for example when changing location in the modal itself) - this.renderDialogHTML(this.condition.sun?.location); return html`
@@ -249,14 +227,20 @@ export class OrRuleTriggerQuery extends OrElement { > - onMapModalOpen()}> + openModal()}> - + +

+ +

+ ${this.renderDialogHTML(this.condition.sun?.location)} +
+ this._mapDialogElem?.close()}> + + +
+
` } ` From 51faef2e4a08185bd709e17b5495e0d8bb9e6fda Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 17:39:04 +0200 Subject: [PATCH 06/42] Minor fixes --- ui/component/or-asset-viewer/src/index.ts | 2 +- .../or-rules/src/json-viewer/modals/or-rule-radial-modal.ts | 1 - .../or-rules/src/json-viewer/or-rule-trigger-query.ts | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ui/component/or-asset-viewer/src/index.ts b/ui/component/or-asset-viewer/src/index.ts index 4b30163f07..d4a6cbbd3b 100644 --- a/ui/component/or-asset-viewer/src/index.ts +++ b/ui/component/or-asset-viewer/src/index.ts @@ -853,7 +853,7 @@ function getPanelContent( }; dialog = showDialog( - hostElement, + hostElement.shadowRoot!, html`

diff --git a/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts b/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts index 8aa4077eab..c44db57040 100644 --- a/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts +++ b/ui/component/or-rules/src/json-viewer/modals/or-rule-radial-modal.ts @@ -21,7 +21,6 @@ import { OrElement } from "@openremote/or-element"; import { customElement, property, query } from "lit/decorators.js"; import type { AssetDescriptor, AttributePredicate, AssetQuery, RadialGeofencePredicate } from "@openremote/model"; import type { OrVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; -import "@openremote/or-mwc-components/or-mwc-input"; import { i18next, translate } from "@openremote/or-translate"; import { OrRulesJsonRuleChangedEvent } from "../or-rule-json-viewer"; import { type OrMap, OrMapClickedEvent, type LngLatLike } from "@openremote/or-map"; diff --git a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts index 2064be8f33..2b38e0867a 100644 --- a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts +++ b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts @@ -25,7 +25,7 @@ import { buttonStyle } from "../style"; import { OrRulesJsonRuleChangedEvent } from "./or-rule-json-viewer"; import { TimeTriggerType } from "../index"; import { Util } from "@openremote/core"; -import { type OrMap, OrMapClickedEvent } from "@openremote/or-map"; +import {type LngLatLike, type OrMap, OrMapClickedEvent} from "@openremote/or-map"; import { i18next } from "@openremote/or-translate"; import type { OrVaadinSelect } from "@openremote/or-vaadin-components/or-vaadin-select"; import { when } from "lit/directives/when.js"; @@ -141,7 +141,7 @@ export class OrRuleTriggerQuery extends OrElement { renderDialogHTML(point: GeoJSONPoint | undefined): TemplateResult { return html`
- + ${ point && point.coordinates ? html` From 57209031e726bb2bd1d150fa1c283bec387ee7e2 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 3 Sep 2026 17:41:33 +0200 Subject: [PATCH 07/42] Apply spotless --- ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts index 2b38e0867a..fe7b797a3f 100644 --- a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts +++ b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts @@ -25,7 +25,7 @@ import { buttonStyle } from "../style"; import { OrRulesJsonRuleChangedEvent } from "./or-rule-json-viewer"; import { TimeTriggerType } from "../index"; import { Util } from "@openremote/core"; -import {type LngLatLike, type OrMap, OrMapClickedEvent} from "@openremote/or-map"; +import { type LngLatLike, type OrMap, OrMapClickedEvent } from "@openremote/or-map"; import { i18next } from "@openremote/or-translate"; import type { OrVaadinSelect } from "@openremote/or-vaadin-components/or-vaadin-select"; import { when } from "lit/directives/when.js"; From 7612d5599808d68288638805e63e46174f69a17c Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Fri, 25 Sep 2026 17:09:51 +0200 Subject: [PATCH 08/42] Migrate JSON dialogs of the appearance page to Vaadin --- .../components/configuration/or-conf-json.ts | 92 +++++++++---------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-json.ts b/ui/app/manager/src/components/configuration/or-conf-json.ts index d4d84296ac..9442cf2315 100644 --- a/ui/app/manager/src/components/configuration/or-conf-json.ts +++ b/ui/app/manager/src/components/configuration/or-conf-json.ts @@ -20,11 +20,11 @@ import { html } from "lit"; import { OrElement } from "@openremote/or-element"; import { customElement, property } from "lit/decorators.js"; import "@openremote/or-components/or-ace-editor"; -import type { DialogAction } from "@openremote/or-mwc-components/or-mwc-dialog"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog} from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { createRef, type Ref, ref } from "lit/directives/ref.js"; import type { OrAceEditor, OrAceEditorChangedEvent } from "@openremote/or-components/or-ace-editor"; import type { ManagerAppConfig, MapConfig } from "@openremote/model"; +import {OrVaadinButton} from "@openremote/or-vaadin-components/or-vaadin-button"; @customElement("or-conf-json") export class OrConfJson extends OrElement { @@ -34,6 +34,7 @@ export class OrConfJson extends OrElement { public heading: string; protected _aceEditor: Ref = createRef(); + protected _updateButton: Ref = createRef(); public beforeSave(): false | string | undefined { if (!this._aceEditor.value) { @@ -48,7 +49,7 @@ export class OrConfJson extends OrElement { } protected _showConfigDialog() { - let dialog: OrMwcDialog; + let dialog: OrVaadinDialog | undefined; const _saveConfig = () => { const config = this.beforeSave(); if (config) { @@ -59,55 +60,44 @@ export class OrConfJson extends OrElement { return false; }; - const dialogActions: DialogAction[] = [ - { - actionName: "cancel", - content: "cancel", - }, - { - actionName: "ok", - content: "update", - action: _saveConfig, - }, - ]; - - dialog = new OrMwcDialog() - .setActions(dialogActions) - .setHeading(this.heading) - .setContent(html` - - `) - .setStyles(html` - - `) - .setDismissAction(null); + const onCancel = () => { + dialog.close(); + } + const onOk = () => { + if(_saveConfig()) { + dialog.close(); + } + } - showDialog(dialog); + dialog = showDialog( + this.shadowRoot!, + html` + +

+ ${this.heading} +

+ +
+ + + + + + +
+
+ ` + ); } render() { From 65aef6b3d7ecfc7854de5071c86485eed9990c5b Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Fri, 25 Sep 2026 17:16:38 +0200 Subject: [PATCH 09/42] Apply spotless --- .../src/components/configuration/or-conf-json.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-json.ts b/ui/app/manager/src/components/configuration/or-conf-json.ts index 9442cf2315..a91c932062 100644 --- a/ui/app/manager/src/components/configuration/or-conf-json.ts +++ b/ui/app/manager/src/components/configuration/or-conf-json.ts @@ -20,11 +20,11 @@ import { html } from "lit"; import { OrElement } from "@openremote/or-element"; import { customElement, property } from "lit/decorators.js"; import "@openremote/or-components/or-ace-editor"; -import { type OrVaadinDialog, showDialog} from "@openremote/or-vaadin-components/or-vaadin-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { createRef, type Ref, ref } from "lit/directives/ref.js"; import type { OrAceEditor, OrAceEditorChangedEvent } from "@openremote/or-components/or-ace-editor"; import type { ManagerAppConfig, MapConfig } from "@openremote/model"; -import {OrVaadinButton} from "@openremote/or-vaadin-components/or-vaadin-button"; +import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; @customElement("or-conf-json") export class OrConfJson extends OrElement { @@ -62,26 +62,24 @@ export class OrConfJson extends OrElement { const onCancel = () => { dialog.close(); - } + }; const onOk = () => { - if(_saveConfig()) { + if (_saveConfig()) { dialog.close(); } - } + }; dialog = showDialog( this.shadowRoot!, html` -

- ${this.heading} -

+

${this.heading}

*:last-child { margin-left: -2px; } - + #controls { display: flex; @@ -284,7 +285,7 @@ const style = css` .attribute-list-dense { flex-wrap: wrap; } - + .attribute-list-item { cursor: pointer; display: flex; @@ -315,7 +316,7 @@ const style = css` .button-clear:hover { --or-icon-fill: var(--or-app-color4); } - + .attribute-list-item-label { display: flex; flex: 1 1 0; @@ -1233,45 +1234,51 @@ export class OrChart extends translate(i18next)(OrElement) { protected _openTimeDialog(startTimestamp?: number, endTimestamp?: number) { const startRef: Ref = createRef(); const endRef: Ref = createRef(); - showDialog( - new OrMwcDialog() - .setHeading(i18next.t("timeframe")) - .setContent( - () => html` -
- - - - - - -
- ` - ) - .setActions([ - { - actionName: "cancel", - content: "cancel", - }, - { - actionName: "ok", - content: "ok", - action: () => { - if (startRef.value?.value && endRef.value?.value) { - this._isCustomWindow = true; - this.timeframe = [new Date(startRef.value.value), new Date(endRef.value.value)]; - } - }, - }, - ]) + let dialog: OrVaadinDialog | undefined; + + const onCancel = () => { + dialog?.close(); + }; + const onOk = () => { + if (startRef.value?.value && endRef.value?.value) { + this._isCustomWindow = true; + this.timeframe = [new Date(startRef.value.value), new Date(endRef.value.value)]; + dialog?.close(); + } + }; + dialog = showVaadinDialog( + this.shadowRoot!, + html` + +

+ +

+
+ + + + + + +
+
+ + + + + + +
+
+ ` ); } From d4e3d9275d64409c447bc1a402a1f1b257164acf Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 14:22:06 +0200 Subject: [PATCH 12/42] Migrate delete realm dialog from the Realms page to Vaadin --- ui/app/manager/src/pages/page-realms.ts | 67 +++++++------------ .../src/or-vaadin-confirm-dialog.ts | 34 +++++----- 2 files changed, 44 insertions(+), 57 deletions(-) diff --git a/ui/app/manager/src/pages/page-realms.ts b/ui/app/manager/src/pages/page-realms.ts index 7bd9bc70e2..9c0d6ece3a 100644 --- a/ui/app/manager/src/pages/page-realms.ts +++ b/ui/app/manager/src/pages/page-realms.ts @@ -28,8 +28,11 @@ import { type AppStateKeyed, Page, type PageProvider } from "@openremote/or-app" import { ClientRole, type Realm } from "@openremote/model"; import { i18next } from "@openremote/or-translate"; import type { OrIcon } from "@openremote/or-icon"; -import { InputType } from "@openremote/or-mwc-components/or-mwc-input"; -import { type DialogAction, OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { + getConfirmDialogContent, + type OrVaadinConfirmDialog, + showConfirmDialog, +} from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import type { OrVaadinTextField } from "@openremote/or-vaadin-components/or-vaadin-text-field"; import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; @@ -522,7 +525,7 @@ export class PageRealms extends Page { let confirmedName = ""; const okBtnRef: Ref = createRef(); - const doDelete = async (dialog: OrMwcDialog) => { + const doDelete = async (dialog: OrVaadinConfirmDialog) => { if (okBtnRef.value.disabled) return; try { await manager.rest.api.RealmResource.delete(realm.name); @@ -530,6 +533,8 @@ export class PageRealms extends Page { this.dispatchEvent(new CustomEvent("realms-changed", { bubbles: true, composed: true })); } catch (e) { showSnackbar(undefined, "realmDeleteFailed", "dismiss"); + } finally { + dialog.close(); } }; @@ -549,45 +554,23 @@ export class PageRealms extends Page {
`; - const dialogActions: DialogAction[] = [ - { - actionName: "ok", - content: html``, - action: doDelete, - }, - { - default: true, - actionName: "cancel", - content: "cancel", - }, - ]; - - const dialog = showDialog( - new OrMwcDialog() - .setContent(dialogContent) - .setActions(dialogActions) - .setStyles(html` - - `) - .setDismissAction(null) + const dialog = showConfirmDialog( + this.shadowRoot, + html` + doDelete(dialog)}> + ${getConfirmDialogContent( + "error", + "deleteRealmConfirm", + dialogContent, + html` + + + + `, + "cancel" + )} + + ` ); } diff --git a/ui/component/or-vaadin-components/src/or-vaadin-confirm-dialog.ts b/ui/component/or-vaadin-components/src/or-vaadin-confirm-dialog.ts index 43b7aaa410..bbe904355c 100644 --- a/ui/component/or-vaadin-components/src/or-vaadin-confirm-dialog.ts +++ b/ui/component/or-vaadin-components/src/or-vaadin-confirm-dialog.ts @@ -55,6 +55,7 @@ export function showConfirmDialog(host: Node, dialog: TemplateResult) { return; } host.appendChild(container); + return dialogElem; } /** @@ -65,17 +66,17 @@ export function showConfirmDialog(host: Node, dialog: TemplateResult) { * @param theme - Optional theme to use for the dialog and its buttons (for example 'error'). * @param header - Dialog header that is either a translation key, or a {@link TemplateResult} * @param content - Dialog content that is either a translation key, or a {@link TemplateResult} - * @param confirmKey - Translation key to display inside the "confirm" button. If `undefined` the button will not be visible. - * @param cancelKey - Translation key to display inside the "cancel" button. If `undefined` the button will not be visible. - * @param rejectKey - Translation key to display inside the "reject" button. If `undefined` the button will not be visible. + * @param confirm - {@link TemplateResult} or translation key to display inside the "confirm" button. If `undefined` the button will not be visible. + * @param cancel - {@link TemplateResult} or translation key to display inside the "cancel" button. If `undefined` the button will not be visible. + * @param reject - {@link TemplateResult} or translation key to display inside the "reject" button. If `undefined` the button will not be visible. */ export function getConfirmDialogContent( theme: string | undefined, header: TemplateResult | string, content: TemplateResult | string, - confirmKey?: string, - cancelKey?: string, - rejectKey?: string + confirm?: TemplateResult | string, + cancel?: TemplateResult | string, + reject?: TemplateResult | string ): TemplateResult { return html` ${ @@ -85,28 +86,31 @@ export function getConfirmDialogContent( } ${typeof content === "string" ? html`` : content} ${when( - confirmKey, + typeof confirm === "string", () => html` - + - ` + `, + confirm ? () => confirm : undefined )} ${when( - cancelKey, + typeof cancel === "string", () => html` - + - ` + `, + cancel ? () => cancel : undefined )} ${when( - rejectKey, + typeof reject === "string", () => html` - + - ` + `, + reject ? () => reject : undefined )} `; } From 8088239bc8e9072cdbbf7023cdcd759679e9103e Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 14:47:46 +0200 Subject: [PATCH 13/42] Migrate Insights bar chart dialog to Vaadin --- .../or-attribute-barchart/src/index.ts | 90 ++++++++++--------- ui/component/or-chart/src/index.ts | 7 +- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/ui/component/or-attribute-barchart/src/index.ts b/ui/component/or-attribute-barchart/src/index.ts index 240fb35234..7a90312752 100644 --- a/ui/component/or-attribute-barchart/src/index.ts +++ b/ui/component/or-attribute-barchart/src/index.ts @@ -48,7 +48,7 @@ import { UniversalTransition } from "echarts/features"; import moment from "moment"; import { getAssetDescriptorIconTemplate } from "@openremote/or-icon"; import { isAxiosError } from "@openremote/rest"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import { cache } from "lit/directives/cache.js"; import { createMenuBarItem, type MenuBarItem } from "@openremote/or-vaadin-components/or-vaadin-menu-bar"; @@ -855,47 +855,53 @@ export class OrAttributeBarChart extends OrElement { protected _openTimeDialog(startTimestamp?: number, endTimestamp?: number) { const startRef: Ref = createRef(); const endRef: Ref = createRef(); - showDialog( - new OrMwcDialog() - .setHeading(i18next.t("timeframe")) - .setContent( - () => html` -
- - - - - - -
- ` - ) - .setActions([ - { - actionName: "cancel", - content: "cancel", - }, - { - actionName: "ok", - content: "ok", - action: () => { - if (startRef.value?.value && endRef.value?.value && startRef.value.value < endRef.value.value) { - this._isCustomWindow = true; - this.timeframe = [new Date(startRef.value.value), new Date(endRef.value.value)]; - } else { - showSnackbar(undefined, i18next.t("errorOccurred")); - } - }, - }, - ]) + let dialog: OrVaadinDialog | undefined; + + const onCancel = () => { + dialog?.close(); + } + const onOk = () => { + if (startRef.value?.value && endRef.value?.value && startRef.value.value < endRef.value.value) { + this._isCustomWindow = true; + this.timeframe = [new Date(startRef.value.value), new Date(endRef.value.value)]; + dialog?.close(); + } else { + showSnackbar(undefined, i18next.t("errorOccurred")); + } + } + dialog = showDialog( + this.shadowRoot!, + html` + +

+ +

+
+ + + + + + +
+
+ + + + + + +
+
+ ` ); } diff --git a/ui/component/or-chart/src/index.ts b/ui/component/or-chart/src/index.ts index b9255eff99..ac20c8c030 100644 --- a/ui/component/or-chart/src/index.ts +++ b/ui/component/or-chart/src/index.ts @@ -56,7 +56,7 @@ import { OrAssetTreeSelectionEvent } from "@openremote/or-asset-tree"; import { getAssetDescriptorIconTemplate } from "@openremote/or-icon"; import { type GenericAxiosResponse, isAxiosError } from "@openremote/rest"; import { OrAssetAttributePicker, OrAssetAttributePickerPickedEvent } from "@openremote/or-attribute-picker"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; import { type OrVaadinDialog, showDialog as showVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { cache } from "lit/directives/cache.js"; import debounce from "lodash.debounce"; @@ -65,6 +65,7 @@ import { when } from "lit/directives/when.js"; import { map } from "lit/directives/map.js"; import { createRef, type Ref, ref } from "lit/directives/ref.js"; import { createMenuBarItem, type MenuBarItem } from "@openremote/or-vaadin-components/or-vaadin-menu-bar"; +import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; echarts.use([ GridComponent, @@ -1240,10 +1241,12 @@ export class OrChart extends translate(i18next)(OrElement) { dialog?.close(); }; const onOk = () => { - if (startRef.value?.value && endRef.value?.value) { + if (startRef.value?.value && endRef.value?.value && startRef.value.value < endRef.value.value) { this._isCustomWindow = true; this.timeframe = [new Date(startRef.value.value), new Date(endRef.value.value)]; dialog?.close(); + } else { + showSnackbar(undefined, i18next.t("errorOccurred")); } }; dialog = showVaadinDialog( From b05e6a49419d3d91719324c1974d5f9ce5f279ee Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 14:54:18 +0200 Subject: [PATCH 14/42] Apply spotless --- ui/component/or-attribute-barchart/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/or-attribute-barchart/src/index.ts b/ui/component/or-attribute-barchart/src/index.ts index 7a90312752..2010593486 100644 --- a/ui/component/or-attribute-barchart/src/index.ts +++ b/ui/component/or-attribute-barchart/src/index.ts @@ -859,7 +859,7 @@ export class OrAttributeBarChart extends OrElement { const onCancel = () => { dialog?.close(); - } + }; const onOk = () => { if (startRef.value?.value && endRef.value?.value && startRef.value.value < endRef.value.value) { this._isCustomWindow = true; @@ -868,7 +868,7 @@ export class OrAttributeBarChart extends OrElement { } else { showSnackbar(undefined, i18next.t("errorOccurred")); } - } + }; dialog = showDialog( this.shadowRoot!, html` From 428a1d29dec9580781df0f0b8712beace8b0b3bd Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 15:12:26 +0200 Subject: [PATCH 15/42] Migrate 'add gateway tunnel' dialog with input fields to Vaadin --- .../manager/src/pages/page-gateway-tunnel.ts | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index 661e07b11f..d853f5f3ad 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -28,12 +28,14 @@ import { DefaultColor3, manager } from "@openremote/core"; import { type Asset, type AssetQuery, type GatewayTunnelInfo, GatewayTunnelInfoType } from "@openremote/model"; import type { TableColumn, TableRow } from "@openremote/or-mwc-components/or-mwc-table"; import { getAssetsRoute } from "../routes"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import moment from "moment"; import type { OrVaadinComboBox } from "@openremote/or-vaadin-components/or-vaadin-combo-box"; import type { OrVaadinSelect } from "@openremote/or-vaadin-components/or-vaadin-select"; import { getConfirmDialogContent, showConfirmDialog } from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; +import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; +import { createRef, ref, type Ref } from "lit/directives/ref.js"; export function pageGatewayTunnelProvider(store: Store): PageProvider { return { @@ -313,22 +315,16 @@ export class PageGatewayTunnel extends Page { */ protected _onAddTunnelClick() { const tunnel = this._getDefaultTunnelToAdd(); - let dialog: OrMwcDialog | undefined; + let dialog: OrVaadinDialog | undefined; + const buttonRef: Ref = createRef(); const onAddClick = () => { this._tryStartTunnel(tunnel); }; - const updateActions = () => { - dialog.setActions([ - { actionName: "cancel", content: "cancel" }, - { - actionName: "add", - disabled: !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort, - content: "add", - action: () => onAddClick(), - }, - ]); + const checkValidity = () => { + buttonRef.value.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; }; + const gatewayListTemplate = async (): Promise => { const gatewayAssets = await this._fetchGatewayAssets(); const items: { value: any; label: string }[] = gatewayAssets.map((g) => ({ value: g.id, label: g.name })); @@ -337,13 +333,13 @@ export class PageGatewayTunnel extends Page { label: String(g), })); return html` -
+
{ tunnel.gatewayId = (ev.currentTarget as OrVaadinComboBox).value; - updateActions(); + checkValidity(); }} > @@ -353,7 +349,7 @@ export class PageGatewayTunnel extends Page { value=${tunnel.type} @change=${(ev: Event) => { tunnel.type = (ev.currentTarget as OrVaadinSelect).value as GatewayTunnelInfoType; - updateActions(); + checkValidity(); }} > @@ -362,7 +358,7 @@ export class PageGatewayTunnel extends Page { value=${tunnel.target} @change=${(ev: Event) => { tunnel.target = (ev.currentTarget as HTMLInputElement).value; - updateActions(); + checkValidity(); }} > @@ -374,7 +370,8 @@ export class PageGatewayTunnel extends Page { @change=${(ev: Event) => { const value = (ev.currentTarget as HTMLInputElement).value; tunnel.targetPort = value ? Number(value) : undefined; - updateActions(); + buttonRef.value.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; + checkValidity(); }} > @@ -382,12 +379,26 @@ export class PageGatewayTunnel extends Page {
`; }; - dialog = new OrMwcDialog() - .setHeading(`${i18next.t("add")} ${i18next.t("tunnel")}`) - .setContent(html` ${until(gatewayListTemplate(), html`${i18next.t("loading")}`)} `); - - updateActions(); - showDialog(dialog); + dialog = showDialog( + this.shadowRoot!, + html` + +

+ ${i18next.t("add")} ${i18next.t("tunnel")} +

+ ${until(gatewayListTemplate(), html`${i18next.t("loading")}`)} +
+ dialog?.close()}> + + + onAddClick()}> + + +
+
+ + ` + ); } /** From 0325019e3049c1fc090554fc1eb54fc02054f7e9 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 16:46:02 +0200 Subject: [PATCH 16/42] Migrate 'add realm configuration' dialogs on appearance page to Vaadin --- .../components/configuration/or-conf-panel.ts | 129 ++++++++---------- 1 file changed, 58 insertions(+), 71 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-panel.ts b/ui/app/manager/src/components/configuration/or-conf-panel.ts index b58825665d..16f887c22a 100644 --- a/ui/app/manager/src/components/configuration/or-conf-panel.ts +++ b/ui/app/manager/src/components/configuration/or-conf-panel.ts @@ -18,18 +18,18 @@ */ import { html, type TemplateResult } from "lit"; import { OrElement } from "@openremote/or-element"; -import { InputType, OrInputChangedEvent } from "@openremote/or-mwc-components/or-mwc-input"; import { customElement, property } from "lit/decorators.js"; import { when } from "lit/directives/when.js"; import type { ManagerAppConfig, MapConfig } from "@openremote/model"; -import { type DialogAction, OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; -import { i18next } from "@openremote/or-translate"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; +import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; import "@openremote/or-components/or-loading-indicator"; import "./or-conf-map/or-conf-map-card"; import "./or-conf-realm/or-conf-realm-card"; import type { OrConfRealmCard } from "./or-conf-realm/or-conf-realm-card"; import type { OrConfMapCard } from "./or-conf-map/or-conf-map-card"; import type { OrVaadinSelect } from "@openremote/or-vaadin-components/or-vaadin-select"; +import { createRef, ref, type Ref } from "lit/directives/ref.js"; @customElement("or-conf-panel") export class OrConfPanel extends OrElement { @@ -184,39 +184,30 @@ export class OrConfPanel extends OrElement { // Show the dialog to "add realm", that allows users to override realm options. protected _showAddingRealmDialog() { this._addedRealm = null; - const dialogActions: DialogAction[] = [ - { - actionName: "cancel", - content: "cancel", - }, - { - default: true, - actionName: "ok", - content: "ok", - action: () => { - if (this._addedRealm) { - let realms = this.getRealmsProperty(this.config); - if (!realms) { - realms = {}; - } - if (this.isManagerConfig(this.config)) { - realms[this._addedRealm] = {}; // empty object since no fields are required - } else if (this.isMapConfig(this.config)) { - realms[this._addedRealm] = { - bounds: [4.42, 51.88, 4.55, 51.94], - center: [4.485222, 51.911712], - zoom: 14, - minZoom: 14, - maxZoom: 19, - boxZoom: false, - }; - } - this.requestUpdate("config"); - this.notifyConfigChange(this.config); - } - }, - }, - ]; + let dialog: OrVaadinDialog | undefined; + const onOk = () => { + if (this._addedRealm) { + let realms = this.getRealmsProperty(this.config); + if (!realms) { + realms = {}; + } + if (this.isManagerConfig(this.config)) { + realms[this._addedRealm] = {}; // empty object since no fields are required + } else if (this.isMapConfig(this.config)) { + realms[this._addedRealm] = { + bounds: [4.42, 51.88, 4.55, 51.94], + center: [4.485222, 51.911712], + zoom: 14, + minZoom: 14, + maxZoom: 19, + boxZoom: false, + }; + } + this.requestUpdate("config"); + this.notifyConfigChange(this.config); + dialog?.close(); + } + }; const headingKey = this.isMapConfig(this.config) ? "configuration.addMapCustomization" : "configuration.addRealmCustomization"; @@ -224,42 +215,38 @@ export class OrConfPanel extends OrElement { value: item.name, label: item.displayName, })); - showDialog( - new OrMwcDialog() - .setHeading(i18next.t(headingKey)) - .setActions(dialogActions) - .setContent(html` -
- (this._addedRealm = (ev.currentTarget as OrVaadinSelect).value)} - > - - -
- `) - .setStyles(html` - - `) - .setDismissAction(null) + const selectRef: Ref = createRef(); + const buttonRef: Ref = createRef(); + dialog = showDialog( + this.shadowRoot!, + html` + +

+ +

+ { + this._addedRealm = (ev.currentTarget as OrVaadinSelect).value; + buttonRef.value.disabled = !selectRef.value?.checkValidity(); + }} + > + + +
+ dialog?.close()}> + + + + + +
+
+ ` ); } } From 0912eb9ced2138f2edd9a590812abb1756e0c0c7 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:03:23 +0200 Subject: [PATCH 17/42] Migrate GeoJSON dialog on appearance page to Vaadin --- .../or-conf-map/or-conf-map-geojson.ts | 94 ++++++++----------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts index ab0f752a86..419482d23d 100644 --- a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts +++ b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts @@ -17,12 +17,14 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import type { GeoJsonConfig } from "@openremote/model"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { html } from "lit"; import { OrElement } from "@openremote/or-element"; import { customElement, property, state } from "lit/decorators.js"; import "@openremote/or-components/or-ace-editor"; -import type { OrAceEditorChangedEvent } from "@openremote/or-components/or-ace-editor"; +import type { OrAceEditor, OrAceEditorChangedEvent } from "@openremote/or-components/or-ace-editor"; +import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; +import { createRef, type Ref, ref } from "lit/directives/ref.js"; @customElement("or-conf-map-geojson") export class OrConfMapGeoJson extends OrElement { @@ -32,7 +34,7 @@ export class OrConfMapGeoJson extends OrElement { @state() protected _jsonValid: boolean = true; - protected _dialog: OrMwcDialog; + protected _dialog: OrVaadinDialog; // Value of or-ace-editor without state to prevent UI update protected _aceEditorValue: string; @@ -40,63 +42,49 @@ export class OrConfMapGeoJson extends OrElement { protected render() { return html` - this.showDialog()}> + this._showDialog()}> `; } - protected showDialog() { + protected _showDialog() { + const buttonRef: Ref = createRef(); + const editorRef: Ref = createRef(); + const onOk = () => { + this.geoJson = this.parseGeoJson(this._aceEditorValue); // update with new value + this.dispatchEvent(new CustomEvent("update", { detail: { value: this.geoJson } })); + }; this._dialog = showDialog( - new OrMwcDialog() - .setHeading("GeoJSON editor") - .setStyles( - html` ` - ) - .setActions([ - { - actionName: "close", - content: "close", - }, - { - actionName: "ok", - content: "update", - disabled: !this._jsonValid, - action: () => { - this.geoJson = this.parseGeoJson(this._aceEditorValue); // update with new value - this.dispatchEvent(new CustomEvent("update", { detail: { value: this.geoJson } })); - }, - }, - ]) - .setContent( - () => - html` ` - ) - .setDismissAction(null) + this.shadowRoot!, + html` + +

+ GeoJSON editor +

+ +
+ this._dialog?.close()}> + + + + + +
+
+ ` ); } From a9462073453ad5cc54b552d255460fcfd6c2a7de Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:05:35 +0200 Subject: [PATCH 18/42] Adjust to broken test; forgot to change 'OK' to the new 'delete' within the delete realm dialog. --- ui/app/manager/test/fixtures/pages/realms.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/manager/test/fixtures/pages/realms.ts b/ui/app/manager/test/fixtures/pages/realms.ts index e4a726d191..6ea3e144c4 100644 --- a/ui/app/manager/test/fixtures/pages/realms.ts +++ b/ui/app/manager/test/fixtures/pages/realms.ts @@ -60,6 +60,6 @@ export class RealmsPage implements BasePage { await this.page.getByRole("cell", { name: realm }).first().click(); await this.page.getByRole("button", { name: "Delete" }).click(); await this.page.getByRole("alertdialog").getByRole("textbox", { name: "Realm" }).fill(realm); - await this.page.getByRole("button", { name: "OK" }).click(); + await this.page.getByRole("button", { name: "Delete" }).click(); } } From 3498fff413147ea9ce95ba56f91557b5c2659065 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:12:34 +0200 Subject: [PATCH 19/42] Migrate asset tree dialog on edit/add users page to Vaadin --- ui/app/manager/src/pages/page-users.ts | 66 ++++++++++++-------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/ui/app/manager/src/pages/page-users.ts b/ui/app/manager/src/pages/page-users.ts index 59eaefbee2..a66d46f6a8 100644 --- a/ui/app/manager/src/pages/page-users.ts +++ b/ui/app/manager/src/pages/page-users.ts @@ -33,7 +33,7 @@ import { type UserSession, } from "@openremote/model"; import { i18next } from "@openremote/or-translate"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import { type GenericAxiosResponse, isAxiosError } from "@openremote/rest"; import type { OrAssetTreeRequestSelectionEvent, OrAssetTreeSelectionEvent } from "@openremote/or-asset-tree"; @@ -826,10 +826,26 @@ export class PageUsers extends Page { }); }; - const dialog = showDialog( - new OrMwcDialog() - .setHeading(i18next.t("linkedAssets")) - .setContent(html` + let dialog: OrVaadinDialog | undefined; + const onCancel = () => { + user.userAssetLinks = user.previousAssetLinks; + user.previousAssetLinks = undefined; + openBtn.disabled = false; + dialog?.close(); + } + const onOk = () => { + openBtn.disabled = false; + this.onUserChanged(suffix); + this.requestUpdate(); + } + + dialog = showDialog( + this.shadowRoot!, + html` + +

+ +

{ } }}" > - `) - .setActions([ - { - default: true, - actionName: "cancel", - content: "cancel", - action: () => { - user.userAssetLinks = user.previousAssetLinks; - user.previousAssetLinks = undefined; - openBtn.disabled = false; - }, - }, - { - actionName: "ok", - content: "ok", - action: () => { - openBtn.disabled = false; - this.onUserChanged(suffix); - this.requestUpdate(); - }, - }, - ]) - .setDismissAction({ - actionName: "cancel", - action: () => { - user.userAssetLinks = user.previousAssetLinks; - user.previousAssetLinks = undefined; - openBtn.disabled = false; - }, - }) +
+ + + + + + +
+
+ ` ); } From 245ff852cf24e96a1716244adc64648cac796a47 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:13:22 +0200 Subject: [PATCH 20/42] WIP --- ui/app/manager/src/pages/page-users.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/manager/src/pages/page-users.ts b/ui/app/manager/src/pages/page-users.ts index a66d46f6a8..3f24be998c 100644 --- a/ui/app/manager/src/pages/page-users.ts +++ b/ui/app/manager/src/pages/page-users.ts @@ -837,6 +837,7 @@ export class PageUsers extends Page { openBtn.disabled = false; this.onUserChanged(suffix); this.requestUpdate(); + dialog?.close(); } dialog = showDialog( From 1d35795b0155a019429c11fadcf27e98bcc20268 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:26:07 +0200 Subject: [PATCH 21/42] Migrate asset selection of Insights assettypes-panel (map+table widgets) to Vaadin --- .../src/panels/assettypes-panel.ts | 93 +++++++++---------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts b/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts index 126a312284..4d4f8495e9 100644 --- a/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts +++ b/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts @@ -26,7 +26,7 @@ import { Util } from "@openremote/core"; import { when } from "lit/directives/when.js"; import { createRef, type Ref, ref } from "lit/directives/ref.js"; import type { AssetTreeConfig, OrAssetTree } from "@openremote/or-asset-tree"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { type ComboBoxLitRenderer, comboBoxRenderer, @@ -314,56 +314,49 @@ export class AssettypesPanel extends OrElement { multiSelect: multi, }, } as AssetTreeConfig; - const dialog = showDialog( - new OrMwcDialog() - .setHeading(i18next.t("linkedAssets")) - .setStyles( - html`` - ) - .setContent(html` -
- + + let dialog: OrVaadinDialog | undefined; + const onCancel = () => dialog?.close(); + const onOk = () => { + const tree = assetTreeRef.value; + if (tree?.selectedIds) { + if (multi) { + this.assetIds = tree.selectedIds; + } else { + this.assetIds = tree.selectedIds[0]; + } + } + dialog?.close(); + } + + dialog = showDialog( + this.shadowRoot!, + html` + +

+ +

+ +
+ + + + + +
- `) - .setActions([ - { - default: true, - actionName: "cancel", - content: "cancel", - }, - { - actionName: "ok", - content: "ok", - action: () => { - const tree = assetTreeRef.value; - if (tree?.selectedIds) { - if (multi) { - this.assetIds = tree.selectedIds; - } else { - this.assetIds = tree.selectedIds[0]; - } - } - }, - }, - ]) - .setDismissAction({ - actionName: "cancel", - }) +
+ ` ); } } From 38d83f6ff56955c4eacaa9cdc64b4196adf39aef Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:26:58 +0200 Subject: [PATCH 22/42] Apply spotless --- ui/app/manager/src/pages/page-users.ts | 4 ++-- .../or-dashboard-builder/src/panels/assettypes-panel.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/app/manager/src/pages/page-users.ts b/ui/app/manager/src/pages/page-users.ts index 3f24be998c..035723b213 100644 --- a/ui/app/manager/src/pages/page-users.ts +++ b/ui/app/manager/src/pages/page-users.ts @@ -832,13 +832,13 @@ export class PageUsers extends Page { user.previousAssetLinks = undefined; openBtn.disabled = false; dialog?.close(); - } + }; const onOk = () => { openBtn.disabled = false; this.onUserChanged(suffix); this.requestUpdate(); dialog?.close(); - } + }; dialog = showDialog( this.shadowRoot!, diff --git a/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts b/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts index 4d4f8495e9..c54a0bc285 100644 --- a/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts +++ b/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts @@ -327,7 +327,7 @@ export class AssettypesPanel extends OrElement { } } dialog?.close(); - } + }; dialog = showDialog( this.shadowRoot!, From 48b8549bdc0febb99f652a784cfbfefbad0187f9 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Tue, 29 Sep 2026 17:39:54 +0200 Subject: [PATCH 23/42] Migrate JSON editor in Manager interconnect page to Vaadin --- ui/app/manager/src/pages/page-gateway.ts | 88 ++++++++++--------- .../or-attribute-barchart/src/index.ts | 1 - 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/ui/app/manager/src/pages/page-gateway.ts b/ui/app/manager/src/pages/page-gateway.ts index 034bc5b4ea..445ce30e58 100644 --- a/ui/app/manager/src/pages/page-gateway.ts +++ b/ui/app/manager/src/pages/page-gateway.ts @@ -23,7 +23,8 @@ import { when } from "lit/directives/when.js"; import { until } from "lit/directives/until.js"; import { createRef, type Ref, ref } from "lit/directives/ref.js"; import "@openremote/or-components/or-panel"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog as showVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { type AttributeDescriptor, type AttributePredicate, @@ -35,7 +36,7 @@ import { LogicGroupOperator, type GatewayAssetSyncRule, } from "@openremote/model"; -import manager, { DefaultColor1, DefaultColor3 } from "@openremote/core"; +import manager, { DefaultColor1 } from "@openremote/core"; import { InputType, type OrInputChangedEvent } from "@openremote/or-mwc-components/or-mwc-input"; import type { OrVaadinToggle } from "@openremote/or-vaadin-components/or-vaadin-toggle"; import { type AppStateKeyed, Page, type PageProvider } from "@openremote/or-app"; @@ -756,49 +757,56 @@ export class PageGateway extends Page { * The changed are only applied once the save button is pressed. */ protected _openConnectionJSONEditor(connection?: GatewayConnection) { + let dialog: OrVaadinDialog | undefined; const editorRef: Ref = createRef(); - showDialog( - new OrMwcDialog() - .setHeading("JSON Editor") - .setContent(html` + const onCancel = () => dialog?.close(); + const onOk = () => { + const editor = editorRef.value; + if (!editor.validate()) { + console.warn("JSON was not valid"); + showSnackbar(undefined, i18next.t("errorOccurred")); + return; + } + try { + let parsed: GatewayAttributeFilter[] | undefined; + if (editor.getValue().length > 0) { + parsed = JSON.parse(editor.getValue()); + + // Verify if the JSON is an array. If so; simply accept the format. + if (!Array.isArray(parsed)) { + console.warn("Could not parse JSON to GatewayAttributeFilter[], as it was not an array."); + showSnackbar(undefined, i18next.t("errorOccurred")); + return; + } + } + this._updateAttributeFilters(parsed); + } catch (e) { + console.error(e); + showSnackbar(undefined, i18next.t("errorOccurred")); + } + }; + dialog = showVaadinDialog( + this.shadowRoot!, + html` + +

+ JSON Editor +

- `) - .setActions([ - { actionName: "cancel", content: "cancel" }, - { - actionName: "save", - content: "save", - action: () => { - const editor = editorRef.value; - if (!editor.validate()) { - console.warn("JSON was not valid"); - showSnackbar(undefined, i18next.t("errorOccurred")); - return; - } - try { - let parsed: GatewayAttributeFilter[] | undefined; - if (editor.getValue().length > 0) { - parsed = JSON.parse(editor.getValue()); - - // Verify if the JSON is an array. If so; simply accept the format. - if (!Array.isArray(parsed)) { - console.warn("Could not parse JSON to GatewayAttributeFilter[], as it was not an array."); - showSnackbar(undefined, i18next.t("errorOccurred")); - return; - } - } - this._updateAttributeFilters(parsed); - } catch (e) { - console.error(e); - showSnackbar(undefined, i18next.t("errorOccurred")); - } - }, - }, - ]) +
+ + + + + + +
+
+ ` ); } } diff --git a/ui/component/or-attribute-barchart/src/index.ts b/ui/component/or-attribute-barchart/src/index.ts index 2010593486..93dba35345 100644 --- a/ui/component/or-attribute-barchart/src/index.ts +++ b/ui/component/or-attribute-barchart/src/index.ts @@ -648,7 +648,6 @@ export class OrAttributeBarChart extends OrElement { } protected _getTimeControlsTemplate(disabled: boolean): TemplateResult { - console.debug("Disabled?", disabled); const menuItems: MenuBarItem[] = [ { component: createMenuBarItem( From 55e069b0273efcd84a304d3ec262cf4efef0e60c Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Wed, 30 Sep 2026 09:46:57 +0200 Subject: [PATCH 24/42] Fix for test cleanup failing because it was accidentally detecting two delete buttons --- ui/app/manager/test/fixtures/pages/realms.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/manager/test/fixtures/pages/realms.ts b/ui/app/manager/test/fixtures/pages/realms.ts index 6ea3e144c4..291dc98f3a 100644 --- a/ui/app/manager/test/fixtures/pages/realms.ts +++ b/ui/app/manager/test/fixtures/pages/realms.ts @@ -60,6 +60,6 @@ export class RealmsPage implements BasePage { await this.page.getByRole("cell", { name: realm }).first().click(); await this.page.getByRole("button", { name: "Delete" }).click(); await this.page.getByRole("alertdialog").getByRole("textbox", { name: "Realm" }).fill(realm); - await this.page.getByRole("button", { name: "Delete" }).click(); + await this.page.getByRole("alertdialog").getByRole("button", { name: "Delete" }).click(); } } From a227a8ab65d094bc7917d6bde28477cc223b2fdd Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Wed, 30 Sep 2026 13:22:23 +0200 Subject: [PATCH 25/42] Migrate 'change parents of multiple assets when selected' dialog to Vaadin --- ui/app/manager/src/pages/page-assets.ts | 108 +++++++++--------------- 1 file changed, 42 insertions(+), 66 deletions(-) diff --git a/ui/app/manager/src/pages/page-assets.ts b/ui/app/manager/src/pages/page-assets.ts index 39ef7679af..a3ff4229b5 100644 --- a/ui/app/manager/src/pages/page-assets.ts +++ b/ui/app/manager/src/pages/page-assets.ts @@ -43,16 +43,16 @@ import { OrAssetTreeRequestSelectionEvent, OrAssetTreeSelectionEvent, } from "@openremote/or-asset-tree"; -import manager, { DefaultBoxShadow, DefaultColor5, Util } from "@openremote/core"; +import manager, { DefaultBoxShadow, Util } from "@openremote/core"; import { type AppStateKeyed, Page, type PageProvider, router } from "@openremote/or-app"; import { createSlice, type Store, createSelector } from "@reduxjs/toolkit"; -import { type DialogAction, OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; -import { i18next } from "@openremote/or-translate"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { type Asset, AssetEventCause, WellknownAssets } from "@openremote/model"; import "@openremote/or-json-forms"; import { getAlarmsRoute, getAssetsRoute, getUsersRoute } from "../routes"; import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import { getConfirmDialogContent, showConfirmDialog } from "@openremote/or-vaadin-components/or-vaadin-confirm-dialog"; +import { createRef, ref, type Ref } from "lit/directives/ref.js"; export interface PageAssetsConfig { viewer?: ViewerConfig; @@ -274,23 +274,13 @@ export class PageAssets extends Page { } protected _onParentChangeClick() { - let dialog: OrMwcDialog; + let dialog: OrVaadinDialog | undefined; + const assetTreeRef: Ref = createRef(); - const blockEvent = (ev: Event) => { - ev.stopPropagation(); - }; - - const dialogContent = html` `; + const blockEvent = (ev: Event) => ev.stopPropagation(); const setParent = () => { - const assetTree = dialog.shadowRoot!.getElementById("parent-asset-tree") as OrAssetTree; + const assetTree = assetTreeRef.value; const idd = assetTree.selectedIds!.length === 1 ? assetTree.selectedIds![0] : undefined; this._onAssetParentChange({ parentId: idd, assetIds: this._assetIds }); }; @@ -299,57 +289,43 @@ export class PageAssets extends Page { this._onAssetParentChange({ parentId: undefined, assetIds: this._assetIds }); }; - const dialogActions: DialogAction[] = [ - { - actionName: "clear", - content: "none", - action: clearParent, - }, - { - actionName: "ok", - content: "ok", - action: setParent, - }, - { - default: true, - actionName: "cancel", - content: "cancel", - }, - ]; + const onCancel = () => dialog?.close(); + const onOk = () => { + setParent(); + dialog?.close(); + }; dialog = showDialog( - new OrMwcDialog() - .setContent(dialogContent) - .setActions(dialogActions) - .setStyles(html` - - `) - .setHeading(i18next.t("setParent")) - .setDismissAction(null) + this.shadowRoot!, + html` + +

+ +

+ +
+ + + +
+ + + + + + +
+
+
+ ` ); } From bf084ff8ff5434e35d0859f585f797d44c51b5a3 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Wed, 30 Sep 2026 14:09:05 +0200 Subject: [PATCH 26/42] Migrate 'add asset' dialog on Assets page to Vaadin --- ui/app/manager/src/pages/page-assets.ts | 3 +- ui/component/or-asset-tree/src/index.ts | 176 ++++++++++++------------ 2 files changed, 88 insertions(+), 91 deletions(-) diff --git a/ui/app/manager/src/pages/page-assets.ts b/ui/app/manager/src/pages/page-assets.ts index a3ff4229b5..5af526c45b 100644 --- a/ui/app/manager/src/pages/page-assets.ts +++ b/ui/app/manager/src/pages/page-assets.ts @@ -308,6 +308,7 @@ export class PageAssets extends Page { disableSubscribe readonly .selectedIds="${[]}" + style="width: 100%; aspect-ratio: 1/1.5;" @or-asset-tree-request-selection="${blockEvent}" @or-asset-tree-selection="${blockEvent}" > @@ -316,7 +317,7 @@ export class PageAssets extends Page {
- + diff --git a/ui/component/or-asset-tree/src/index.ts b/ui/component/or-asset-tree/src/index.ts index 43f6859828..21a467d2b9 100644 --- a/ui/component/or-asset-tree/src/index.ts +++ b/ui/component/or-asset-tree/src/index.ts @@ -62,12 +62,12 @@ import { getAssetDescriptorIconTemplate, type OrIcon } from "@openremote/or-icon import type { ListItem } from "@openremote/or-mwc-components/or-mwc-list"; import "@openremote/or-mwc-components/or-mwc-list"; import { i18next } from "@openremote/or-translate"; -import "@openremote/or-mwc-components/or-mwc-dialog"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import type { OrAddAssetDialog, OrAddChangedEvent } from "./or-add-asset-dialog"; import "./or-add-asset-dialog"; import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar"; import { when } from "lit/directives/when.js"; +import { createRef, ref, type Ref } from "lit/directives/ref.js"; import debounce from "lodash.debounce"; export interface AssetTreeTypeConfig { @@ -1627,108 +1627,104 @@ export class OrAssetTree extends subscribe(manager)(OrElement) { const agentTypes = types.filter((t) => t.descriptorType === "agent"); const assetTypes = types.filter((t) => t.descriptorType === "asset"); const parent = this._selectedNodes && this._selectedNodes.length === 1 ? this._selectedNodes[0].asset : undefined; - let dialog: OrMwcDialog; + let dialog: OrVaadinDialog | undefined; + const addAssetDialogRef: Ref = createRef(); + const addBtnRef: Ref = createRef(); const onAddChanged = (ev: OrAddChangedEvent) => { const nameValid = !!ev.detail.name && ev.detail.name.trim().length > 0 && ev.detail.name.trim().length < 1024; - const addBtn = dialog.shadowRoot!.getElementById("add-btn") as OrVaadinButton; - addBtn.disabled = !ev.detail.descriptor || !nameValid; + const addBtn = addBtnRef.value; + addBtn!.disabled = !ev.detail.descriptor || !nameValid; + }; + const onCancel = () => dialog?.close(); + const onOk = () => { + const addAssetDialog = addAssetDialogRef.value; + const descriptor = addAssetDialog!.selectedType; + const selectedOptionalAttributes = addAssetDialog!.selectedAttributes; + const name = addAssetDialog!.name.trim(); + const parent = addAssetDialog!.parent; + + if (!descriptor) { + return; + } + + const asset: Asset = { + name, + type: descriptor.name, + realm: manager.displayRealm, + }; + + // Construct attributes + const assetTypeInfo = AssetModelUtil.getAssetTypeInfo(descriptor.name!); + + if (!assetTypeInfo) { + return; + } + + if (assetTypeInfo.attributeDescriptors) { + asset.attributes = {}; + assetTypeInfo.attributeDescriptors + .filter((attributeDescriptor) => !attributeDescriptor.optional) + .forEach((attributeDescriptor) => { + asset.attributes![attributeDescriptor.name!] = { + name: attributeDescriptor.name, + type: attributeDescriptor.type, + meta: attributeDescriptor.meta ? { ...attributeDescriptor.meta } : undefined, + } as Attribute; + }); + } + + if (selectedOptionalAttributes) { + selectedOptionalAttributes?.forEach((attribute) => { + asset.attributes![attribute.name!] = { + name: attribute.name, + type: attribute.type, + meta: attribute.meta ? { ...attribute.meta } : undefined, + }; + }); + } + + if (this.selectedIds) { + asset.parentId = parent ? parent.id : undefined; + } + const detail: AddEventDetail = { + asset, + }; + dialog?.close(); + Util.dispatchCancellableEvent(this, new OrAssetTreeRequestAddEvent(detail)).then((detail) => { + if (detail.allow) { + this.dispatchEvent(new OrAssetTreeAddEvent(detail.detail)); + } + }); }; dialog = showDialog( - new OrMwcDialog() - .setHeading(i18next.t("addAsset")) - .setContent(html` + this.shadowRoot!, + html` + +

+ +

- `) - .setActions([ - { - actionName: "cancel", - content: html``, - }, - { - actionName: "add", - content: html` - - `, - action: () => { - const addAssetDialog = dialog.shadowRoot!.getElementById("add-panel") as OrAddAssetDialog; - const descriptor = addAssetDialog.selectedType; - const selectedOptionalAttributes = addAssetDialog.selectedAttributes; - const name = addAssetDialog.name.trim(); - const parent = addAssetDialog.parent; - - if (!descriptor) { - return; - } - - const asset: Asset = { - name, - type: descriptor.name, - realm: manager.displayRealm, - }; - - // Construct attributes - const assetTypeInfo = AssetModelUtil.getAssetTypeInfo(descriptor.name!); - - if (!assetTypeInfo) { - return; - } - - if (assetTypeInfo.attributeDescriptors) { - asset.attributes = {}; - assetTypeInfo.attributeDescriptors - .filter((attributeDescriptor) => !attributeDescriptor.optional) - .forEach((attributeDescriptor) => { - asset.attributes![attributeDescriptor.name!] = { - name: attributeDescriptor.name, - type: attributeDescriptor.type, - meta: attributeDescriptor.meta ? { ...attributeDescriptor.meta } : undefined, - } as Attribute; - }); - } - - if (selectedOptionalAttributes) { - selectedOptionalAttributes?.forEach((attribute) => { - asset.attributes![attribute.name!] = { - name: attribute.name, - type: attribute.type, - meta: attribute.meta ? { ...attribute.meta } : undefined, - }; - }); - } - - if (this.selectedIds) { - asset.parentId = parent ? parent.id : undefined; - } - const detail: AddEventDetail = { - asset, - }; - Util.dispatchCancellableEvent(this, new OrAssetTreeRequestAddEvent(detail)).then((detail) => { - if (detail.allow) { - this.dispatchEvent(new OrAssetTreeAddEvent(detail.detail)); - } - }); - }, - }, - ]) - .setStyles(html` - - `) - .setDismissAction(null) +
+ + + + + + +
+
+ + ` ); } From e592c691791bae58f00439d4308a18d09956771e Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Wed, 30 Sep 2026 16:53:18 +0200 Subject: [PATCH 27/42] Migrate asset dialogs (change parent, add attribute, add meta item) to new Vaadin dialog format. Adjusted tests to behave as expected. --- ui/app/manager/src/pages/page-assets.ts | 2 +- ui/app/manager/test/assets.test.ts | 8 +- ui/app/manager/test/fixtures/pages/assets.ts | 2 +- ui/component/or-asset-tree/src/index.ts | 2 +- .../src/or-add-attribute-panel.ts | 5 +- .../src/or-edit-asset-panel.ts | 271 +++++++----------- .../or-asset-viewer/test/fixtures/index.ts | 2 +- 7 files changed, 120 insertions(+), 172 deletions(-) diff --git a/ui/app/manager/src/pages/page-assets.ts b/ui/app/manager/src/pages/page-assets.ts index 5af526c45b..ef9ba647b1 100644 --- a/ui/app/manager/src/pages/page-assets.ts +++ b/ui/app/manager/src/pages/page-assets.ts @@ -308,7 +308,7 @@ export class PageAssets extends Page { disableSubscribe readonly .selectedIds="${[]}" - style="width: 100%; aspect-ratio: 1/1.5;" + style="width: 100%; aspect-ratio: 1/1.75;" @or-asset-tree-request-selection="${blockEvent}" @or-asset-tree-selection="${blockEvent}" > diff --git a/ui/app/manager/test/assets.test.ts b/ui/app/manager/test/assets.test.ts index 16d4bab650..4dd762019d 100644 --- a/ui/app/manager/test/assets.test.ts +++ b/ui/app/manager/test/assets.test.ts @@ -195,8 +195,8 @@ test.describe("Parent asset", () => { await assetViewer.switchMode("modify"); await page.getByText("Parent Edit").getByRole("button").click(); - await page.getByLabel("Select parent asset").getByText("Parent").click(); - await page.getByLabel("Select parent asset").getByRole("button", { name: "OK" }).click(); + await page.getByRole("dialog").getByText("Parent").click(); + await page.getByRole("dialog").getByRole("button", { name: "OK" }).click(); await page.getByRole("button", { name: "Save" }).click(); await expect(page.getByRole("textbox", { name: "Parent" })).toHaveValue("Parent"); @@ -217,7 +217,7 @@ test.describe("Parent asset", () => { await assetViewer.switchMode("modify"); await page.getByText("Parent Edit").getByRole("button").click(); - await page.getByLabel("Select parent asset").getByRole("button", { name: "NONE" }).click(); + await page.getByRole("dialog").getByRole("button", { name: "Clear" }).click(); await page.getByRole("button", { name: "Save" }).click(); await expect(page.getByRole("textbox", { name: "Parent" })).toBeEmpty(); @@ -243,7 +243,7 @@ test.describe("Attributes", () => { await page.getByRole("button", { name: "Add attribute" }).click(); - const dialog = page.getByLabel("Add attribute"); + const dialog = page.getByRole("dialog"); await dialog.getByLabel("Name").fill("test"); await dialog.getByRole("combobox", { name: "Value type", exact: true }).fill("Int"); await dialog.getByRole("option", { name: "Integer", exact: true }).click(); diff --git a/ui/app/manager/test/fixtures/pages/assets.ts b/ui/app/manager/test/fixtures/pages/assets.ts index bad4004e3e..5f01459e1d 100644 --- a/ui/app/manager/test/fixtures/pages/assets.ts +++ b/ui/app/manager/test/fixtures/pages/assets.ts @@ -50,7 +50,7 @@ export class AssetsPage implements BasePage { await this.shared.interceptResponse("**/asset", (asset) => { if (asset) this.manager.assets.push(asset); }); - await this.page.click("#add-btn"); + await this.page.getByRole("button", { name: "Add" }).click(); } /** diff --git a/ui/component/or-asset-tree/src/index.ts b/ui/component/or-asset-tree/src/index.ts index 21a467d2b9..c7cf6afba9 100644 --- a/ui/component/or-asset-tree/src/index.ts +++ b/ui/component/or-asset-tree/src/index.ts @@ -1719,7 +1719,7 @@ export class OrAssetTree extends subscribe(manager)(OrElement) { - +
diff --git a/ui/component/or-asset-viewer/src/or-add-attribute-panel.ts b/ui/component/or-asset-viewer/src/or-add-attribute-panel.ts index 052d4e8c47..919ede1842 100644 --- a/ui/component/or-asset-viewer/src/or-add-attribute-panel.ts +++ b/ui/component/or-asset-viewer/src/or-add-attribute-panel.ts @@ -70,7 +70,6 @@ export class OrAddAttributePanel extends OrElement { return css` #attribute-creator { min-width: 300px; - padding: 20px; display: flex; flex-direction: column; gap: 10px; @@ -129,11 +128,11 @@ export class OrAddAttributePanel extends OrElement { @change=${(ev: CustomEvent) => this.onValueTypeChanged((ev.currentTarget as OrVaadinComboBox).value)}> - this.onArrayChanged((ev.currentTarget as OrVaadinCheckbox).checked, 1)}> - this.onArrayChanged(true, Number((ev.currentTarget as OrVaadinNumberField).value))}> diff --git a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts index afddc0df50..ba504e3926 100644 --- a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts +++ b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts @@ -24,7 +24,7 @@ import { type ValueInputProviderOptions, getValueHolderInputTemplateProvider, } from "@openremote/or-vaadin-components/value-input-provider"; -import { InputType, type OrMwcInput, type OrInputChangedEvent } from "@openremote/or-mwc-components/or-mwc-input"; +import { InputType, type OrInputChangedEvent } from "@openremote/or-mwc-components/or-mwc-input"; import { i18next } from "@openremote/or-translate"; import { type Asset, @@ -36,7 +36,8 @@ import { import { DefaultColor5, DefaultColor3, Util } from "@openremote/core"; import "@openremote/or-mwc-components/or-mwc-input"; import type { OrIcon } from "@openremote/or-icon"; -import { showDialog, OrMwcDialog, type DialogAction } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { showDialog, type OrVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; +import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; import { type ListItem, ListType, type OrMwcList } from "@openremote/or-mwc-components/or-mwc-list"; import "./or-add-attribute-panel"; import { getField, getPanel, getPropertyTemplate } from "./index"; @@ -591,6 +592,7 @@ export class OrEditAssetPanel extends OrElement { protected _addAttribute() { const asset = this.asset!; let attr: Attribute; + const addBtnRef: Ref = createRef(); const isDisabled = (attribute: Attribute) => { return !( @@ -602,53 +604,42 @@ export class OrEditAssetPanel extends OrElement { ); }; - const onAttributeChanged = (attribute: Attribute) => { - const addDisabled = isDisabled(attribute); - const addBtn = dialog!.shadowRoot!.getElementById("add-btn") as OrMwcInput; - addBtn!.disabled = addDisabled; + const onAttributeChanged = (ev: OrAddAttributePanelAttributeChangedEvent) => { + const attribute = ev.detail; + addBtnRef.value!.disabled = isDisabled(attribute); attr = attribute; }; + const onOk = () => { + if (!isDisabled(attr)) { + this.asset.attributes![attr.name!] = attr; + this._onModified(); + this.requestUpdate(); + dialog?.close(); + } + }; + const dialog = showDialog( - new OrMwcDialog() - .setContent(html` + this.shadowRoot!, + html` + +

+ +

- `) - .setStyles(html` - - `) - .setHeading(i18next.t("addAttribute")) - .setActions([ - { - actionName: "cancel", - content: "cancel", - }, - { - default: true, - actionName: "add", - action: () => { - if (!isDisabled(attr)) { - this.asset.attributes![attr.name!] = attr; - this._onModified(); - this.requestUpdate(); - } - }, - content: html``, - }, - ]) - .setDismissAction(null) +
+ dialog?.close()}> + + + + + +
+
+ ` ); } @@ -672,73 +663,55 @@ export class OrEditAssetPanel extends OrElement { }) .sort(Util.sortByString((item) => item.text)); + const listRef: Ref = createRef(); + const onOk = () => { + const list = listRef.value; + const selectedItems = list ? list.selectedItems : undefined; + if (selectedItems) { + if (!attribute.meta) { + attribute.meta = {}; + } + selectedItems.forEach((item) => { + const descriptor = AssetModelUtil.getMetaItemDescriptors().find( + (descriptor) => descriptor.name === item.value + ); + if (descriptor) { + attribute.meta![descriptor.name!] = descriptor.type === "boolean" ? true : null; + this._onModified(); + this.requestUpdate(); + } + }); + dialog?.close(); + } + }; + const dialog = showDialog( - new OrMwcDialog() - .setContent(html` -
- + this.shadowRoot!, + html` + +

+ +

+ +
+ dialog?.close()}> + + + + +
- `) - .setStyles(html` - - `) - .setHeading(i18next.t("addMetaItems")) - .setActions([ - { - actionName: "cancel", - content: "cancel", - }, - { - default: true, - actionName: "add", - action: () => { - const list = dialog!.shadowRoot!.getElementById("meta-creator-list") as OrMwcList; - const selectedItems = list ? list.selectedItems : undefined; - if (selectedItems) { - if (!attribute.meta) { - attribute.meta = {}; - } - selectedItems.forEach((item) => { - const descriptor = AssetModelUtil.getMetaItemDescriptors().find( - (descriptor) => descriptor.name === item.value - ); - if (descriptor) { - attribute.meta![descriptor.name!] = descriptor.type === "boolean" ? true : null; - this._onModified(); - this.requestUpdate(); - } - }); - } - }, - content: "add", - }, - ]) - .setDismissAction(null) +
+ ` ); } protected _getParentTemplate() { - let dialog: OrMwcDialog; + let dialog: OrVaadinDialog | undefined; + const assetTreeRef: Ref = createRef(); const setParent = () => { - const assetTree = dialog.shadowRoot!.getElementById("parent-asset-tree") as OrAssetTree; + const assetTree = assetTreeRef.value!; this.asset.parentId = assetTree.selectedIds!.length === 1 ? assetTree.selectedIds![0] : undefined; // Need to update the assets path as well const path = [this.asset.id!]; @@ -757,72 +730,48 @@ export class OrEditAssetPanel extends OrElement { this._onModified(); }; - const blockEvent = (ev: Event) => { - ev.stopPropagation(); - }; + const blockEvent = (ev: Event) => ev.stopPropagation(); const parentSelector = (node: UiAssetTreeNode) => node.asset!.id !== this.asset.id; - // Prevent change event from bubbling up as it will affect any ancestor listeners that are interested in a different asset tree - const dialogContent = html``; - - const dialogActions: DialogAction[] = [ - { - actionName: "clear", - content: "none", - action: clearParent, - }, - { - actionName: "ok", - content: "ok", - action: setParent, - }, - { - default: true, - actionName: "cancel", - content: "cancel", - }, - ]; + const onOk = () => { + setParent(); + dialog?.close(); + }; const openDialog = () => { dialog = showDialog( - new OrMwcDialog() - .setContent(dialogContent) - .setActions(dialogActions) - .setStyles(html` - - `) - .setHeading(i18next.t("setParent")) - .setDismissAction(null) + this.shadowRoot!, + html` + +

+ +

+ +
+ dialog?.close()}> + + +
+ + + + + + +
+
+
+ ` ); }; diff --git a/ui/component/or-asset-viewer/test/fixtures/index.ts b/ui/component/or-asset-viewer/test/fixtures/index.ts index 28cffb3b79..8fc1ec67ba 100644 --- a/ui/component/or-asset-viewer/test/fixtures/index.ts +++ b/ui/component/or-asset-viewer/test/fixtures/index.ts @@ -77,7 +77,7 @@ export class AssetViewer { .locator("li", { has: this.page.getByText(Util.camelCaseToSentenceCase(item), { exact: true }) }) .check(); } - await this.page.getByRole("button", { name: "Add", exact: true }).click(); + await this.page.getByRole("dialog").getByRole("button", { name: "Add", exact: true }).click(); } /** From 40b7d8305b55c7280e444c794d7d950c93fcb061 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 1 Oct 2026 11:33:08 +0200 Subject: [PATCH 28/42] Code cleanup and fix several cases where dialog was not closed. --- .../components/configuration/or-conf-map/or-conf-map-geojson.ts | 1 + ui/app/manager/src/pages/page-assets.ts | 1 + ui/app/manager/src/pages/page-gateway-tunnel.ts | 1 - ui/component/or-asset-tree/src/index.ts | 1 - ui/component/or-asset-viewer/src/or-edit-asset-panel.ts | 1 + 5 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts index 419482d23d..869376844e 100644 --- a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts +++ b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts @@ -55,6 +55,7 @@ export class OrConfMapGeoJson extends OrElement { const onOk = () => { this.geoJson = this.parseGeoJson(this._aceEditorValue); // update with new value this.dispatchEvent(new CustomEvent("update", { detail: { value: this.geoJson } })); + this._dialog?.close(); }; this._dialog = showDialog( this.shadowRoot!, diff --git a/ui/app/manager/src/pages/page-assets.ts b/ui/app/manager/src/pages/page-assets.ts index ef9ba647b1..0ad2f269ef 100644 --- a/ui/app/manager/src/pages/page-assets.ts +++ b/ui/app/manager/src/pages/page-assets.ts @@ -287,6 +287,7 @@ export class PageAssets extends Page { const clearParent = () => { this._onAssetParentChange({ parentId: undefined, assetIds: this._assetIds }); + dialog?.close(); }; const onCancel = () => dialog?.close(); diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index d853f5f3ad..8d15f03c8c 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -396,7 +396,6 @@ export class PageGatewayTunnel extends Page {
- ` ); } diff --git a/ui/component/or-asset-tree/src/index.ts b/ui/component/or-asset-tree/src/index.ts index c7cf6afba9..c5016476d3 100644 --- a/ui/component/or-asset-tree/src/index.ts +++ b/ui/component/or-asset-tree/src/index.ts @@ -1722,7 +1722,6 @@ export class OrAssetTree extends subscribe(manager)(OrElement) {

-
` ); diff --git a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts index ba504e3926..688426047e 100644 --- a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts +++ b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts @@ -728,6 +728,7 @@ export class OrEditAssetPanel extends OrElement { this.asset.parentId = undefined; this.asset.path = [this.asset.id!]; this._onModified(); + dialog?.close(); }; const blockEvent = (ev: Event) => ev.stopPropagation(); From 52418bf8ff8c4241fd2acf38c2138adcbad4a2af Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 1 Oct 2026 11:53:04 +0200 Subject: [PATCH 29/42] More cleanup, revert textual changes in OK/cancel buttons, and other minor fixes --- ui/app/manager/src/components/configuration/or-conf-json.ts | 6 +++--- .../configuration/or-conf-map/or-conf-map-geojson.ts | 4 ++-- .../manager/src/components/configuration/or-conf-panel.ts | 2 +- ui/app/manager/src/pages/page-gateway-tunnel.ts | 2 +- ui/app/manager/src/pages/page-gateway.ts | 2 +- ui/app/manager/src/pages/page-realms.ts | 4 ++-- ui/app/manager/src/pages/page-users.ts | 2 +- .../or-rules/src/json-viewer/or-rule-trigger-query.ts | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-json.ts b/ui/app/manager/src/components/configuration/or-conf-json.ts index a91c932062..07a0c8e4db 100644 --- a/ui/app/manager/src/components/configuration/or-conf-json.ts +++ b/ui/app/manager/src/components/configuration/or-conf-json.ts @@ -61,11 +61,11 @@ export class OrConfJson extends OrElement { }; const onCancel = () => { - dialog.close(); + dialog?.close(); }; const onOk = () => { if (_saveConfig()) { - dialog.close(); + dialog?.close(); } }; @@ -90,7 +90,7 @@ export class OrConfJson extends OrElement { - +
diff --git a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts index 869376844e..cb867eb00c 100644 --- a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts +++ b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts @@ -78,10 +78,10 @@ export class OrConfMapGeoJson extends OrElement { >
this._dialog?.close()}> - + - +
diff --git a/ui/app/manager/src/components/configuration/or-conf-panel.ts b/ui/app/manager/src/components/configuration/or-conf-panel.ts index 16f887c22a..238fd6fcc6 100644 --- a/ui/app/manager/src/components/configuration/or-conf-panel.ts +++ b/ui/app/manager/src/components/configuration/or-conf-panel.ts @@ -232,7 +232,7 @@ export class OrConfPanel extends OrElement { .items=${realmItems} @change=${(ev: Event) => { this._addedRealm = (ev.currentTarget as OrVaadinSelect).value; - buttonRef.value.disabled = !selectRef.value?.checkValidity(); + buttonRef.value!.disabled = !selectRef.value?.checkValidity(); }} > diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index 8d15f03c8c..ab2723f83f 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -370,7 +370,7 @@ export class PageGatewayTunnel extends Page { @change=${(ev: Event) => { const value = (ev.currentTarget as HTMLInputElement).value; tunnel.targetPort = value ? Number(value) : undefined; - buttonRef.value.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; + buttonRef.value!.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; checkValidity(); }} > diff --git a/ui/app/manager/src/pages/page-gateway.ts b/ui/app/manager/src/pages/page-gateway.ts index 445ce30e58..635a6e29cd 100644 --- a/ui/app/manager/src/pages/page-gateway.ts +++ b/ui/app/manager/src/pages/page-gateway.ts @@ -802,7 +802,7 @@ export class PageGateway extends Page { - + diff --git a/ui/app/manager/src/pages/page-realms.ts b/ui/app/manager/src/pages/page-realms.ts index 9c0d6ece3a..28983e8615 100644 --- a/ui/app/manager/src/pages/page-realms.ts +++ b/ui/app/manager/src/pages/page-realms.ts @@ -525,7 +525,7 @@ export class PageRealms extends Page { let confirmedName = ""; const okBtnRef: Ref = createRef(); - const doDelete = async (dialog: OrVaadinConfirmDialog) => { + const doDelete = async (dialog?: OrVaadinConfirmDialog) => { if (okBtnRef.value.disabled) return; try { await manager.rest.api.RealmResource.delete(realm.name); @@ -534,7 +534,7 @@ export class PageRealms extends Page { } catch (e) { showSnackbar(undefined, "realmDeleteFailed", "dismiss"); } finally { - dialog.close(); + dialog?.close(); } }; diff --git a/ui/app/manager/src/pages/page-users.ts b/ui/app/manager/src/pages/page-users.ts index 035723b213..afe58e55b8 100644 --- a/ui/app/manager/src/pages/page-users.ts +++ b/ui/app/manager/src/pages/page-users.ts @@ -843,7 +843,7 @@ export class PageUsers extends Page { dialog = showDialog( this.shadowRoot!, html` - +

diff --git a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts index fe7b797a3f..1b00e4250b 100644 --- a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts +++ b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts @@ -237,7 +237,7 @@ export class OrRuleTriggerQuery extends OrElement { ${this.renderDialogHTML(this.condition.sun?.location)}
this._mapDialogElem?.close()}> - +
From 448b3800c7497bf92c08b7fc9a1f5c1b70f15b63 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 1 Oct 2026 13:54:08 +0200 Subject: [PATCH 30/42] Address changes after running an AI review of the PR --- .../src/components/configuration/or-conf-json.ts | 2 +- .../configuration/or-conf-map/or-conf-map-geojson.ts | 2 +- ui/app/manager/src/pages/page-assets.ts | 2 +- ui/app/manager/src/pages/page-gateway-tunnel.ts | 3 ++- ui/app/manager/src/pages/page-gateway.ts | 1 + ui/app/manager/src/pages/page-realms.ts | 4 ++-- ui/component/or-asset-tree/src/index.ts | 12 ++++++------ .../or-asset-viewer/src/or-edit-asset-panel.ts | 2 +- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/ui/app/manager/src/components/configuration/or-conf-json.ts b/ui/app/manager/src/components/configuration/or-conf-json.ts index 07a0c8e4db..e8eebdc28c 100644 --- a/ui/app/manager/src/components/configuration/or-conf-json.ts +++ b/ui/app/manager/src/components/configuration/or-conf-json.ts @@ -81,7 +81,7 @@ export class OrConfJson extends OrElement { @or-ace-editor-changed="${(ev: OrAceEditorChangedEvent) => { if (this._updateButton.value) { this._updateButton.value.disabled = !ev.detail.valid; - dialog.requestUpdate(); + dialog?.requestUpdate(); } }}" > diff --git a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts index cb867eb00c..7528c85a63 100644 --- a/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts +++ b/ui/app/manager/src/components/configuration/or-conf-map/or-conf-map-geojson.ts @@ -70,7 +70,7 @@ export class OrConfMapGeoJson extends OrElement { style="width: 100%; aspect-ratio: 1/1;" @or-ace-editor-changed="${(ev: OrAceEditorChangedEvent) => { this._jsonValid = ev.detail.valid; - buttonRef.value.disabled = !this._jsonValid; + buttonRef.value!.disabled = !this._jsonValid; if (this._jsonValid) { this._aceEditorValue = ev.detail.value; } diff --git a/ui/app/manager/src/pages/page-assets.ts b/ui/app/manager/src/pages/page-assets.ts index 0ad2f269ef..db046bcd12 100644 --- a/ui/app/manager/src/pages/page-assets.ts +++ b/ui/app/manager/src/pages/page-assets.ts @@ -280,7 +280,7 @@ export class PageAssets extends Page { const blockEvent = (ev: Event) => ev.stopPropagation(); const setParent = () => { - const assetTree = assetTreeRef.value; + const assetTree = assetTreeRef.value!; const idd = assetTree.selectedIds!.length === 1 ? assetTree.selectedIds![0] : undefined; this._onAssetParentChange({ parentId: idd, assetIds: this._assetIds }); }; diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index ab2723f83f..7271d6801b 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -320,9 +320,10 @@ export class PageGatewayTunnel extends Page { const onAddClick = () => { this._tryStartTunnel(tunnel); + dialog?.close(); }; const checkValidity = () => { - buttonRef.value.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; + buttonRef.value!.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; }; const gatewayListTemplate = async (): Promise => { diff --git a/ui/app/manager/src/pages/page-gateway.ts b/ui/app/manager/src/pages/page-gateway.ts index 635a6e29cd..90aaca9415 100644 --- a/ui/app/manager/src/pages/page-gateway.ts +++ b/ui/app/manager/src/pages/page-gateway.ts @@ -780,6 +780,7 @@ export class PageGateway extends Page { } } this._updateAttributeFilters(parsed); + dialog?.close(); } catch (e) { console.error(e); showSnackbar(undefined, i18next.t("errorOccurred")); diff --git a/ui/app/manager/src/pages/page-realms.ts b/ui/app/manager/src/pages/page-realms.ts index 28983e8615..96261a9ef3 100644 --- a/ui/app/manager/src/pages/page-realms.ts +++ b/ui/app/manager/src/pages/page-realms.ts @@ -526,7 +526,7 @@ export class PageRealms extends Page { const okBtnRef: Ref = createRef(); const doDelete = async (dialog?: OrVaadinConfirmDialog) => { - if (okBtnRef.value.disabled) return; + if (okBtnRef.value!.disabled) return; try { await manager.rest.api.RealmResource.delete(realm.name); this._realms = this._realms.filter((r) => r !== realm); @@ -555,7 +555,7 @@ export class PageRealms extends Page { `; const dialog = showConfirmDialog( - this.shadowRoot, + this.shadowRoot!, html` doDelete(dialog)}> ${getConfirmDialogContent( diff --git a/ui/component/or-asset-tree/src/index.ts b/ui/component/or-asset-tree/src/index.ts index c5016476d3..ff461a5ae0 100644 --- a/ui/component/or-asset-tree/src/index.ts +++ b/ui/component/or-asset-tree/src/index.ts @@ -1633,16 +1633,16 @@ export class OrAssetTree extends subscribe(manager)(OrElement) { const onAddChanged = (ev: OrAddChangedEvent) => { const nameValid = !!ev.detail.name && ev.detail.name.trim().length > 0 && ev.detail.name.trim().length < 1024; - const addBtn = addBtnRef.value; - addBtn!.disabled = !ev.detail.descriptor || !nameValid; + const addBtn = addBtnRef.value!; + addBtn.disabled = !ev.detail.descriptor || !nameValid; }; const onCancel = () => dialog?.close(); const onOk = () => { - const addAssetDialog = addAssetDialogRef.value; + const addAssetDialog = addAssetDialogRef.value!; const descriptor = addAssetDialog!.selectedType; const selectedOptionalAttributes = addAssetDialog!.selectedAttributes; - const name = addAssetDialog!.name.trim(); - const parent = addAssetDialog!.parent; + const name = addAssetDialog.name.trim(); + const parent = addAssetDialog.parent; if (!descriptor) { return; @@ -1718,7 +1718,7 @@ export class OrAssetTree extends subscribe(manager)(OrElement) { - + diff --git a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts index 688426047e..7bf7df6dd0 100644 --- a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts +++ b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts @@ -681,8 +681,8 @@ export class OrEditAssetPanel extends OrElement { this.requestUpdate(); } }); - dialog?.close(); } + dialog?.close(); }; const dialog = showDialog( From df46f7d69932860b333a43352ac4a9645427649c Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 1 Oct 2026 14:21:51 +0200 Subject: [PATCH 31/42] Minor cleanup --- ui/app/manager/src/pages/page-assets.ts | 1 - ui/app/manager/src/pages/page-gateway-tunnel.ts | 4 +--- ui/component/or-asset-tree/src/index.ts | 5 ++--- .../or-dashboard-builder/src/panels/assettypes-panel.ts | 1 - 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/ui/app/manager/src/pages/page-assets.ts b/ui/app/manager/src/pages/page-assets.ts index db046bcd12..fa922e8223 100644 --- a/ui/app/manager/src/pages/page-assets.ts +++ b/ui/app/manager/src/pages/page-assets.ts @@ -304,7 +304,6 @@ export class PageAssets extends Page { { this.shadowRoot!, html` -

- ${i18next.t("add")} ${i18next.t("tunnel")} -

+

${i18next.t("add")} ${i18next.t("tunnel")}

${until(gatewayListTemplate(), html`${i18next.t("loading")}`)}
dialog?.close()}> diff --git a/ui/component/or-asset-tree/src/index.ts b/ui/component/or-asset-tree/src/index.ts index ff461a5ae0..34aac65c56 100644 --- a/ui/component/or-asset-tree/src/index.ts +++ b/ui/component/or-asset-tree/src/index.ts @@ -1639,8 +1639,8 @@ export class OrAssetTree extends subscribe(manager)(OrElement) { const onCancel = () => dialog?.close(); const onOk = () => { const addAssetDialog = addAssetDialogRef.value!; - const descriptor = addAssetDialog!.selectedType; - const selectedOptionalAttributes = addAssetDialog!.selectedAttributes; + const descriptor = addAssetDialog.selectedType; + const selectedOptionalAttributes = addAssetDialog.selectedAttributes; const name = addAssetDialog.name.trim(); const parent = addAssetDialog.parent; @@ -1706,7 +1706,6 @@ export class OrAssetTree extends subscribe(manager)(OrElement) { Date: Thu, 1 Oct 2026 14:52:29 +0200 Subject: [PATCH 32/42] Revert notification form changes, as a separate PR is created by Ekhorn on this issue. --- .../src/components/notifications/or-notification-form.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/app/manager/src/components/notifications/or-notification-form.ts b/ui/app/manager/src/components/notifications/or-notification-form.ts index 79cfa40e09..89b90c3c54 100644 --- a/ui/app/manager/src/components/notifications/or-notification-form.ts +++ b/ui/app/manager/src/components/notifications/or-notification-form.ts @@ -126,8 +126,6 @@ export class OrNotificationForm extends OrElement { position: absolute; width: 100%; height: 100%; - display: flex; - flex-direction: column; } .messageContentContainer { From a9858276acc6af9becaf60a8c5728c27b4b7d573 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 1 Oct 2026 14:58:36 +0200 Subject: [PATCH 33/42] Remove duplicate and/or unused code --- ui/app/manager/src/pages/page-gateway-tunnel.ts | 1 - ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index 662d884c79..177ac57a41 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -371,7 +371,6 @@ export class PageGatewayTunnel extends Page { @change=${(ev: Event) => { const value = (ev.currentTarget as HTMLInputElement).value; tunnel.targetPort = value ? Number(value) : undefined; - buttonRef.value!.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; checkValidity(); }} > diff --git a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts index 1b00e4250b..e3f091859c 100644 --- a/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts +++ b/ui/component/or-rules/src/json-viewer/or-rule-trigger-query.ts @@ -25,7 +25,7 @@ import { buttonStyle } from "../style"; import { OrRulesJsonRuleChangedEvent } from "./or-rule-json-viewer"; import { TimeTriggerType } from "../index"; import { Util } from "@openremote/core"; -import { type LngLatLike, type OrMap, OrMapClickedEvent } from "@openremote/or-map"; +import { type OrMap, OrMapClickedEvent } from "@openremote/or-map"; import { i18next } from "@openremote/or-translate"; import type { OrVaadinSelect } from "@openremote/or-vaadin-components/or-vaadin-select"; import { when } from "lit/directives/when.js"; From 983732efc666d04f23450446d37e3ead25dddabf Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 1 Oct 2026 15:23:44 +0200 Subject: [PATCH 34/42] Fix realm delete button color, and fixed height for assettypes-panel asset selection in Insights --- ui/app/manager/src/pages/page-realms.ts | 2 +- .../or-dashboard-builder/src/panels/assettypes-panel.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/app/manager/src/pages/page-realms.ts b/ui/app/manager/src/pages/page-realms.ts index 96261a9ef3..a6ee381c82 100644 --- a/ui/app/manager/src/pages/page-realms.ts +++ b/ui/app/manager/src/pages/page-realms.ts @@ -563,7 +563,7 @@ export class PageRealms extends Page { "deleteRealmConfirm", dialogContent, html` - + `, diff --git a/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts b/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts index ca6885a1ab..7dbd371f11 100644 --- a/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts +++ b/ui/component/or-dashboard-builder/src/panels/assettypes-panel.ts @@ -345,6 +345,7 @@ export class AssettypesPanel extends OrElement { .showSortBtn="${false}" .showFilterIcon="${false}" .checkboxes="${multi}" + style="width: 100%; aspect-ratio: 1/1.75;" >
From f55639c947e2551e6faa9124816dff17b534777c Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 15 Oct 2026 16:15:19 +0200 Subject: [PATCH 35/42] Additional commit for resolving merge conflict; put back tunnel validation to what is on main branch --- .../manager/src/pages/page-gateway-tunnel.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index 2557c24b35..0efc232443 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -324,21 +324,10 @@ export class PageGatewayTunnel extends Page { }; const checkValidity = () => { - buttonRef.value!.disabled = !tunnel.gatewayId || !tunnel.target || !tunnel.targetPort; - } - const updateActions = () => { - dialog.setActions([ - { actionName: "cancel", content: "cancel" }, - { - actionName: "add", - disabled: - !tunnel.gatewayId || - (tunnel.hostname && tunnel.hostname.trim().length === 0) || - (tunnel.targetPort !== undefined && (tunnel.targetPort <= 0 || tunnel.targetPort > 65535)), - content: "add", - action: () => onAddClick(), - }, - ]); + buttonRef.value!.disabled = + !tunnel.gatewayId || + (tunnel.hostname && tunnel.hostname.trim().length === 0) || + (tunnel.targetPort !== undefined && (tunnel.targetPort <= 0 || tunnel.targetPort > 65535)); }; const gatewayListTemplate = async (): Promise => { From 50cb0208adb56524ceb48fe45d13f429beecf5c7 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 15 Oct 2026 17:48:57 +0200 Subject: [PATCH 36/42] Minor text adjustment with or-translate on gateway tunnel page after feedback --- ui/app/manager/src/pages/page-gateway-tunnel.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/app/manager/src/pages/page-gateway-tunnel.ts b/ui/app/manager/src/pages/page-gateway-tunnel.ts index 0efc232443..071e609318 100644 --- a/ui/app/manager/src/pages/page-gateway-tunnel.ts +++ b/ui/app/manager/src/pages/page-gateway-tunnel.ts @@ -390,8 +390,11 @@ export class PageGatewayTunnel extends Page { this.shadowRoot!, html` -

${i18next.t("add")} ${i18next.t("tunnel")}

- ${until(gatewayListTemplate(), html`${i18next.t("loading")}`)} +

+ + +

+ ${until(gatewayListTemplate(), html``)}
dialog?.close()}> From 0b6cb72a79f654c4d4e47de912671052f3df73f2 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 15 Oct 2026 17:50:55 +0200 Subject: [PATCH 37/42] Adjust styling to be aligned with the design after feedback --- .../or-asset-tree/src/or-add-asset-dialog.ts | 55 +++++++++++++------ 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/ui/component/or-asset-tree/src/or-add-asset-dialog.ts b/ui/component/or-asset-tree/src/or-add-asset-dialog.ts index 29c2417382..c1baaa3886 100644 --- a/ui/component/or-asset-tree/src/or-add-asset-dialog.ts +++ b/ui/component/or-asset-tree/src/or-add-asset-dialog.ts @@ -113,7 +113,7 @@ export class OrAddAssetDialog extends OrElement { border-color: var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); border-width: 1px 0; } - + #name-wrapper { display: flex; flex-direction: column; @@ -138,12 +138,12 @@ export class OrAddAssetDialog extends OrElement { #parent { flex: 1 1 auto; } - + #parent-selector { max-width: 250px; border-left: 1px solid var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); } - + #mdc-dialog-form-add { display: flex; height: 600px; @@ -162,23 +162,40 @@ export class OrAddAssetDialog extends OrElement { } #asset-type-option-container { - padding: 15px; + padding: 7px; flex: 1 1 auto; overflow: auto; max-width: 100%; font-size: 16px; } + #asset-type-option-content { + padding: 7px 14px; + box-sizing: border-box; + height: 100%; + overflow: auto; + background: white; + border-radius: 7px; + } + #type-list-filter { padding: 7px; - background-color: var(--or-app-color2, ${unsafeCSS(DefaultColor2)})) } - + #filterInput{ width: 100%; } + #type-list-content { + padding: 0 7px; + overflow: hidden; + } + #type-list { + padding: 0 7px; + background: white; + border-radius: 7px; + height: 100%; overflow: auto; text-transform: capitalize; } @@ -186,8 +203,8 @@ export class OrAddAssetDialog extends OrElement { #type-list-container { display: flex; flex-direction: column; - width: 300px; - border-right: 1px solid var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); + width: 320px; + gap: 4px; } #type-title { @@ -291,19 +308,23 @@ export class OrAddAssetDialog extends OrElement {
-
- ${when(agentItems.length > 0, () => getListTemplate(filteredAgentItems, true))} -
- ${when(assetItems.length > 0, () => getListTemplate(filteredAssetItems, false))} +
+
+ ${when(agentItems.length > 0, () => getListTemplate(filteredAgentItems, true))} +
+ ${when(assetItems.length > 0, () => getListTemplate(filteredAssetItems, false))} +
- ${ - !this.selectedType - ? html`
` - : this.getTypeTemplate(this.selectedType, parentStr) - } +
+ ${ + !this.selectedType + ? html`
` + : this.getTypeTemplate(this.selectedType, parentStr) + } +
${ !this.showParentAssetSelector From 5142cc50c48342bf21084e466c6cd9ad59ffda4a Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Thu, 15 Oct 2026 18:03:27 +0200 Subject: [PATCH 38/42] Migrate checkboxes of adding meta items to Vaadin after feedback. Apply spotless. --- .../or-asset-tree/src/or-add-asset-dialog.ts | 260 +++++++++--------- .../src/or-edit-asset-panel.ts | 41 ++- 2 files changed, 150 insertions(+), 151 deletions(-) diff --git a/ui/component/or-asset-tree/src/or-add-asset-dialog.ts b/ui/component/or-asset-tree/src/or-add-asset-dialog.ts index c1baaa3886..8de2324284 100644 --- a/ui/component/or-asset-tree/src/or-add-asset-dialog.ts +++ b/ui/component/or-asset-tree/src/or-add-asset-dialog.ts @@ -108,136 +108,136 @@ export class OrAddAssetDialog extends OrElement { public static get styles() { // language=CSS return css` - :host{ - border-style: solid; - border-color: var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); - border-width: 1px 0; - } - - #name-wrapper { - display: flex; - flex-direction: column; - margin-top: 12px; - } - - #toggle-parent-selector, - #remove-parent { - margin: 4px 0 0 5px; - } - - #name-input, - #parent-wrapper { - margin: 10px 0; - } - - #parent-wrapper { - display: flex; - align-items: end; - } - - #parent { - flex: 1 1 auto; - } - - #parent-selector { - max-width: 250px; - border-left: 1px solid var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); - } - - #mdc-dialog-form-add { - display: flex; - height: 600px; - max-height: 600px; - width: 1000px; - } - - .msg { - display: flex; - justify-content: center; - align-items: center; - text-align: center; - height: 100%; - font-family: "Segoe UI", Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; - font-size: 14px; - } - - #asset-type-option-container { - padding: 7px; - flex: 1 1 auto; - overflow: auto; - max-width: 100%; - font-size: 16px; - } - - #asset-type-option-content { - padding: 7px 14px; - box-sizing: border-box; - height: 100%; - overflow: auto; - background: white; - border-radius: 7px; - } - - #type-list-filter { - padding: 7px; - } - - #filterInput{ - width: 100%; - } - - #type-list-content { - padding: 0 7px; - overflow: hidden; - } - - #type-list { - padding: 0 7px; - background: white; - border-radius: 7px; - height: 100%; - overflow: auto; - text-transform: capitalize; - } - - #type-list-container { - display: flex; - flex-direction: column; - width: 320px; - gap: 4px; - } - - #type-title { - display: flex; - align-items: center; - margin: 9px 4px; - } - - #type-description { - text-transform: capitalize; - color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)}); - margin-left: 10px; - font-size: 18px; - font-weight: bold; - font-family: "Segoe UI", Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; - } - - .heading, - .mdc-list-group__subheader { - text-transform: uppercase; - font-family: "Segoe UI", Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; - font-weight: bolder; - line-height: 1em; - color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)}); - letter-spacing: 0.025em; - font-size: 14px; - margin: 20px 0 10px; - } - - .mdc-list-group__subheader { - margin: 20px 0 0 16px; - } - `; + :host { + border-style: solid; + border-color: var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); + border-width: 1px 0; + } + + #name-wrapper { + display: flex; + flex-direction: column; + margin-top: 12px; + } + + #toggle-parent-selector, + #remove-parent { + margin: 4px 0 0 5px; + } + + #name-input, + #parent-wrapper { + margin: 10px 0; + } + + #parent-wrapper { + display: flex; + align-items: end; + } + + #parent { + flex: 1 1 auto; + } + + #parent-selector { + max-width: 250px; + border-left: 1px solid var(--or-app-color5, ${unsafeCSS(DefaultColor5)}); + } + + #mdc-dialog-form-add { + display: flex; + height: 600px; + max-height: 600px; + width: 1000px; + } + + .msg { + display: flex; + justify-content: center; + align-items: center; + text-align: center; + height: 100%; + font-family: "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 14px; + } + + #asset-type-option-container { + padding: 7px; + flex: 1 1 auto; + overflow: auto; + max-width: 100%; + font-size: 16px; + } + + #asset-type-option-content { + padding: 7px 14px; + box-sizing: border-box; + height: 100%; + overflow: auto; + background: white; + border-radius: 7px; + } + + #type-list-filter { + padding: 7px; + } + + #filterInput { + width: 100%; + } + + #type-list-content { + padding: 0 7px; + overflow: hidden; + } + + #type-list { + padding: 0 7px; + background: white; + border-radius: 7px; + height: 100%; + overflow: auto; + text-transform: capitalize; + } + + #type-list-container { + display: flex; + flex-direction: column; + width: 320px; + gap: 4px; + } + + #type-title { + display: flex; + align-items: center; + margin: 9px 4px; + } + + #type-description { + text-transform: capitalize; + color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)}); + margin-left: 10px; + font-size: 18px; + font-weight: bold; + font-family: "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + } + + .heading, + .mdc-list-group__subheader { + text-transform: uppercase; + font-family: "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-weight: bolder; + line-height: 1em; + color: var(--or-app-color3, ${unsafeCSS(DefaultColor3)}); + letter-spacing: 0.025em; + font-size: 14px; + margin: 20px 0 10px; + } + + .mdc-list-group__subheader { + margin: 20px 0 0 16px; + } + `; } constructor() { diff --git a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts index 7bf7df6dd0..2a9ff38441 100644 --- a/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts +++ b/ui/component/or-asset-viewer/src/or-edit-asset-panel.ts @@ -37,8 +37,8 @@ import { DefaultColor5, DefaultColor3, Util } from "@openremote/core"; import "@openremote/or-mwc-components/or-mwc-input"; import type { OrIcon } from "@openremote/or-icon"; import { showDialog, type OrVaadinDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; +import type { OrVaadinCheckboxGroup } from "@openremote/or-vaadin-components/or-vaadin-checkbox-group"; import type { OrVaadinButton } from "@openremote/or-vaadin-components/or-vaadin-button"; -import { type ListItem, ListType, type OrMwcList } from "@openremote/or-mwc-components/or-mwc-list"; import "./or-add-attribute-panel"; import { getField, getPanel, getPropertyTemplate } from "./index"; import type { OrAddAttributePanelAttributeChangedEvent } from "./or-add-attribute-panel"; @@ -651,30 +651,15 @@ export class OrEditAssetPanel extends OrElement { const meta = attribute.meta || {}; - const metaItemList: (ListItem | null)[] = assetTypeInfo.metaItemDescriptors - .map((metaName) => AssetModelUtil.getMetaItemDescriptor(metaName)!) - .filter((descriptor) => !meta.hasOwnProperty(descriptor.name!)) - .map((descriptor) => { - return { - text: Util.getMetaLabel(undefined, descriptor, this.asset!.type!, true), - value: descriptor.name!, - translate: false, - }; - }) - .sort(Util.sortByString((item) => item.text)); - - const listRef: Ref = createRef(); + const listRef: Ref = createRef(); const onOk = () => { - const list = listRef.value; - const selectedItems = list ? list.selectedItems : undefined; + const selectedItems = listRef.value?.value; if (selectedItems) { if (!attribute.meta) { attribute.meta = {}; } selectedItems.forEach((item) => { - const descriptor = AssetModelUtil.getMetaItemDescriptors().find( - (descriptor) => descriptor.name === item.value - ); + const descriptor = AssetModelUtil.getMetaItemDescriptors().find((descriptor) => descriptor.name === item); if (descriptor) { attribute.meta![descriptor.name!] = descriptor.type === "boolean" ? true : null; this._onModified(); @@ -688,11 +673,25 @@ export class OrEditAssetPanel extends OrElement { const dialog = showDialog( this.shadowRoot!, html` - +

- + + ${assetTypeInfo.metaItemDescriptors + .map((metaName) => AssetModelUtil.getMetaItemDescriptor(metaName)!) + .filter((descriptor) => !meta.hasOwnProperty(descriptor.name!)) + .map((descriptor) => ({ + descriptor, + label: Util.getMetaLabel(undefined, descriptor, this.asset!.type!, true), + })) + .sort(Util.sortByString((item) => item.label)) + .map( + (item) => html` + + ` + )} +
dialog?.close()}> From 4fde9d92e30a524fc2483f7cb870035b1127d531 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Fri, 16 Oct 2026 09:38:26 +0200 Subject: [PATCH 39/42] Migrate or-attribute-input location picker dialog to Vaadin --- ui/component/or-attribute-input/src/index.ts | 3 +- ui/component/or-map/src/index.ts | 93 ++++++++++---------- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/ui/component/or-attribute-input/src/index.ts b/ui/component/or-attribute-input/src/index.ts index e52012a060..089b6234e0 100644 --- a/ui/component/or-attribute-input/src/index.ts +++ b/ui/component/or-attribute-input/src/index.ts @@ -348,10 +348,11 @@ export class OrAttributeInput extends subscribe(manager)(translate(i18next)(OrEl #wrapper or-map { min-height: 250px; + aspect-ratio: 3/1 !important; } #wrapper .long-press-msg { - display: none; + display: none !important; } #wrapper { diff --git a/ui/component/or-map/src/index.ts b/ui/component/or-map/src/index.ts index e359534505..de5ecdc55f 100644 --- a/ui/component/or-map/src/index.ts +++ b/ui/component/or-map/src/index.ts @@ -31,9 +31,8 @@ import type { ValueInputProviderGenerator, ValueInputTemplateFunction, } from "@openremote/or-vaadin-components/value-input-provider"; -import { OrMwcDialog, showDialog } from "@openremote/or-mwc-components/or-mwc-dialog"; +import { type OrVaadinDialog, showDialog } from "@openremote/or-vaadin-components/or-vaadin-dialog"; import { getMarkerIconAndColorFromAssetType } from "./util"; -import { i18next } from "@openremote/or-translate"; import debounce from "lodash.debounce"; import type { AttributeEvent, GeoJsonConfig } from "@openremote/model"; import { @@ -46,6 +45,7 @@ import { AssetMap } from "./asset-map"; import { OrMapCenterControl } from "./controls/center"; import { OrMapGeolocateControl } from "./controls/geolocate"; import { ifDefined } from "lit-html/directives/if-defined.js"; +import { createRef, ref, type Ref } from "lit/directives/ref.js"; import type { AssetWithLocation, ClusterConfig, ControlPosition, MapEventDetail, MapFilter } from "./types"; // Re-exports @@ -179,18 +179,19 @@ export const geoJsonPointInputTemplateProvider: ValueInputProviderGenerator = ( const iconAndColor = getMarkerIconAndColorFromAssetType(assetDescriptor); - let dialog: OrMwcDialog | undefined; + let dialog: OrVaadinDialog | undefined; + const orMap: Ref = createRef(); - _setPos = (lngLat: LngLatLike | null) => { + const setPos = (lngLat: LngLatLike | null) => { if (readonly || disabled) { return; } pos = lngLat ? Util.getLngLat(lngLat) : null; - if (dialog) { + if (orMap.value) { // We're in compact mode modal - const marker = dialog.shadowRoot!.getElementById("geo-json-point-marker") as OrMapMarker; + const marker = orMap.value.firstElementChild as OrMapMarker; marker.lng = pos ? pos.lng : undefined; marker.lat = pos ? pos.lat : undefined; center = pos ? Object.values(pos) : undefined; @@ -200,12 +201,12 @@ export const geoJsonPointInputTemplateProvider: ValueInputProviderGenerator = ( valueChangeHandler(pos as LngLatLike); } }; - const setPos = _setPos; let content = html` - ${i18next.t("longPressSetLoc")} + + + `; if (compact) { @@ -231,45 +234,39 @@ export const geoJsonPointInputTemplateProvider: ValueInputProviderGenerator = ( const onClick = () => { dialog = showDialog( - new OrMwcDialog() - .setContent(mapContent) - .setStyles(html` - - `) - .setActions([ - { - actionName: "none", - content: "none", - action: () => { - setPos(null); - valueChangeHandler(pos as LngLatLike); - }, - }, - { - actionName: "ok", - content: "ok", - action: () => { - valueChangeHandler(pos as LngLatLike); - }, - }, - { - default: true, - actionName: "cancel", - content: "cancel", - }, - ]) + document.body, + html` + +
+ ${mapContent} +
+ dialog?.close()}> + + +
+ { + setPos(null); + valueChangeHandler(pos as LngLatLike); + dialog?.close(); + }} + > + + + { + valueChangeHandler(pos as LngLatLike); + dialog?.close(); + }} + > + + +
+
+
+ ` ); }; From 92ba2c8f02c17e53a8802a379469312343a5aeab Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Fri, 16 Oct 2026 09:48:41 +0200 Subject: [PATCH 40/42] Remove MWC dependency from or-map --- ui/component/or-map/package.json | 1 - ui/component/or-map/tsconfig.json | 1 - 2 files changed, 2 deletions(-) diff --git a/ui/component/or-map/package.json b/ui/component/or-map/package.json index f23c06f3dc..ab932075d0 100644 --- a/ui/component/or-map/package.json +++ b/ui/component/or-map/package.json @@ -33,7 +33,6 @@ "@openremote/model": "workspace:*", "@openremote/or-element": "workspace:*", "@openremote/or-icon": "workspace:*", - "@openremote/or-mwc-components": "workspace:*", "@openremote/or-translate": "workspace:*", "@openremote/or-vaadin-components": "workspace:*", "lit": "^3.3.1", diff --git a/ui/component/or-map/tsconfig.json b/ui/component/or-map/tsconfig.json index b4a1315023..1b39379857 100644 --- a/ui/component/or-map/tsconfig.json +++ b/ui/component/or-map/tsconfig.json @@ -12,7 +12,6 @@ { "path": "../rest" }, { "path": "../model" }, { "path": "../or-translate" }, - { "path": "../or-mwc-components" }, { "path": "../or-icon" }, { "path": "../or-vaadin-components" } ] From 9bae7e68c93b5329cd8dda74f7876210b75d0623 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Fri, 16 Oct 2026 09:53:17 +0200 Subject: [PATCH 41/42] Fix yarn.lock --- yarn.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index e547d00c13..ae7707af77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2233,7 +2233,6 @@ __metadata: "@openremote/model": "workspace:*" "@openremote/or-element": "workspace:*" "@openremote/or-icon": "workspace:*" - "@openremote/or-mwc-components": "workspace:*" "@openremote/or-translate": "workspace:*" "@openremote/or-vaadin-components": "workspace:*" "@openremote/util": "workspace:*" From eb16c0bc2cc0ba67532ae212d7a1fc5b7d57cbd1 Mon Sep 17 00:00:00 2001 From: MartinaeyNL Date: Fri, 16 Oct 2026 11:15:27 +0200 Subject: [PATCH 42/42] Adjust test for adding configuration items after Vaadin migration. --- ui/component/or-asset-viewer/test/fixtures/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/component/or-asset-viewer/test/fixtures/index.ts b/ui/component/or-asset-viewer/test/fixtures/index.ts index 8fc1ec67ba..32ceba5199 100644 --- a/ui/component/or-asset-viewer/test/fixtures/index.ts +++ b/ui/component/or-asset-viewer/test/fixtures/index.ts @@ -74,7 +74,8 @@ export class AssetViewer { await configItemLocator.getByRole("button", { name: "Add configuration items" }).click(); for (const item of items) { await this.page - .locator("li", { has: this.page.getByText(Util.camelCaseToSentenceCase(item), { exact: true }) }) + .getByRole("dialog") + .getByRole("checkbox", { name: Util.camelCaseToSentenceCase(item), exact: true }) .check(); } await this.page.getByRole("dialog").getByRole("button", { name: "Add", exact: true }).click();