This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch 3992-improve-widget-handling-in-dashboard in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 62ddf7171e0a64a7d6e2b65e0766545b696f34cb Author: Dominik Riemer <[email protected]> AuthorDate: Tue Dec 2 15:58:21 2025 +0100 Fix size management of widgets --- .../streampipes/model/dashboard/DashboardItem.java | 37 +++ .../management/DataExplorerResourceManager.java | 3 +- .../datalake/KioskDashboardDataLakeResource.java | 2 +- .../core/migrations/AvailableMigrations.java | 4 +- .../v099/UniqueDashboardIdMigration.java | 73 +++++ ui/package-lock.json | 298 ++++++++++++++++----- .../src/lib/model/dashboard/dashboard.model.ts | 2 +- .../static-free-input.component.ts | 1 - .../kiosk/dashboard-kiosk.component.html | 4 +- .../kiosk/dashboard-kiosk.component.scss | 1 + .../components/kiosk/dashboard-kiosk.component.ts | 2 +- .../chart-view/abstract-chart-view.directive.ts | 34 +-- .../grid-view/dashboard-grid-view.component.html | 24 +- .../grid-view/dashboard-grid-view.component.ts | 21 +- .../slide-view/dashboard-slide-view.component.html | 2 +- .../slide-view/dashboard-slide-view.component.ts | 18 -- .../chart-selection-panel.component.html | 5 - .../panel/dashboard-panel.component.scss | 2 +- .../components/panel/dashboard-panel.component.ts | 26 +- .../data-explorer-chart-container.component.html | 7 +- .../data-explorer-chart-container.component.scss | 4 +- .../data-explorer-chart-container.component.ts | 61 +++-- .../base/base-data-explorer-widget.directive.ts | 49 ++-- .../charts/base/echarts-widget.component.html | 2 +- .../charts/base/echarts-widget.component.ts | 18 +- .../charts/gauge/gauge-renderer.service.ts | 10 +- .../charts/heatmap/heatmap-renderer.service.ts | 5 +- .../charts/status/status-widget.component.html | 19 +- .../charts/status/status-widget.component.scss | 22 +- .../charts/status/status-widget.component.ts | 11 +- .../charts/table/table-widget.component.ts | 2 +- .../traffic-light-widget.component.scss | 2 +- .../models/dataview-dashboard.model.ts | 2 +- .../data-explorer-chart-view.component.ts | 4 +- 34 files changed, 518 insertions(+), 259 deletions(-) diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardItem.java b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardItem.java index 81759642cb..d874e11567 100644 --- a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardItem.java +++ b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardItem.java @@ -25,6 +25,7 @@ public class DashboardItem { private String id; private String name; private String component; + private String dataViewElementId; private List<String> settings; @@ -33,6 +34,9 @@ public class DashboardItem { private Integer x; private Integer y; private Map<String, Object> timeSettings; + private String widgetId; + private Integer w; + private Integer h; public DashboardItem() { @@ -109,4 +113,37 @@ public class DashboardItem { public void setTimeSettings(Map<String, Object> timeSettings) { this.timeSettings = timeSettings; } + + @Deprecated + public String getWidgetId() { + return widgetId; + } + + public void setWidgetId(String widgetId) { + this.widgetId = widgetId; + } + + public Integer getW() { + return w; + } + + public void setW(Integer w) { + this.w = w; + } + + public Integer getH() { + return h; + } + + public void setH(Integer h) { + this.h = h; + } + + public String getDataViewElementId() { + return dataViewElementId; + } + + public void setDataViewElementId(String dataViewElementId) { + this.dataViewElementId = dataViewElementId; + } } diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java index 6a2f8cf867..a55d0fb42e 100644 --- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java +++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java @@ -40,7 +40,8 @@ public class DataExplorerResourceManager extends CrudResourceManager<DashboardMo public CompositeDashboardModel getCompositeDashboard(String dashboardId) { var dashboard = db.getElementById(dashboardId); - var widgets = dashboard.getWidgets().stream().map(w -> widgetStorage.getElementById(w.getId())).toList(); + var widgets = dashboard.getWidgets().stream() + .map(w -> widgetStorage.getElementById(w.getDataViewElementId())).toList(); var dataLakeMeasures = getMeasureNames(widgets).stream().map(dataLakeMeasureStorage::getByMeasureName).toList(); return new CompositeDashboardModel(dashboard, widgets, dataLakeMeasures); diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java index 76f99977fd..885fd80dff 100644 --- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java +++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/KioskDashboardDataLakeResource.java @@ -76,7 +76,7 @@ public class KioskDashboardDataLakeResource extends AbstractAuthGuardedRestResou @PathVariable("widgetId") String widgetId, @RequestBody Map<String, String> queryParams) { var dashboard = dashboardStorage.getElementById(dashboardId); - if (dashboard.getWidgets().stream().noneMatch(w -> w.getId().equals(widgetId))) { + if (dashboard.getWidgets().stream().noneMatch(w -> w.getDataViewElementId().equals(widgetId))) { return badRequest(String.format("Widget with id %s not found in dashboard", widgetId)); } var widget = dataExplorerWidgetStorage.getElementById(widgetId); diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java index deedfd63ca..86cde709b2 100644 --- a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/AvailableMigrations.java @@ -32,6 +32,7 @@ import org.apache.streampipes.service.core.migrations.v0980.ModifyAssetLinkTypes import org.apache.streampipes.service.core.migrations.v0980.ModifyAssetLinksMigration; import org.apache.streampipes.service.core.migrations.v099.AddAssetManagementViewMigration; import org.apache.streampipes.service.core.migrations.v099.CreateAssetPermissionMigration; +import org.apache.streampipes.service.core.migrations.v099.UniqueDashboardIdMigration; import org.apache.streampipes.service.core.migrations.v099.MoveAssetContentMigration; import org.apache.streampipes.service.core.migrations.v099.RemoveObsoletePrivilegesMigration; import org.apache.streampipes.service.core.migrations.v970.AddDataLakePipelineTemplateMigration; @@ -68,7 +69,8 @@ public class AvailableMigrations { new AddAssetManagementViewMigration(), new MoveAssetContentMigration(), new CreateAssetPermissionMigration(), - new RemoveObsoletePrivilegesMigration() + new RemoveObsoletePrivilegesMigration(), + new UniqueDashboardIdMigration() ); } } diff --git a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/UniqueDashboardIdMigration.java b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/UniqueDashboardIdMigration.java new file mode 100644 index 0000000000..4bdd2bfe6b --- /dev/null +++ b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/migrations/v099/UniqueDashboardIdMigration.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.streampipes.service.core.migrations.v099; + +import org.apache.streampipes.model.dashboard.DashboardModel; +import org.apache.streampipes.service.core.migrations.Migration; +import org.apache.streampipes.storage.api.CRUDStorage; +import org.apache.streampipes.storage.management.StorageDispatcher; + +import org.apache.commons.lang3.RandomStringUtils; + +import java.io.IOException; +import java.util.Objects; + +public class UniqueDashboardIdMigration implements Migration { + + private final CRUDStorage<DashboardModel> dashboardStorage; + private static final String Prefix = "sp:dataexplorerwidgetmodel"; + + public UniqueDashboardIdMigration() { + this.dashboardStorage = StorageDispatcher.INSTANCE.getNoSqlStore().getDataExplorerDashboardStorage(); + } + + @Override + public boolean shouldExecute() { + return dashboardStorage + .findAll() + .stream() + .anyMatch(d -> d.getWidgets() + .stream() + .anyMatch(w -> Objects.nonNull(w.getId()) && w.getId().startsWith(Prefix))); + } + + @Override + public void executeMigration() throws IOException { + var allDashboards = dashboardStorage.findAll(); + + allDashboards.forEach(d -> { + d.getWidgets().forEach(w -> { + if (Objects.nonNull(w.getId()) && w.getId().startsWith(Prefix)) { + w.setDataViewElementId(w.getId()); + var uniqueDashboardWidgetId = Objects.nonNull(w.getId()) + ? w.getId() + : RandomStringUtils.randomAlphanumeric(16); + w.setId(uniqueDashboardWidgetId); + w.setWidgetId(null); + } + }); + dashboardStorage.updateElement(d); + }); + } + + @Override + public String getDescription() { + return "Moving dashboard widget IDs to dataViewElementId field and generating new unique IDs for widgets."; + } +} diff --git a/ui/package-lock.json b/ui/package-lock.json index 7799d762c8..1049ed3bb5 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -182,6 +182,24 @@ } } }, + "node_modules/@angular-devkit/architect/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/architect/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -189,6 +207,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -392,6 +411,24 @@ "semver": "bin/semver.js" } }, + "node_modules/@angular-devkit/build-angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -435,6 +472,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -510,6 +548,24 @@ } } }, + "node_modules/@angular-devkit/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-devkit/schematics/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -517,6 +573,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -568,6 +625,24 @@ } } }, + "node_modules/@angular-eslint/builder/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-eslint/builder/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -575,6 +650,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -669,6 +745,24 @@ } } }, + "node_modules/@angular-eslint/schematics/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular-eslint/schematics/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -676,6 +770,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -719,7 +814,6 @@ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.2.13.tgz", "integrity": "sha512-x9LYcSndY9BdwuRxTx0gXvlLrvJyzjnWoaIoVLrAZWZbKfQh2+HK4XkclbzNvn8RMeoBpZZatcC3ZBC1TffjtA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -942,7 +1036,6 @@ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.2.17.tgz", "integrity": "sha512-3jG33S+5+kqymCRwQlcSEWlY5rYwkKxe0onln+NXxT0/kteR02vWvv1+Li4/QqSr5JvsGHEhAFsZaR9QtOzbdA==", "license": "MIT", - "peer": true, "dependencies": { "parse5": "^7.1.2", "tslib": "^2.3.0" @@ -1015,6 +1108,24 @@ } } }, + "node_modules/@angular/cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/cli/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -1022,6 +1133,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -1035,7 +1147,6 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.13.tgz", "integrity": "sha512-k7I4bLH+bgI02VL81MaL0NcZPfVl153KAiARwk+ZlkmQjMnWlmsAHQ6054SWoNEXwP855ATR6YYDVqJh8TZaqw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1052,7 +1163,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.13.tgz", "integrity": "sha512-xAj1peVrQtb65NsULmz8ocH4QZ4ESG5YiiVzJ0tLz8t280xY+QhJiM6C0+jaCVHLXvZp0c7GEzsYjL6x1HmabQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1066,7 +1176,6 @@ "integrity": "sha512-SSuzKMcktvd6VexivDwhP7ctQBD6yyoo5E91I7Frn5nrvYNM+TIyYcXmJ4dgby5/GrPZGfm2sWl3ARr2vbCgtA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.26.9", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -1125,7 +1234,6 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.13.tgz", "integrity": "sha512-HpzDI3TSQzVV2mmQ8KwH0JSLNlYNemNrEo3L3hcqqYwTzqFgAK4y1Q2Xym3yiRSLTenYhW5D4CQqOHUQ26HxwQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1142,7 +1250,6 @@ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.13.tgz", "integrity": "sha512-g46KQFrBJhmknczlGEYvWVsPhk7ZI8WOuWkzWEl81Lf3ojEVA/OF8w4VwKZL7wOMKRxOUhuYq6tNPm8tBjtryw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1178,7 +1285,6 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.13.tgz", "integrity": "sha512-YeuRfGbo8qFepoAUoubk/1079wOown5Qgr9eAhgCXxoXb2rt87xbJF3YCSSim38SP3kK1rJQqP+Sr8n7ef+n5Q==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1299,7 +1405,6 @@ "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -4164,7 +4269,6 @@ "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@inquirer/checkbox": "^4.1.2", "@inquirer/confirm": "^5.1.6", @@ -5099,7 +5203,6 @@ "resolved": "https://registry.npmjs.org/@ngx-loading-bar/core/-/core-6.0.2.tgz", "integrity": "sha512-8r+OQEYXwvU+2ZXK6CY3Guh2yJuG8pQ2XNryHVbPZB2Ub3VmzhGWqjxXAQgxmsi+GxrD4m+nGmGZPeOrNH1ztA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.0" }, @@ -6014,7 +6117,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.34.8", @@ -6172,6 +6276,24 @@ } } }, + "node_modules/@schematics/angular/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@schematics/angular/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -6179,6 +6301,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -6828,7 +6951,6 @@ "integrity": "sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -7154,7 +7276,6 @@ "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", @@ -7262,7 +7383,6 @@ "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -7306,7 +7426,6 @@ "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.1", @@ -7620,7 +7739,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "devOptional": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -7697,7 +7815,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -8355,7 +8472,8 @@ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "devOptional": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/browserslist": { "version": "4.24.4", @@ -8377,7 +8495,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", @@ -8633,6 +8750,7 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "devOptional": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -8702,6 +8820,21 @@ "node": ">= 0.8.0" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, "node_modules/chevrotain-allstar": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", @@ -9065,8 +9198,7 @@ "version": "5.65.18", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.18.tgz", "integrity": "sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", @@ -9753,6 +9885,16 @@ "node": ">= 10.0.0" } }, + "node_modules/cytoscape": { + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", + "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/cytoscape-cose-bilkent": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", @@ -10198,6 +10340,16 @@ "node": ">=12" } }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-shape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", @@ -10374,6 +10526,7 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "devOptional": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -10611,6 +10764,7 @@ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "devOptional": true, "license": "BSD-3-Clause", + "peer": true, "engines": { "node": ">=0.3.1" } @@ -10931,7 +11085,6 @@ "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -11168,7 +11321,6 @@ "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -12516,6 +12668,7 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "devOptional": true, "license": "MIT", + "peer": true, "bin": { "he": "bin/he" } @@ -13589,8 +13742,7 @@ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.6.0.tgz", "integrity": "sha512-niVlkeYVRwKFpmfWg6suo6H9CrNnydfBLEqefM5UjibYS+UoTjZdmvPJSiuyrRLGnFj1eYRhFd/ch+5hSlsFVA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-worker": { "version": "27.5.1", @@ -13629,7 +13781,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -13943,7 +14094,6 @@ "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -14439,8 +14589,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", - "license": "BSD-2-Clause", - "peer": true + "license": "BSD-2-Clause" }, "node_modules/less": { "version": "4.2.2", @@ -14448,7 +14597,6 @@ "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -15344,7 +15492,6 @@ "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -15859,6 +16006,7 @@ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -15875,6 +16023,7 @@ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "devOptional": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 14.18.0" }, @@ -15889,6 +16038,7 @@ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -16078,7 +16228,6 @@ "integrity": "sha512-dFuwFsDJMBSd1YtmLLcX5bNNUCQUlRqgf34aXA+79PmkOP+0eF8GP2949wq3+jMjmFTNm80Oo8IUYiSLwklKCQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rollup/plugin-json": "^6.1.0", "@rollup/wasm-node": "^4.24.0", @@ -17466,7 +17615,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -17798,7 +17946,6 @@ "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz", "integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==", "license": "BSD-3-Clause", - "peer": true, "dependencies": { "eventemitter3": "^5.0.1", "lodash-es": "^4.17.21", @@ -18340,7 +18487,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -18396,7 +18542,6 @@ "integrity": "sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -19721,7 +19866,6 @@ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -19988,8 +20132,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tuf-js": { "version": "3.0.1", @@ -20079,7 +20222,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -20358,6 +20500,7 @@ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -20439,7 +20582,8 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-android-arm64": { "version": "4.41.1", @@ -20453,7 +20597,8 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": { "version": "4.41.1", @@ -20467,7 +20612,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": { "version": "4.41.1", @@ -20481,7 +20627,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.41.1", @@ -20495,7 +20642,8 @@ "optional": true, "os": [ "freebsd" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-freebsd-x64": { "version": "4.41.1", @@ -20509,7 +20657,8 @@ "optional": true, "os": [ "freebsd" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.41.1", @@ -20523,7 +20672,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.41.1", @@ -20537,7 +20687,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.41.1", @@ -20551,7 +20702,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.41.1", @@ -20565,7 +20717,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-loongarch64-gnu": { "version": "4.41.1", @@ -20579,7 +20732,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "version": "4.41.1", @@ -20593,7 +20747,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.41.1", @@ -20607,7 +20762,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.41.1", @@ -20621,7 +20777,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.41.1", @@ -20635,7 +20792,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.41.1", @@ -20649,7 +20807,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.41.1", @@ -20663,7 +20822,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.41.1", @@ -20677,7 +20837,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.41.1", @@ -20691,14 +20852,16 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/vite/node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/vite/node_modules/rollup": { "version": "4.41.1", @@ -20706,6 +20869,7 @@ "integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.7" }, @@ -20853,7 +21017,6 @@ "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -20944,7 +21107,6 @@ "integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -21225,7 +21387,8 @@ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "devOptional": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/wrap-ansi": { "version": "6.2.0", @@ -21312,7 +21475,6 @@ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -21355,6 +21517,7 @@ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -21371,6 +21534,7 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "devOptional": true, "license": "BSD-3-Clause", + "peer": true, "bin": { "flat": "cli.js" } @@ -21381,6 +21545,7 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "devOptional": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -21426,8 +21591,7 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/zrender": { "version": "5.6.1", diff --git a/ui/projects/streampipes/platform-services/src/lib/model/dashboard/dashboard.model.ts b/ui/projects/streampipes/platform-services/src/lib/model/dashboard/dashboard.model.ts index 112976b16b..7ae48ef399 100644 --- a/ui/projects/streampipes/platform-services/src/lib/model/dashboard/dashboard.model.ts +++ b/ui/projects/streampipes/platform-services/src/lib/model/dashboard/dashboard.model.ts @@ -24,7 +24,7 @@ import { } from '../gen/streampipes-model'; export interface ClientDashboardItem { - widgetId: string; + dataViewElementId: string; widgetType: string; timeSettings?: TimeSettings; id: string; diff --git a/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts b/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts index f5a963b626..1ca578e426 100644 --- a/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts +++ b/ui/src/app/core-ui/static-properties/static-free-input/static-free-input.component.ts @@ -72,7 +72,6 @@ export class StaticFreeInputComponent this.addValidator(this.staticProperty.value, this.collectValidators()); this.enableValidators(); this.emitUpdate(); - console.log(this.staticProperty); } collectValidators() { diff --git a/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.html b/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.html index c6550df07e..401e6e2b15 100644 --- a/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.html +++ b/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.html @@ -18,7 +18,7 @@ <div fxLayout="column" - style="height: 100vh" + style="height: 100%" class="light-mode w-100 standalone-outer" > <mat-toolbar class="standalone-toolbar"> @@ -55,7 +55,7 @@ </div> </div> </mat-toolbar> - <div fxLayout="column" style="height: calc(100vh - 40px)"> + <div fxLayout="column" style="height: calc(100% - 40px)"> @if (dashboard) { @if (dashboard?.widgets.length > 0) { <sp-dashboard-grid-view diff --git a/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.scss b/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.scss index 0937b31c4c..76ab40d896 100644 --- a/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.scss +++ b/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.scss @@ -22,6 +22,7 @@ .standalone-outer { background: var(--color-bg-1); + min-height: 100vh; } .dashboard-grid { diff --git a/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.ts b/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.ts index 1e7009994e..b4ccb7154a 100644 --- a/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.ts +++ b/ui/src/app/dashboard-kiosk/components/kiosk/dashboard-kiosk.component.ts @@ -63,7 +63,7 @@ export class DashboardKioskComponent implements OnInit, OnDestroy { if (res.ok) { const cd = res.body; cd.dashboard.widgets.forEach(w => { - w.widgetId ??= + w.id ??= this.dataExplorerDashboardService.makeUniqueWidgetId(); }); const eTag = res.headers.get('ETag'); diff --git a/ui/src/app/dashboard-shared/components/chart-view/abstract-chart-view.directive.ts b/ui/src/app/dashboard-shared/components/chart-view/abstract-chart-view.directive.ts index 4409e749b4..0b18b81cc3 100644 --- a/ui/src/app/dashboard-shared/components/chart-view/abstract-chart-view.directive.ts +++ b/ui/src/app/dashboard-shared/components/chart-view/abstract-chart-view.directive.ts @@ -19,18 +19,17 @@ import { Directive, EventEmitter, inject, Input, Output } from '@angular/core'; import { ChartService, + ClientDashboardItem, Dashboard, DataExplorerWidgetModel, DataLakeMeasure, TimeSettings, } from '@streampipes/platform-services'; -import { ResizeService } from '../../../data-explorer-shared/services/resize.service'; import { DataExplorerChartRegistry } from '../../../data-explorer-shared/registry/data-explorer-chart-registry'; import { ObservableGenerator } from '../../../data-explorer-shared/models/dataview-dashboard.model'; @Directive() export abstract class AbstractChartViewDirective { - protected resizeService = inject(ResizeService); protected dataViewDataExplorerService = inject(ChartService); protected widgetRegistryService = inject(DataExplorerChartRegistry); @@ -43,9 +42,6 @@ export abstract class AbstractChartViewDirective { @Input() editMode: boolean; - @Input() - currentlyConfiguredWidgetId: string; - @Input() observableGenerator: ObservableGenerator; @@ -73,7 +69,6 @@ export abstract class AbstractChartViewDirective { startEditMode(value: DataExplorerWidgetModel) { this.startEditModeEmitter.emit(value); - this.currentlyConfiguredWidgetId = value.elementId; } loadWidgetConfigs() { @@ -81,7 +76,7 @@ export abstract class AbstractChartViewDirective { widgetConfig.w ??= widgetConfig.cols; widgetConfig.h ??= widgetConfig.rows; const availableWidget = this.widgets.find( - w => w.elementId === widgetConfig.id, + w => w.elementId === widgetConfig.dataViewElementId, ); this.processWidget(availableWidget); }); @@ -89,23 +84,16 @@ export abstract class AbstractChartViewDirective { this.widgetsAvailable = true; } - loadWidgetConfig(widgetId: string, setCurrentlyConfigured?: boolean) { + loadWidgetConfig(dashboardItem: ClientDashboardItem) { if (!this.isGridView()) { this.widgetsAvailable = false; } this.dataViewDataExplorerService - .getChart(widgetId) + .getChart(dashboardItem.dataViewElementId) .subscribe(response => { this.processWidget(response); - if (setCurrentlyConfigured) { - this.propagateWidgetSelection( - this.configuredWidgets.get(widgetId), - ); - if (!this.isGridView()) { - this.selectNewWidget(widgetId); - } - } if (!this.isGridView()) { + this.selectNewWidget(dashboardItem.id); this.widgetsVisible = true; } this.widgetsAvailable = true; @@ -125,18 +113,6 @@ export abstract class AbstractChartViewDirective { } } - propagateItemRemoval(widgetIndex: number) { - this.deleteCallback.emit(widgetIndex); - } - - propagateWidgetSelection(configuredWidget: DataExplorerWidgetModel) { - if (configuredWidget) { - this.currentlyConfiguredWidgetId = configuredWidget.elementId; - } else { - this.currentlyConfiguredWidgetId = undefined; - } - } - abstract onWidgetsAvailable(): void; abstract isGridView(): boolean; diff --git a/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.html b/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.html index 0f38edfc20..5929888514 100644 --- a/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.html +++ b/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.html @@ -22,20 +22,32 @@ <h3>{{ dashboard.description }}</h3> </div> } -<gridstack [options]="gridOptions" class="dashboard-outer" #grid> - @for (item of dashboard.widgets; let i = $index; track item.widgetId) { +<gridstack + [options]="gridOptions" + (changeCB)="onGridChange($event)" + class="dashboard-outer" + #grid +> + @for (item of dashboard.widgets; let i = $index; track item.id) { <gridstack-item [options]="item"> - @if (widgetsAvailable && configuredWidgets.has(item.id)) { + @if ( + widgetsAvailable && + configuredWidgets.has(item.dataViewElementId) + ) { <sp-data-explorer-chart-container [timeSettings]="timeSettings" [globalTimeEnabled]=" dashboard.dashboardGeneralSettings.globalTimeEnabled " - (deleteCallback)="propagateItemRemoval($event)" + (deleteCallback)="deleteCallback.emit($event)" (startEditModeEmitter)="startEditMode($event)" [dashboardItem]="item" - [configuredWidget]="configuredWidgets.get(item.id)" - [dataLakeMeasure]="dataLakeMeasures.get(item.id)" + [configuredWidget]=" + configuredWidgets.get(item.dataViewElementId) + " + [dataLakeMeasure]=" + dataLakeMeasures.get(item.dataViewElementId) + " [observableGenerator]="observableGenerator" [editMode]="editMode" [kioskMode]="kioskMode" diff --git a/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.ts b/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.ts index ddc0b947cb..cf0d893425 100644 --- a/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.ts +++ b/ui/src/app/dashboard-shared/components/chart-view/grid-view/dashboard-grid-view.component.ts @@ -27,7 +27,7 @@ import { } from '@angular/core'; import { AbstractChartViewDirective } from '../abstract-chart-view.directive'; import { GridStack, GridStackOptions } from 'gridstack'; -import { GridstackComponent } from 'gridstack/dist/angular'; +import { GridstackComponent, nodesCB } from 'gridstack/dist/angular'; @Component({ selector: 'sp-dashboard-grid-view', @@ -61,10 +61,13 @@ export class DashboardGridViewComponent minRow: 5, column: this.dashboard.gridColumns, margin: 2, - cellHeight: 'auto', + cellHeight: 'initial', disableResize: !this.editMode, disableDrag: !this.editMode, float: true, + resizable: { + handles: 'w,e,se', + }, }; } @@ -76,6 +79,20 @@ export class DashboardGridViewComponent } } + onGridChange(data: nodesCB): void { + data.nodes.forEach(changed => { + const widget = this.dashboard.widgets.find( + w => w.id === (changed as any).id, + ); + if (widget) { + widget.x = changed.x; + widget.y = changed.y; + widget.w = changed.w; + widget.h = changed.h; + } + }); + } + onWidgetsAvailable(): void {} isGridView(): boolean { diff --git a/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.html b/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.html index 5fa0ade591..2d35c6a182 100644 --- a/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.html +++ b/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.html @@ -59,7 +59,7 @@ [globalTimeEnabled]=" dashboard.dashboardGeneralSettings.globalTimeEnabled " - (deleteCallback)="propagateItemRemoval($event)" + (deleteCallback)="deleteCallback.emit($event)" (startEditModeEmitter)="startEditMode($event)" [dashboardItem]="currentDashboardItem" [configuredWidget]="currentWidget" diff --git a/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.ts b/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.ts index d6fa8ffcda..835fb2762d 100644 --- a/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.ts +++ b/ui/src/app/dashboard-shared/components/chart-view/slide-view/dashboard-slide-view.component.ts @@ -54,28 +54,10 @@ export class DashboardSlideViewComponent this.currentWidget = this.configuredWidgets.get(widgetId); this.currentMeasure = this.dataLakeMeasures.get(widgetId); this.currentDashboardItem = this.dashboard.widgets[index]; - this.currentlyConfiguredWidgetId = widgetId; this.displayWidget = true; }); } - // ngAfterViewInit(): void { - // const obs = new ResizeObserver(entries => { - // entries.forEach(entry => { - // const cr = entry.contentRect; - // this.gridsterItemComponent.width = cr.width; - // this.gridsterItemComponent.height = cr.height; - // console.log(entry); - // this.resizeService.notify({ - // gridsterItem: - // this.dashboard.widgets[this.selectedWidgetIndex], - // gridsterItemComponent: this.gridsterItemComponent, - // }); - // }); - // }); - // obs.observe(document.getElementById('slideViewOuter')); - // } - onWidgetsAvailable(): void { this.selectWidget(0, this.dashboard.widgets[0].id); } diff --git a/ui/src/app/dashboard/components/panel/chart-selection-panel/chart-selection-panel.component.html b/ui/src/app/dashboard/components/panel/chart-selection-panel/chart-selection-panel.component.html index 1c4f323cb4..37166e0a2e 100644 --- a/ui/src/app/dashboard/components/panel/chart-selection-panel/chart-selection-panel.component.html +++ b/ui/src/app/dashboard/components/panel/chart-selection-panel/chart-selection-panel.component.html @@ -17,11 +17,6 @@ --> <div fxFlex="100" class="designer-panel-content" fxLayout="column"> - <div fxLayout="row" class="sp-tab-bg designer-panel-header"> - <div fxLayoutAlign="start center" class="designer-panel-title"> - <span> {{ 'Configure dashboard' | translate }} </span> - </div> - </div> <div fxFlex="100" fxLayout="column" class="no-overflow"> <mat-tab-group color="accent" diff --git a/ui/src/app/dashboard/components/panel/dashboard-panel.component.scss b/ui/src/app/dashboard/components/panel/dashboard-panel.component.scss index ad4770c30a..6b94dd13a0 100644 --- a/ui/src/app/dashboard/components/panel/dashboard-panel.component.scss +++ b/ui/src/app/dashboard/components/panel/dashboard-panel.component.scss @@ -40,7 +40,7 @@ } .designer-panel { - width: 450px; + width: 350px; } .edit-menu-btn { diff --git a/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts b/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts index 6520f4f1f0..50e88b20c2 100644 --- a/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts +++ b/ui/src/app/dashboard/components/panel/dashboard-panel.component.ts @@ -85,8 +85,8 @@ export class DashboardPanelComponent public items: Dashboard[]; dataLakeMeasure: DataLakeMeasure; - authSubscription: Subscription; - refreshSubscription: Subscription; + auth$: Subscription; + refresh$: Subscription; private detectChangesService = inject(ChartDetectChangesService); private dialog = inject(MatDialog); @@ -113,7 +113,7 @@ export class DashboardPanelComponent this.getDashboard(params.id, startTime, endTime); - this.authSubscription = this.currentUserService.user$.subscribe(_ => { + this.auth$ = this.currentUserService.user$.subscribe(_ => { this.hasDashboardWritePrivileges = this.authService.hasRole( UserPrivilege.PRIVILEGE_WRITE_DASHBOARD, ); @@ -124,28 +124,28 @@ export class DashboardPanelComponent } ngOnDestroy() { - this.authSubscription?.unsubscribe(); - this.refreshSubscription?.unsubscribe(); + this.auth$?.unsubscribe(); + this.refresh$?.unsubscribe(); } addChartToDashboard(dataViewElementId: string) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const dashboardItem = {} as ClientDashboardItem; - dashboardItem.id = dataViewElementId; + dashboardItem.id = + this.dataExplorerDashboardService.makeUniqueWidgetId(); dashboardItem.cols = 3; dashboardItem.rows = 4; dashboardItem.w = 3; dashboardItem.h = 4; dashboardItem.x = 0; dashboardItem.y = 0; - dashboardItem.widgetId = - this.dataExplorerDashboardService.makeUniqueWidgetId(); + dashboardItem.dataViewElementId = dataViewElementId; this.dashboard.widgets.push(dashboardItem); setTimeout(() => { if (this.viewMode === 'grid') { - this.dashboardGrid.loadWidgetConfig(dataViewElementId, true); + this.dashboardGrid.loadWidgetConfig(dashboardItem); } else { - this.dashboardSlide.loadWidgetConfig(dataViewElementId, true); + this.dashboardSlide.loadWidgetConfig(dashboardItem); } }); } @@ -233,7 +233,7 @@ export class DashboardPanelComponent if (resp.ok) { const compositeDashboard = resp.body; compositeDashboard.dashboard.widgets.forEach(w => { - w.widgetId ??= + w.id ??= this.dataExplorerDashboardService.makeUniqueWidgetId(); }); this.dashboard = compositeDashboard.dashboard; @@ -331,14 +331,14 @@ export class DashboardPanelComponent modifyRefreshInterval(liveSettings: DashboardLiveSettings): void { this.dashboard.dashboardLiveSettings = liveSettings; - this.refreshSubscription?.unsubscribe(); + this.refresh$?.unsubscribe(); if (this.dashboard.dashboardLiveSettings.refreshModeActive) { this.createQuerySubscription(); } } createQuerySubscription() { - this.refreshSubscription = timer( + this.refresh$ = timer( 0, this.dashboard.dashboardLiveSettings.refreshIntervalInSeconds * 1000, diff --git a/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.html b/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.html index 175a31dbd1..bddbd7de47 100644 --- a/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.html +++ b/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.html @@ -21,7 +21,7 @@ [ngStyle]="{ background: configuredWidget.baseAppearanceConfig.backgroundColor, color: configuredWidget.baseAppearanceConfig.textColor, - height: 'calc(100% - 4px)' + height: '100%' }" [attr.data-cy]=" 'widget-' + configuredWidget.baseAppearanceConfig.widgetTitle @@ -166,10 +166,7 @@ </div> </div> } - <div - fxLayout="column" - class="widget-content p-0 gridster-item-content ml-0 mr-0 h-100 mw-100" - > + <div fxLayout="column" class="widget-content p-0 ml-0 mr-0 h-100 mw-100"> <ng-template spWidgetHost class="h-100 p-0"></ng-template> @if (errorMessage) { <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center"> diff --git a/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.scss b/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.scss index f6bf324699..edbf29c51d 100644 --- a/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.scss +++ b/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.scss @@ -39,8 +39,7 @@ .box { display: flex; flex-flow: column; - height: 100%; - border: 1px solid var(--color-bg-2); + max-height: 100%; } .box .row.content { @@ -85,4 +84,5 @@ max-width: 100%; width: 100%; overflow-x: hidden; + overflow-y: hidden; } diff --git a/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.ts b/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.ts index f7ab3ae907..1009b2037a 100644 --- a/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.ts +++ b/ui/src/app/data-explorer-shared/components/chart-container/data-explorer-chart-container.component.ts @@ -139,9 +139,9 @@ export class DataExplorerChartContainerComponent hasDataExplorerWritePrivileges = false; hasDashboardWritePrivileges = false; - authSubscription: Subscription; - widgetTypeChangedSubscription: Subscription; - intervalSubscription: Subscription; + auth$: Subscription; + widgetTypeChanged$: Subscription; + interval$: Subscription; errorMessage: SpLogMessage; @@ -177,9 +177,9 @@ export class DataExplorerChartContainerComponent this.resizeService.notify({ width, height, - widgetId: this.dashboardItem?.widgetId || undefined, + widgetId: this.dashboardItem?.id || undefined, }); - }, 150); + }, 100); }); obs.observe(container); } @@ -195,19 +195,17 @@ export class DataExplorerChartContainerComponent this.quickSelections ??= this.timeSelectionService.defaultQuickTimeSelections; this.labels ??= this.timeSelectionService.defaultLabels; - this.authSubscription = this.currentUserService.user$.subscribe( - user => { - this.hasDataExplorerWritePrivileges = this.authService.hasRole( - UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW, - ); - this.hasDashboardWritePrivileges = this.authService.hasRole( - UserPrivilege.PRIVILEGE_WRITE_DASHBOARD, - ); - }, - ); + this.auth$ = this.currentUserService.user$.subscribe(user => { + this.hasDataExplorerWritePrivileges = this.authService.hasRole( + UserPrivilege.PRIVILEGE_WRITE_DATA_EXPLORER_VIEW, + ); + this.hasDashboardWritePrivileges = this.authService.hasRole( + UserPrivilege.PRIVILEGE_WRITE_DASHBOARD, + ); + }); this.widgetLoaded = true; this.title = this.dataLakeMeasure.measureName; - this.widgetTypeChangedSubscription = + this.widgetTypeChanged$ = this.widgetTypeService.chartTypeChangeSubject.subscribe( typeChange => { if ( @@ -256,8 +254,9 @@ export class DataExplorerChartContainerComponent ngOnDestroy() { this.resizeObserver?.disconnect(); this.componentRef?.destroy(); - this.authSubscription?.unsubscribe(); - this.widgetTypeChangedSubscription?.unsubscribe(); + this.auth$?.unsubscribe(); + this.widgetTypeChanged$?.unsubscribe(); + this.interval$?.unsubscribe(); } chooseWidget(widgetTypeId: string) { @@ -269,6 +268,13 @@ export class DataExplorerChartContainerComponent } loadComponent(widgetToDisplay) { + const container = this.el.nativeElement.querySelector( + '.widget-content', + ) as HTMLDivElement; + const initialSize = { + width: container.clientWidth, + height: container.clientHeight, + }; const componentFactory = this.componentFactoryResolver.resolveComponentFactory< BaseWidgetData<any> @@ -282,6 +288,7 @@ export class DataExplorerChartContainerComponent componentFactory, ); this.componentRef.instance.dataExplorerWidget = this.configuredWidget; + this.componentRef.instance.initialSize = initialSize; this.componentRef.instance.timeSettings = this.getTimeSettings(); this.timeSelectionService.updateTimeSettings( this.quickSelections, @@ -298,22 +305,22 @@ export class DataExplorerChartContainerComponent this.componentRef.instance.widgetIndex = this.widgetIndex; this.componentRef.instance.observableGenerator = this.observableGenerator; - const removeSub = + const remove$ = this.componentRef.instance.removeWidgetCallback.subscribe(ev => this.removeWidget(), ); - const timerSub = this.componentRef.instance.timerCallback.subscribe( - ev => this.handleTimer(ev), + const timer$ = this.componentRef.instance.timerCallback.subscribe(ev => + this.handleTimer(ev), ); - const errorSub = this.componentRef.instance.errorCallback.subscribe( + const error$ = this.componentRef.instance.errorCallback.subscribe( ev => (this.errorMessage = ev), ); this.componentRef.onDestroy(destroy => { this.componentRef.instance.cleanupSubscriptions(); - removeSub?.unsubscribe(); - timerSub?.unsubscribe(); - errorSub?.unsubscribe(); + remove$?.unsubscribe(); + timer$?.unsubscribe(); + error$?.unsubscribe(); }); } @@ -340,7 +347,7 @@ export class DataExplorerChartContainerComponent startLoadingTimer() { this.timerActive = true; - this.intervalSubscription = interval(100) + this.interval$ = interval(100) .pipe(takeWhile(() => this.timerActive)) .subscribe(value => { this.loadingTime = (value * 100) / 1000; @@ -349,7 +356,7 @@ export class DataExplorerChartContainerComponent stopLoadingTimer() { this.timerActive = false; - this.intervalSubscription.unsubscribe(); + this.interval$.unsubscribe(); } handleTimer(start: boolean) { diff --git a/ui/src/app/data-explorer-shared/components/charts/base/base-data-explorer-widget.directive.ts b/ui/src/app/data-explorer-shared/components/charts/base/base-data-explorer-widget.directive.ts index 5cc4905a67..0025e2c6c7 100644 --- a/ui/src/app/data-explorer-shared/components/charts/base/base-data-explorer-widget.directive.ts +++ b/ui/src/app/data-explorer-shared/components/charts/base/base-data-explorer-widget.directive.ts @@ -31,7 +31,6 @@ import { DataExplorerDataConfig, DataExplorerField, DataExplorerWidgetModel, - DataViewQueryGeneratorService, SpLogMessage, SpQueryResult, TimeSettings, @@ -48,6 +47,7 @@ import { catchError, switchMap } from 'rxjs/operators'; import { DataExplorerChartRegistry } from '../../../registry/data-explorer-chart-registry'; import { SpFieldUpdateService } from '../../../services/field-update.service'; import { TimeSelectionService } from '@streampipes/shared-ui'; +import { WidgetSize } from '../../../models/dataset.model'; @Directive() export abstract class BaseDataExplorerWidgetDirective< @@ -88,6 +88,12 @@ export abstract class BaseDataExplorerWidgetDirective< @HostBinding('class') className = 'h-100'; + @Input() + initialSize: WidgetSize; + + currentWidth: number; + currentHeight: number; + public selectedProperties: string[]; public showNoDataInDateRange: boolean; @@ -99,9 +105,9 @@ export abstract class BaseDataExplorerWidgetDirective< fieldProvider: FieldProvider; - widgetConfigurationSub: Subscription; - resizeSub: Subscription; - timeSelectionSub: Subscription; + widgetConfiguration$: Subscription; + resize$: Subscription; + timeSelection$: Subscription; widthOffset: number; heightOffset: number; @@ -112,9 +118,6 @@ export abstract class BaseDataExplorerWidgetDirective< protected widgetConfigurationService = inject(ChartConfigurationService); protected resizeService = inject(ResizeService); - protected dataViewQueryGeneratorService = inject( - DataViewQueryGeneratorService, - ); protected timeSelectionService = inject(TimeSelectionService); protected widgetRegistryService = inject(DataExplorerChartRegistry); protected fieldUpdateService = inject(SpFieldUpdateService); @@ -123,6 +126,8 @@ export abstract class BaseDataExplorerWidgetDirective< ngOnInit(): void { this.heightOffset = this.gridMode ? 70 : 65; this.widthOffset = this.gridMode ? 10 : 10; + this.currentWidth = this.initialSize.width; + this.currentHeight = this.initialSize.height; this.showData = true; const sourceConfigs = this.dataExplorerWidget.dataConfig.sourceConfigs; this.fieldProvider = @@ -151,7 +156,7 @@ export abstract class BaseDataExplorerWidgetDirective< }); }); - this.widgetConfigurationSub = + this.widgetConfiguration$ = this.widgetConfigurationService.configurationChangedSubject.subscribe( refreshMessage => { if (refreshMessage.refreshData) { @@ -177,18 +182,18 @@ export abstract class BaseDataExplorerWidgetDirective< }, ); if (!this.previewMode) { - this.resizeSub = this.resizeService.resizeSubject.subscribe( - info => { - if ( - this.dataViewMode || - info.widgetId === this.dataViewDashboardItem.widgetId - ) { - this.onResize(info.width, info.height); - } - }, - ); + this.resize$ = this.resizeService.resizeSubject.subscribe(info => { + if ( + this.dataViewMode || + info.widgetId === this.dataViewDashboardItem.id + ) { + this.currentWidth = info.width; + this.currentHeight = info.height; + this.onResize(info.width, info.height); + } + }); } - this.timeSelectionSub = + this.timeSelection$ = this.timeSelectionService.timeSelectionChangeSubject.subscribe( widgetTimeSettings => { if ( @@ -213,9 +218,9 @@ export abstract class BaseDataExplorerWidgetDirective< } public cleanupSubscriptions(): void { - this.widgetConfigurationSub?.unsubscribe(); - this.resizeSub?.unsubscribe(); - this.timeSelectionSub?.unsubscribe(); + this.widgetConfiguration$?.unsubscribe(); + this.resize$?.unsubscribe(); + this.timeSelection$.unsubscribe(); this.requestQueue$?.unsubscribe(); } diff --git a/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.html b/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.html index f7d787b876..02753931c0 100644 --- a/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.html +++ b/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.html @@ -51,7 +51,7 @@ [attr.data-cy]="dataExplorerWidget.widgetType" echarts [options]="option" - [ngStyle]="{ width: currentWidth, height: '100%' }" + [ngStyle]="{ width: currentWidth, height: 'calc(100% - 1px)' }" (chartInit)="onChartInit($event)" ></div> } diff --git a/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts b/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts index 375499beda..2e090060ca 100644 --- a/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts +++ b/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts @@ -41,9 +41,6 @@ export class SpEchartsWidgetComponent<T extends DataExplorerWidgetModel> implements OnInit { eChartsInstance: ECharts; - currentWidth: number; - currentHeight: number; - option: EChartsOption; configReady = false; @@ -64,7 +61,6 @@ export class SpEchartsWidgetComponent<T extends DataExplorerWidgetModel> this.resizeEcharts$ = this.resizeEchartsService.echartsResizeSubject.subscribe(width => { this.currentWidth = width - this.widthOffset; - this.applySize(this.currentWidth, this.currentHeight); this.refreshView(); }); this.renderSubject$ = this.renderSubject @@ -80,30 +76,20 @@ export class SpEchartsWidgetComponent<T extends DataExplorerWidgetModel> beforeDataFetched() {} onDataReceived(spQueryResult: SpQueryResult[]) { - this.renderChartOptions(spQueryResult); this.latestData = spQueryResult; + this.renderChartOptions(spQueryResult); this.setShownComponents(false, true, false, false); } onResize(width: number, height: number) { - this.currentWidth = width; - this.currentHeight = height; this.configReady = true; - this.applySize(width, height); if (this.latestData) { - this.renderSubject.next(); + this.refreshView(); } } onChartInit(ec: ECharts) { this.eChartsInstance = ec; - this.applySize(this.currentWidth, this.currentHeight); - } - - applySize(width: number, height: number) { - if (this.eChartsInstance) { - this.eChartsInstance.resize({ width, height }); - } } renderChartOptions(spQueryResult: SpQueryResult[]): void { diff --git a/ui/src/app/data-explorer-shared/components/charts/gauge/gauge-renderer.service.ts b/ui/src/app/data-explorer-shared/components/charts/gauge/gauge-renderer.service.ts index 376bbf2cbf..7be7324f64 100644 --- a/ui/src/app/data-explorer-shared/components/charts/gauge/gauge-renderer.service.ts +++ b/ui/src/app/data-explorer-shared/components/charts/gauge/gauge-renderer.service.ts @@ -46,18 +46,25 @@ export class SpGaugeRendererService fieldName: string, value: number, widgetConfig: GaugeWidgetModel, + widgetSize: WidgetSize, ): GaugeSeriesOption { const visConfig = widgetConfig.visualizationConfig; + const clamp = Math.min(Math.max(widgetSize.width / 400, 0.7), 1.4); return { name: seriesName, type: 'gauge', progress: { show: true, }, + axisLabel: { + fontSize: 10 * clamp, + }, detail: { show: true, valueAnimation: false, formatter: '{value}', + fontSize: 14 * clamp, + offsetCenter: [0, '70%'], }, min: visConfig.min, max: visConfig.max, @@ -87,7 +94,7 @@ export class SpGaugeRendererService render( queryResult: SpQueryResult[], widgetConfig: GaugeWidgetModel, - _widgetSize: WidgetSize, + widgetSize: WidgetSize, ): EChartsOption { const option = this.echartsBaseOptionsGenerator.makeBaseConfig( widgetConfig.baseAppearanceConfig as WidgetEchartsAppearanceConfig, @@ -110,6 +117,7 @@ export class SpGaugeRendererService selectedField.fullDbName, data, widgetConfig, + widgetSize, ), }); diff --git a/ui/src/app/data-explorer-shared/components/charts/heatmap/heatmap-renderer.service.ts b/ui/src/app/data-explorer-shared/components/charts/heatmap/heatmap-renderer.service.ts index 08c87275b0..90abf4ee55 100644 --- a/ui/src/app/data-explorer-shared/components/charts/heatmap/heatmap-renderer.service.ts +++ b/ui/src/app/data-explorer-shared/components/charts/heatmap/heatmap-renderer.service.ts @@ -109,10 +109,7 @@ export class SpHeatmapRendererService extends SpBaseEchartsRenderer<HeatmapWidge options: EChartsOption, widgetConfig: HeatmapWidgetModel, ): void { - options.grid = { - height: '80%', - top: '80', - }; + options.grid = {}; options.xAxis = { type: 'category', splitArea: { diff --git a/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.html b/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.html index 24929b45c0..239fe7aad1 100644 --- a/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.html +++ b/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.html @@ -31,24 +31,19 @@ </sp-no-data-in-date-range> } - <div fxLayoutAlign="center center"> - <div - class="tl-container" - [ngStyle]="{ - width: containerWidth + 'px', - height: containerHeight + 'px' - }" - > + <div + class="status-light-wrapper" + fxFlex + fxLayout="column" + fxLayoutAlign="center center" + > + <div class="tl-container"> <div class="light" [ngClass]="{ 'light-red': !active, 'light-green': active }" - [ngStyle]="{ - width: lightWidth + 'px', - height: lightHeight + 'px' - }" ></div> </div> </div> diff --git a/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.scss b/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.scss index ac656663e5..c18549cdc5 100644 --- a/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.scss +++ b/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.scss @@ -19,19 +19,33 @@ height: 100%; } +.status-light-wrapper { + display: inline-flex; + flex-direction: column; + align-items: center; +} + .tl-container { background-color: #222; display: flex; align-items: center; - flex-direction: column; - padding: 20px; + padding: 10%; border-radius: 10px; + box-sizing: border-box; + height: 90%; + max-width: 100%; + aspect-ratio: 1 / 1; + flex-direction: column; + justify-content: space-between; + overflow: hidden; } .light { + width: 100%; + height: 100%; + aspect-ratio: 1 / 1; border-radius: 50%; - background-color: #3d3535; - background: repeating-linear-gradient(#333, #443 5px); + background: #3d3535 repeating-linear-gradient(#333, #443 5px); } .light-red, diff --git a/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.ts b/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.ts index 2681bc225d..220598544c 100644 --- a/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.ts +++ b/ui/src/app/data-explorer-shared/components/charts/status/status-widget.component.ts @@ -58,10 +58,6 @@ export class StatusWidgetComponent ngOnInit(): void { super.ngOnInit(); - // this.onResize( - // this.gridsterItemComponent.width - this.widthOffset, - // this.gridsterItemComponent.height - this.heightOffset, - // ); this.updateSettings(); } @@ -134,12 +130,7 @@ export class StatusWidgetComponent } } - onResize(width: number, heigth: number): void { - this.containerHeight = heigth * 0.7; - this.containerWidth = this.containerHeight; - this.lightWidth = this.containerHeight; - this.lightHeight = this.lightWidth; - } + onResize(width: number, heigth: number): void {} handleUpdatedFields( addedFields: DataExplorerField[], diff --git a/ui/src/app/data-explorer-shared/components/charts/table/table-widget.component.ts b/ui/src/app/data-explorer-shared/components/charts/table/table-widget.component.ts index a125322eee..e922ad992e 100644 --- a/ui/src/app/data-explorer-shared/components/charts/table/table-widget.component.ts +++ b/ui/src/app/data-explorer-shared/components/charts/table/table-widget.component.ts @@ -142,7 +142,7 @@ export class TableWidgetComponent this.refreshColumns(); } - onResize(width: number, height: number) {} + onResize(_width: number, _height: number) {} beforeDataFetched() {} diff --git a/ui/src/app/data-explorer-shared/components/charts/traffic-light/traffic-light-widget.component.scss b/ui/src/app/data-explorer-shared/components/charts/traffic-light/traffic-light-widget.component.scss index 0da8e49f0c..918f615ee5 100644 --- a/ui/src/app/data-explorer-shared/components/charts/traffic-light/traffic-light-widget.component.scss +++ b/ui/src/app/data-explorer-shared/components/charts/traffic-light/traffic-light-widget.component.scss @@ -48,7 +48,7 @@ height: auto; flex: 0 0 auto; - width: 90%; + width: 96%; aspect-ratio: 1 / 1; border-radius: 50%; diff --git a/ui/src/app/data-explorer-shared/models/dataview-dashboard.model.ts b/ui/src/app/data-explorer-shared/models/dataview-dashboard.model.ts index b6e15d442b..0340c63f46 100644 --- a/ui/src/app/data-explorer-shared/models/dataview-dashboard.model.ts +++ b/ui/src/app/data-explorer-shared/models/dataview-dashboard.model.ts @@ -40,7 +40,7 @@ export interface BaseWidgetData<T extends DataExplorerWidgetModel> { editMode: boolean; kioskMode: boolean; observableGenerator: ObservableGenerator; - + initialSize: WidgetSize; timeSettings: TimeSettings; dataViewDashboardItem: ClientDashboardItem; diff --git a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts index 5719774686..c272329388 100644 --- a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts +++ b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts @@ -59,8 +59,8 @@ import { ResizeEchartsService } from '../../../data-explorer-shared/services/res import { AssetDialogComponent } from '../../dialog/asset-dialog.component'; import { AuthService } from '../../../services/auth.service'; import { UserRole } from '../../../_enums/user-role.enum'; -import { Tuple2 } from 'src/app/core-model/base/Tuple2'; -import { ChartFieldProviderService } from 'src/app/data-explorer-shared/services/chart-field-provider.service'; +import { ChartFieldProviderService } from '../../../data-explorer-shared/services/chart-field-provider.service'; +import { Tuple2 } from '../../../core-model/base/Tuple2'; @Component({ selector: 'sp-data-explorer-data-view',
