diff --git a/cmd/ui/main.go b/cmd/ui/main.go index 61a1938e7..239dff6b3 100644 --- a/cmd/ui/main.go +++ b/cmd/ui/main.go @@ -32,13 +32,13 @@ const envPrefixGoogle = "MG_GOOGLE_" type config struct { LogLevel string `env:"MG_UI_LOG_LEVEL" envDefault:"debug"` - Port string `env:"MG_UI_PORT" envDefault:"9097"` + Port string `env:"MG_UI_PORT" envDefault:"9095"` InstanceID string `env:"MG_UI_INSTANCE_ID" envDefault:""` HTTPAdapterURL string `env:"MG_HTTP_ADAPTER_URL" envDefault:"http://localhost:8008"` ReaderURL string `env:"MG_READER_URL" envDefault:"http://localhost:9007"` ThingsURL string `env:"MG_THINGS_URL" envDefault:"http://localhost:9000"` UsersURL string `env:"MG_USERS_URL" envDefault:"http://localhost:9002"` - HostURL string `env:"MG_UI_HOST_URL" envDefault:"http://localhost:9097"` + HostURL string `env:"MG_UI_HOST_URL" envDefault:"http://localhost:9095"` BootstrapURL string `env:"MG_BOOTSTRAP_URL" envDefault:"http://localhost:9013"` DomainsURL string `env:"MG_DOMAINS_URL" envDefault:"http://localhost:8189"` InvitationsURL string `env:"MG_INVITATIONS_URL" envDefault:"http://localhost:9020"` diff --git a/internal/postgres/postgres.go b/internal/postgres/postgres.go index f5d5cf441..64143f341 100644 --- a/internal/postgres/postgres.go +++ b/internal/postgres/postgres.go @@ -22,7 +22,7 @@ var ( // Config defines the options that are used when connecting to the PostgresSQL instance. type Config struct { Host string `env:"MG_UI_DB_HOST" envDefault:"localhost"` - Port string `env:"MG_UI_DB_PORT" envDefault:"6042"` + Port string `env:"MG_UI_DB_PORT" envDefault:"5432"` User string `env:"MG_UI_DB_USER" envDefault:"magistrala-ui"` Pass string `env:"MG_UI_DB_PASS" envDefault:"magistrala-ui"` Name string `env:"MG_UI_DB_NAME" envDefault:"dashboards"` diff --git a/ui/web/static/css/dashboards.css b/ui/web/static/css/dashboards.css index 11e5b6720..5ff13d270 100644 --- a/ui/web/static/css/dashboards.css +++ b/ui/web/static/css/dashboards.css @@ -121,5 +121,12 @@ SPDX-License-Identifier: Apache-2.0 */ } .resize-helper { - border: 10px dotted #000; /* Customize as needed */ + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + z-index: 1000; + border: 1px dashed #1d2231; + pointer-events: none; } diff --git a/ui/web/static/js/charts.js b/ui/web/static/js/charts.js index fc202134e..4105c7791 100644 --- a/ui/web/static/js/charts.js +++ b/ui/web/static/js/charts.js @@ -1836,13 +1836,6 @@ class Widget { this.widgetID = widgetID; this.config = new chartTypes[this.chartData.Type](chartData, widgetID); this.element = this.#createWidgetElement(); - this.resizeObserver = this.initResizeObserver(); - this.resizeObserver.observe(this.element); - this.previousSizes = new Map(); - this.previousChartSize = { - width: 400, - height: 400, - }; } #createWidgetElement() { @@ -1869,101 +1862,4 @@ class Widget { }); return newItem; } - - initResizeObserver() { - const resizeObserver = new ResizeObserver((entries) => { - for (let entry of entries) { - const { target } = entry; - const previousSize = previousSizes.get(target) || { - width: target.clientWidth, - height: target.clientHeight, - }; - const contentEl = target.querySelector(".item-content"); - const gridRightPosition = target.parentNode.getBoundingClientRect().right; - const widgetRightPosition = target.getBoundingClientRect().right; - const isOverflowing = widgetRightPosition > gridRightPosition; - if (isOverflowing) { - target.style.maxWidth = target.clientWidth + "px"; - target.style.maxHeight = target.clientHeight + "px"; - } else { - target.style.maxWidth = "none"; - target.style.maxHeight = "none"; - } - - if (widgetRightPosition < gridRightPosition - 5) { - // Calculate the change in width and height - var widthChange = target.clientWidth - previousSize.width; - var heightChange = target.clientHeight - previousSize.height; - var itemContentWidth = - parseInt(window.getComputedStyle(contentEl).getPropertyValue("width")) + widthChange; - var itemContentHeight = - parseInt(window.getComputedStyle(contentEl).getPropertyValue("height")) + heightChange; - - // Update the previous size for the next callback - previousSizes.set(target, { - width: target.clientWidth, - height: target.clientHeight, - }); - - target.style.width = target.clientWidth + "px"; - target.style.height = target.clientHeight + "px"; - - contentEl.style.width = itemContentWidth + "px"; - contentEl.style.height = itemContentHeight + "px"; - - // Resize apache echarts chart - const chart = echarts.getInstanceByDom(contentEl); - if (chart) { - chart.resize({ - width: itemContentWidth, - height: itemContentHeight, - }); - } else { - const cardDiv = target.querySelector(".widgetcard"); - const h5Elem = cardDiv.querySelector("h5"); - const cardBody = cardDiv.querySelector(".card-body"); - const cardFooter = cardDiv.querySelector(".card-footer"); - - if (entry.contentBoxSize) { - // The standard makes contentBoxSize an array... - if (entry.contentBoxSize[0]) { - h5Elem.style.fontSize = - Math.max(1, entry.contentBoxSize[0].inlineSize / 300) + "rem"; - if (cardBody) { - cardBody.style.fontSize = - Math.max(1.5, entry.contentBoxSize[0].inlineSize / 300) + "rem"; - } - if (cardFooter) { - cardFooter.style.fontSize = - Math.max(1, entry.contentBoxSize[0].inlineSize / 600) + "rem"; - } - } else { - // ...but old versions of Firefox treat it as a single item - h5Elem.style.fontSize = Math.max(1, entry.contentBoxSize.inlineSize / 300) + "rem"; - if (cardBody) { - cardBody.style.fontSize = - Math.max(1.5, entry.contentBoxSize.inlineSize / 300) + "rem"; - } - if (cardFooter) { - cardFooter.style.fontSize = - Math.max(1, entry.contentBoxSize.inlineSize / 600) + "rem"; - } - } - } else { - h5Elem.style.fontSize = `${Math.max(1, entry.contentRect.width / 300)}rem`; - if (cardBody) { - cardBody.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 300)}rem`; - } - if (cardFooter) { - cardFooter.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`; - } - } - } - // grid.refreshItems(); - // grid.layout(true); - } - } - }); - return resizeObserver; - } } diff --git a/ui/web/static/js/dashboard.js b/ui/web/static/js/dashboard.js index 8f2dab5f2..bb7fc0e9a 100644 --- a/ui/web/static/js/dashboard.js +++ b/ui/web/static/js/dashboard.js @@ -16,7 +16,7 @@ function cancelEdit() { function addWidget(chartData, widgetID) { let newItem = new Widget(chartData, widgetID); grid.add(newItem.element); - // resizeObserver.observe(newItem.element); + resizeObserver.observe(newItem.element); } function removeGridItem(item) { @@ -172,7 +172,7 @@ function editableCanvas() { height: widgetSize.height, }); grid.add(newItem, { layout: true }); - // resizeObserver.observe(newItem); + resizeObserver.observe(newItem); }); grid.layout(); } @@ -189,6 +189,110 @@ function editableCanvas() { return grid; } +const previousSizes = new Map(); + +const resizeObserver = new ResizeObserver((entries) => { + for (let entry of entries) { + const { target } = entry; + addResizeHelper(target); + const br = target.querySelector(".item-border"); + br.style.border = "none"; + const resizeHelper = target.querySelector(".resize-helper"); + const previousSize = previousSizes.get(target) || { + width: target.clientWidth, + height: target.clientHeight, + }; + + const snapToGrid = (size) => Math.round(size / gridSize) * gridSize; + const contentEl = target.querySelector(".item-content"); + const gridRightPosition = target.parentNode.getBoundingClientRect().right; + const widgetRightPosition = resizeHelper.getBoundingClientRect().right; + const isOverflowing = widgetRightPosition > gridRightPosition; + if (isOverflowing) { + const newWidth = snapToGrid(target.clientWidth); + const newHeight = snapToGrid(target.clientHeight); + + resizeHelper.style.maxWidth = newWidth + "px"; + resizeHelper.style.maxHeight = newHeight + "px"; + } else { + resizeHelper.style.maxWidth = "none"; + resizeHelper.style.maxHeight = "none"; + } + + if (widgetRightPosition < gridRightPosition - 5) { + const snappedWidth = snapToGrid(target.clientWidth); + const snappedHeight = snapToGrid(target.clientHeight); + + resizeHelper.style.width = snappedWidth + "px"; + resizeHelper.style.height = snappedHeight + "px"; + + previousSizes.set(target, { + width: parseInt(window.getComputedStyle(resizeHelper).getPropertyValue("width")), + height: parseInt(window.getComputedStyle(resizeHelper).getPropertyValue("height")), + }); + + const finalizeResize = (event) => { + contentEl.style.width = resizeHelper.style.width; + contentEl.style.height = resizeHelper.style.height; + + // Resize apache echarts chart + const chart = echarts.getInstanceByDom(contentEl); + if (chart) { + chart.resize({ + width: parseInt(window.getComputedStyle(resizeHelper).getPropertyValue("width")), + height: parseInt(window.getComputedStyle(resizeHelper).getPropertyValue("height")), + }); + } else { + const cardDiv = target.querySelector(".widgetcard"); + const h5Elem = cardDiv.querySelector("h5"); + const cardBody = cardDiv.querySelector(".card-body"); + const cardFooter = cardDiv.querySelector(".card-footer"); + + if (entry.contentBoxSize) { + // The standard makes contentBoxSize an array... + if (entry.contentBoxSize[0]) { + h5Elem.style.fontSize = Math.max(1, entry.contentBoxSize[0].inlineSize / 300) + "rem"; + if (cardBody) { + cardBody.style.fontSize = + Math.max(1.5, entry.contentBoxSize[0].inlineSize / 300) + "rem"; + } + if (cardFooter) { + cardFooter.style.fontSize = + Math.max(1, entry.contentBoxSize[0].inlineSize / 600) + "rem"; + } + } else { + // ...but old versions of Firefox treat it as a single item + h5Elem.style.fontSize = Math.max(1, entry.contentBoxSize.inlineSize / 300) + "rem"; + if (cardBody) { + cardBody.style.fontSize = + Math.max(1.5, entry.contentBoxSize.inlineSize / 300) + "rem"; + } + if (cardFooter) { + cardFooter.style.fontSize = + Math.max(1, entry.contentBoxSize.inlineSize / 600) + "rem"; + } + } + } else { + h5Elem.style.fontSize = `${Math.max(1, entry.contentRect.width / 300)}rem`; + if (cardBody) { + cardBody.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 300)}rem`; + } + if (cardFooter) { + cardFooter.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`; + } + } + } + grid.refreshItems(); + grid.layout(true); + document.removeEventListener("mouseup", finalizeResize); + console.log("Resize finalized"); + }; + document.addEventListener("mouseup", finalizeResize); + + } + } +}); + // No widget placeholder function showNoWidgetPlaceholder() { const noWidgetPlaceholder = document.querySelector(".no-widget-placeholder"); @@ -245,3 +349,9 @@ function updateMetadata(layout, savedMetadata) { } return upMetadata; } + +function addResizeHelper(element) { + const resizeHelper = document.createElement("div"); + resizeHelper.classList.add("resize-helper"); + element.appendChild(resizeHelper); +}