From 3f80b53ea61f6e1b4e1634822549dcef58100b63 Mon Sep 17 00:00:00 2001 From: Khalid Adil Date: Thu, 17 Aug 2023 11:18:25 -0500 Subject: [PATCH 1/9] [Tooltips] Fixes for dictionary objects and self-referential objects (#6916) * Fix getTelemetryPath to handle cases where parent is the same as the child, handle yamcs aggregate telemetry, and fix how identifiers are passed in * Cleanup getTelemetryPath * Switch to filter instead of forEach * Get path item names * Remove tooltips on scroll of tree * Remove handing for scroll * Allow break-words * Cleanup --- src/api/objects/ObjectAPI.js | 42 +++++++++++-------- src/api/tooltips/ToolTipAPI.js | 15 +++++-- .../components/tooltip-component.scss | 1 + 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/api/objects/ObjectAPI.js b/src/api/objects/ObjectAPI.js index 39a3e5039d..6b46e85835 100644 --- a/src/api/objects/ObjectAPI.js +++ b/src/api/objects/ObjectAPI.js @@ -554,28 +554,34 @@ export default class ObjectAPI { */ async getTelemetryPath(identifier, telemetryIdentifier) { const objectDetails = await this.get(identifier); - const telemetryPath = []; - if (objectDetails.composition && !['folder'].includes(objectDetails.type)) { - let sourceTelemetry = objectDetails.composition[0]; + let telemetryPath = []; + if (objectDetails?.type === 'folder') { + return telemetryPath; + } + + let sourceTelemetry = null; + if (telemetryIdentifier && utils.identifierEquals(identifier, telemetryIdentifier)) { + sourceTelemetry = identifier; + } else if (objectDetails.composition) { + sourceTelemetry = objectDetails.composition[0]; if (telemetryIdentifier) { - sourceTelemetry = objectDetails.composition.find( - (telemetrySource) => - this.makeKeyString(telemetrySource) === this.makeKeyString(telemetryIdentifier) + sourceTelemetry = objectDetails.composition.find((telemetrySource) => + utils.identifierEquals(telemetrySource, telemetryIdentifier) ); } - const compositionElement = await this.get(sourceTelemetry); - if (!['yamcs.telemetry', 'generator'].includes(compositionElement.type)) { - return telemetryPath; - } - const telemetryKey = compositionElement.identifier.key; - const telemetryPathObjects = await this.getOriginalPath(telemetryKey); - telemetryPathObjects.forEach((pathObject) => { - if (pathObject.type === 'root') { - return; - } - telemetryPath.unshift(pathObject.name); - }); } + + const compositionElement = await this.get(sourceTelemetry); + if (!['yamcs.telemetry', 'generator', 'yamcs.aggregate'].includes(compositionElement.type)) { + return telemetryPath; + } + + const telemetryPathObjects = await this.getOriginalPath(compositionElement.identifier); + telemetryPath = telemetryPathObjects + .reverse() + .filter((pathObject) => pathObject.type !== 'root') + .map((pathObject) => pathObject.name); + return telemetryPath; } diff --git a/src/api/tooltips/ToolTipAPI.js b/src/api/tooltips/ToolTipAPI.js index 425538e23e..384ac2f1f0 100644 --- a/src/api/tooltips/ToolTipAPI.js +++ b/src/api/tooltips/ToolTipAPI.js @@ -57,13 +57,22 @@ class TooltipAPI { * @private for platform-internal use */ showTooltip(tooltip) { + this.removeAllTooltips(); + this.activeToolTips.push(tooltip); + tooltip.show(); + } + + /** + * API method to allow for removing all tooltips + */ + removeAllTooltips() { + if (!this.activeToolTips?.length) { + return; + } for (let i = this.activeToolTips.length - 1; i > -1; i--) { this.activeToolTips[i].destroy(); this.activeToolTips.splice(i, 1); } - this.activeToolTips.push(tooltip); - - tooltip.show(); } /** diff --git a/src/api/tooltips/components/tooltip-component.scss b/src/api/tooltips/components/tooltip-component.scss index e71ce501ea..fa9a57bd00 100644 --- a/src/api/tooltips/components/tooltip-component.scss +++ b/src/api/tooltips/components/tooltip-component.scss @@ -3,6 +3,7 @@ height: auto; width: auto; padding: $interiorMargin; + overflow-wrap: break-word; } .c-tooltip { From bada228b8fcea7dd17224708ebbfd18fe33019be Mon Sep 17 00:00:00 2001 From: Shefali Joshi Date: Thu, 17 Aug 2023 16:24:02 -0700 Subject: [PATCH 2/9] Ensure that dynamically created vue components are destroyed. (#6948) --- src/plugins/charts/scatter/plugin.js | 8 +++++++- src/plugins/clearData/plugin.js | 5 +++-- src/plugins/gauge/GaugePlugin.js | 8 +++++++- src/plugins/imagery/components/ImageryTimeView.vue | 9 ++++++++- .../notebook/components/NotebookSnapshotIndicator.vue | 6 +++++- src/plugins/notebook/plugin.js | 5 +++-- src/plugins/notificationIndicator/plugin.js | 5 +++-- src/plugins/plot/stackedPlot/StackedPlotItem.vue | 3 ++- src/plugins/userIndicator/plugin.js | 5 +++-- 9 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/plugins/charts/scatter/plugin.js b/src/plugins/charts/scatter/plugin.js index b136bb12f0..075083a718 100644 --- a/src/plugins/charts/scatter/plugin.js +++ b/src/plugins/charts/scatter/plugin.js @@ -98,9 +98,11 @@ export default function () { }; function getScatterPlotFormControl(openmct) { + let destroyComponent; + return { show(element, model, onChange) { - const { vNode } = mount( + const { vNode, destroy } = mount( { el: element, components: { @@ -122,8 +124,12 @@ export default function () { element } ); + destroyComponent = destroy; return vNode; + }, + destroy() { + destroyComponent(); } }; } diff --git a/src/plugins/clearData/plugin.js b/src/plugins/clearData/plugin.js index 8f2fd74a33..f8dc606b44 100644 --- a/src/plugins/clearData/plugin.js +++ b/src/plugins/clearData/plugin.js @@ -30,7 +30,7 @@ export default function plugin(appliesToObjects, options = { indicator: true }) return function install(openmct) { if (installIndicator) { - const { vNode } = mount( + const { vNode, destroy } = mount( { components: { GlobalClearIndicator @@ -49,7 +49,8 @@ export default function plugin(appliesToObjects, options = { indicator: true }) let indicator = { element: vNode.el, key: 'global-clear-indicator', - priority: openmct.priority.DEFAULT + priority: openmct.priority.DEFAULT, + destroy: destroy }; openmct.indicators.add(indicator); diff --git a/src/plugins/gauge/GaugePlugin.js b/src/plugins/gauge/GaugePlugin.js index 4c64ccb8fe..d05e4eff47 100644 --- a/src/plugins/gauge/GaugePlugin.js +++ b/src/plugins/gauge/GaugePlugin.js @@ -167,9 +167,11 @@ export default function () { }; function getGaugeFormController(openmct) { + let destroyComponent; + return { show(element, model, onChange) { - const { vNode } = mount( + const { vNode, destroy } = mount( { el: element, components: { @@ -191,8 +193,12 @@ export default function () { element } ); + destroyComponent = destroy; return vNode.componentInstance; + }, + destroy() { + destroyComponent(); } }; } diff --git a/src/plugins/imagery/components/ImageryTimeView.vue b/src/plugins/imagery/components/ImageryTimeView.vue index 23aeba6a51..6e8a24819f 100644 --- a/src/plugins/imagery/components/ImageryTimeView.vue +++ b/src/plugins/imagery/components/ImageryTimeView.vue @@ -98,6 +98,9 @@ export default { if (this.unlisten) { this.unlisten(); } + if (this.destroyImageryContainer) { + this.destroyImageryContainer(); + } }, methods: { setTimeContext() { @@ -237,7 +240,10 @@ export default { imageryContainer = existingContainer; imageryContainer.style.maxWidth = `${containerWidth}px`; } else { - const { vNode } = mount( + if (this.destroyImageryContainer) { + this.destroyImageryContainer(); + } + const { vNode, destroy } = mount( { components: { SwimLane @@ -257,6 +263,7 @@ export default { } ); + this.destroyImageryContainer = destroy; const component = vNode.componentInstance; this.$refs.imageryHolder.appendChild(component.$el); diff --git a/src/plugins/notebook/components/NotebookSnapshotIndicator.vue b/src/plugins/notebook/components/NotebookSnapshotIndicator.vue index 9906d1f15f..16eba66b4d 100644 --- a/src/plugins/notebook/components/NotebookSnapshotIndicator.vue +++ b/src/plugins/notebook/components/NotebookSnapshotIndicator.vue @@ -90,7 +90,10 @@ export default { drawerElement.innerHTML = '
'; const divElement = document.querySelector('.l-shell__drawer div'); - mount( + if (this.destroySnapshotContainer) { + this.destroySnapshotContainer(); + } + const { destroy } = mount( { el: divElement, components: { @@ -113,6 +116,7 @@ export default { element: divElement } ); + this.destroySnapshotContainer = destroy; }, updateSnapshotIndicatorTitle() { const snapshotCount = this.snapshotContainer.getSnapshots().length; diff --git a/src/plugins/notebook/plugin.js b/src/plugins/notebook/plugin.js index 33b23da862..6ecdc8a4da 100644 --- a/src/plugins/notebook/plugin.js +++ b/src/plugins/notebook/plugin.js @@ -83,7 +83,7 @@ function installBaseNotebookFunctionality(openmct) { openmct.actions.register(new CopyToNotebookAction(openmct)); openmct.actions.register(new ExportNotebookAsTextAction(openmct)); - const { vNode } = mount( + const { vNode, destroy } = mount( { components: { NotebookSnapshotIndicator @@ -102,7 +102,8 @@ function installBaseNotebookFunctionality(openmct) { const indicator = { element: vNode.el, key: 'notebook-snapshot-indicator', - priority: openmct.priority.DEFAULT + priority: openmct.priority.DEFAULT, + destroy: destroy }; openmct.indicators.add(indicator); diff --git a/src/plugins/notificationIndicator/plugin.js b/src/plugins/notificationIndicator/plugin.js index 22e92f6bde..79dfce78f2 100644 --- a/src/plugins/notificationIndicator/plugin.js +++ b/src/plugins/notificationIndicator/plugin.js @@ -24,7 +24,7 @@ import NotificationIndicator from './components/NotificationIndicator.vue'; export default function plugin() { return function install(openmct) { - const { vNode } = mount( + const { vNode, destroy } = mount( { components: { NotificationIndicator @@ -42,7 +42,8 @@ export default function plugin() { let indicator = { key: 'notifications-indicator', element: vNode.el, - priority: openmct.priority.DEFAULT + priority: openmct.priority.DEFAULT, + destroy: destroy }; openmct.indicators.add(indicator); }; diff --git a/src/plugins/plot/stackedPlot/StackedPlotItem.vue b/src/plugins/plot/stackedPlot/StackedPlotItem.vue index 219aed6b74..f69e44eb16 100644 --- a/src/plugins/plot/stackedPlot/StackedPlotItem.vue +++ b/src/plugins/plot/stackedPlot/StackedPlotItem.vue @@ -197,7 +197,7 @@ export default { this.composition.load(); } - const { vNode } = mount( + const { vNode, destroy } = mount( { components: { Plot @@ -249,6 +249,7 @@ export default { } ); this.component = vNode.componentInstance; + this._destroy = destroy; if (this.isEditing) { this.setSelection(); diff --git a/src/plugins/userIndicator/plugin.js b/src/plugins/userIndicator/plugin.js index e844a77f83..d9cce9a79b 100644 --- a/src/plugins/userIndicator/plugin.js +++ b/src/plugins/userIndicator/plugin.js @@ -25,7 +25,7 @@ import UserIndicator from './components/UserIndicator.vue'; export default function UserIndicatorPlugin() { function addIndicator(openmct) { - const { vNode } = mount( + const { vNode, destroy } = mount( { components: { UserIndicator @@ -43,7 +43,8 @@ export default function UserIndicatorPlugin() { openmct.indicators.add({ key: 'user-indicator', element: vNode.el, - priority: openmct.priority.HIGH + priority: openmct.priority.HIGH, + destroy: destroy }); } From a495e86231346081c58c3770b0b803133e386ee3 Mon Sep 17 00:00:00 2001 From: David 'Epper' Marshall Date: Fri, 18 Aug 2023 18:54:58 -0400 Subject: [PATCH 3/9] fix(#6516): Progress Bar does not show progress percentage (#6952) MCT 6516 Co-authored-by: Jesse Mazzella --- src/ui/components/progress-bar.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/components/progress-bar.scss b/src/ui/components/progress-bar.scss index 70ab413acf..4fd1052072 100644 --- a/src/ui/components/progress-bar.scss +++ b/src/ui/components/progress-bar.scss @@ -25,6 +25,7 @@ &__bar { background: $colorProgressBar; height: 100%; + min-height: $progressBarMinH; &.--indeterminate { position: absolute; From a52577e7296fda747912caeabe465805004d3023 Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Sat, 19 Aug 2023 22:16:26 +0200 Subject: [PATCH 4/9] feat(tooling): adds nvm (#6938) * feat(tooling): adds nvm * fix(ci): nodev16 -> nodev18 * chore(node): dont modify ci config * feat(nvm): add lts * docs(readme): add section on nvm * fix(docs): revise section --------- Co-authored-by: John Hill --- .nvmrc | 1 + README.md | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..1a2f5bd204 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/* \ No newline at end of file diff --git a/README.md b/README.md index 109aa43c49..1221e19a62 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ Building and running Open MCT in your local dev environment is very easy. Be sur `git clone https://github.com/nasa/openmct.git` -2. Install development dependencies. Note: Check the package.json engine for our tested and supported node versions. +2. (Optionally) Install the correct node version using [nvm](https://github.com/nvm-sh/nvm) (`nvm install`) +3. Install development dependencies. Note: Check the package.json engine for our tested and supported node versions. `npm install` -3. Run a local development server +4. Run a local development server `npm start` @@ -51,6 +52,8 @@ For more on developing with Open MCT, see our documentation for a guide on [Deve This is a fast moving project and we do our best to test and support the widest possible range of browsers, operating systems, and nodejs APIs. We have a published list of support available in our package.json's `browserslist` key. +The project uses `nvm` to ensure the node and npm version used, is coherent in all projects. Install nvm (non-windows), [here](https://github.com/nvm-sh/nvm) or the windows equivalent [here](https://github.com/coreybutler/nvm-windows) + If you encounter an issue with a particular browser, OS, or nodejs API, please file a [GitHub issue](https://github.com/nasa/openmct/issues/new/choose) ## Plugins From 0a497483f20360f4298a4c6a4ba5b9e58e035bbe Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Mon, 21 Aug 2023 18:58:06 +0200 Subject: [PATCH 5/9] fix(html): minor fixes from validation (#6962) * fix(html): minor fixes from validation * chore(html): Update index.html Co-authored-by: Jesse Mazzella --------- Co-authored-by: Jesse Mazzella --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index dce027e2a2..9233eadfbd 100644 --- a/index.html +++ b/index.html @@ -28,7 +28,7 @@ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no" /> - + Open MCT -