Migrate to Vue 3 Migration Build (#6767)
* Replacing all instances of the new Vue() component creation pattern * In Vue 3, components cannot be created on the fly and mounted off-DOM. The suggested fix from Vue is to use createApp, but in the context of Open MCT this means dozens of Vue apps being created and destroyed at any given moment. Instead, we have used a community hack for creating individual components. * beforeDestroy() -> beforeUnmount() * destroyed() -> unmounted() * The addition of deep: true option on Array listeners is now required to detect Array changes * Open MCT is now mounted on a child div instead of directly on document.body --------- Co-authored-by: Scott Bell <scott@traclabs.com> Co-authored-by: Andrew Henry <akhenry@gmail.com> Co-authored-by: John Hill <john.c.hill@nasa.gov>
This commit is contained in:
@@ -25,29 +25,37 @@
|
||||
|
||||
<script>
|
||||
import AboutDialog from './AboutDialog.vue';
|
||||
import Vue from 'vue';
|
||||
import mount from 'utils/mount';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
mounted() {
|
||||
let branding = this.openmct.branding();
|
||||
const branding = this.openmct.branding();
|
||||
if (branding.smallLogoImage) {
|
||||
this.$refs.aboutLogo.style.backgroundImage = `url('${branding.smallLogoImage}')`;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
launchAbout() {
|
||||
let vm = new Vue({
|
||||
components: { AboutDialog },
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
const { el, destroy } = mount(
|
||||
{
|
||||
components: { AboutDialog },
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
},
|
||||
template: '<about-dialog></about-dialog>'
|
||||
},
|
||||
template: '<about-dialog></about-dialog>'
|
||||
}).$mount();
|
||||
{
|
||||
app: this.openmct.app
|
||||
}
|
||||
);
|
||||
|
||||
el.classList.add('u-contents');
|
||||
|
||||
this.openmct.overlays.overlay({
|
||||
element: vm.$el,
|
||||
size: 'large'
|
||||
element: el,
|
||||
size: 'large',
|
||||
onDestroy: destroy
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ import ViewSwitcher from './ViewSwitcher.vue';
|
||||
import NotebookMenuSwitcher from '@/plugins/notebook/components/NotebookMenuSwitcher.vue';
|
||||
import IndependentTimeConductor from '@/plugins/timeConductor/independent/IndependentTimeConductor.vue';
|
||||
import tooltipHelpers from '../../api/tooltips/tooltipMixins';
|
||||
import { toRaw } from 'vue';
|
||||
|
||||
const SupportedViewTypes = [
|
||||
'plot-stacked',
|
||||
@@ -202,7 +203,7 @@ export default {
|
||||
});
|
||||
},
|
||||
hasParent() {
|
||||
return this.domainObject !== PLACEHOLDER_OBJECT && this.parentUrl !== '/browse';
|
||||
return toRaw(this.domainObject) !== PLACEHOLDER_OBJECT && this.parentUrl !== '/browse';
|
||||
},
|
||||
parentUrl() {
|
||||
const objectKeyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
@@ -268,7 +269,6 @@ export default {
|
||||
this.unlistenToActionCollection();
|
||||
}
|
||||
|
||||
this.actionCollection = actionCollection;
|
||||
this.actionCollection.on('update', this.updateActionItems);
|
||||
this.updateActionItems(this.actionCollection.getActionsObject());
|
||||
}
|
||||
@@ -282,7 +282,7 @@ export default {
|
||||
this.isEditing = isEditing;
|
||||
});
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
beforeUnmount: function () {
|
||||
if (this.mutationObserver) {
|
||||
this.mutationObserver();
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
<multipane class="l-shell__main" :class="[resizingClass]" type="horizontal">
|
||||
<pane
|
||||
class="l-shell__pane-tree"
|
||||
style="width: 300px"
|
||||
handle="after"
|
||||
label="Browse"
|
||||
hide-param="hideTree"
|
||||
@@ -81,18 +80,18 @@
|
||||
@start-resizing="onStartResizing"
|
||||
@end-resizing="onEndResizing"
|
||||
>
|
||||
<button
|
||||
slot="controls"
|
||||
class="c-icon-button l-shell__reset-tree-button icon-folders-collapse"
|
||||
title="Collapse all tree items"
|
||||
@click="handleTreeReset"
|
||||
></button>
|
||||
<button
|
||||
slot="controls"
|
||||
class="c-icon-button l-shell__sync-tree-button icon-target"
|
||||
title="Show selected item in tree"
|
||||
@click="handleSyncTreeNavigation"
|
||||
></button>
|
||||
<template #controls>
|
||||
<button
|
||||
class="c-icon-button l-shell__reset-tree-button icon-folders-collapse"
|
||||
title="Collapse all tree items"
|
||||
@click="handleTreeReset"
|
||||
></button>
|
||||
<button
|
||||
class="c-icon-button l-shell__sync-tree-button icon-target"
|
||||
title="Show selected item in tree"
|
||||
@click="handleSyncTreeNavigation"
|
||||
></button>
|
||||
</template>
|
||||
<multipane type="vertical">
|
||||
<pane>
|
||||
<mct-tree
|
||||
@@ -109,14 +108,15 @@
|
||||
@openAndScrollTo="openAndScrollTo($event)"
|
||||
@setClearButtonDisabled="setClearButtonDisabled"
|
||||
/>
|
||||
<button
|
||||
slot="controls"
|
||||
class="c-icon-button icon-clear-data"
|
||||
aria-label="Clear Recently Viewed"
|
||||
title="Clear Recently Viewed"
|
||||
:disabled="disableClearButton"
|
||||
@click="handleClearRecentObjects"
|
||||
></button>
|
||||
<template #controls>
|
||||
<button
|
||||
class="c-icon-button icon-clear-data"
|
||||
aria-label="Clear Recently Viewed"
|
||||
title="Clear Recently Viewed"
|
||||
:disabled="disableClearButton"
|
||||
@click="handleClearRecentObjects"
|
||||
></button>
|
||||
</template>
|
||||
</pane>
|
||||
</multipane>
|
||||
</pane>
|
||||
|
||||
@@ -62,7 +62,7 @@ export default {
|
||||
this.openmct.router.on('change:path', this.onPathChange);
|
||||
this.getSavedRecentItems();
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.openmct.router.off('change:path', this.onPathChange);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
class="c-recentobjects-listitem__object-path"
|
||||
:read-only="false"
|
||||
:domain-object="domainObject"
|
||||
:show-original-path="false"
|
||||
:object-path="objectPath"
|
||||
/>
|
||||
</div>
|
||||
@@ -102,7 +101,7 @@ export default {
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
this.previewAction.on('isVisible', this.togglePreviewState);
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.previewAction.off('isVisible', this.togglePreviewState);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
}
|
||||
|
||||
&__pane-tree {
|
||||
width: 100%;
|
||||
width: 300px;
|
||||
padding-left: nth($shellPanePad, 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
import _ from 'lodash';
|
||||
import treeItem from './tree-item.vue';
|
||||
import search from '../components/search.vue';
|
||||
import { markRaw } from 'vue';
|
||||
|
||||
const ITEM_BUFFER = 25;
|
||||
const LOCAL_STORAGE_KEY__TREE_EXPANDED = 'mct-tree-expanded';
|
||||
@@ -248,11 +249,17 @@ export default {
|
||||
mainTreeHeight() {
|
||||
this.updateVisibleItems();
|
||||
},
|
||||
focusedItems() {
|
||||
this.updateVisibleItems();
|
||||
focusedItems: {
|
||||
handler(val, oldVal) {
|
||||
this.updateVisibleItems();
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
openTreeItems() {
|
||||
this.setSavedOpenItems();
|
||||
openTreeItems: {
|
||||
handler(val, oldVal) {
|
||||
this.setSavedOpenItems();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
@@ -278,7 +285,7 @@ export default {
|
||||
this.handleTreeResize = _.debounce(this.handleTreeResize, 300);
|
||||
this.scrollEndEvent = _.debounce(this.scrollEndEvent, 100);
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
if (this.treeResizeObserver) {
|
||||
this.treeResizeObserver.disconnect();
|
||||
}
|
||||
@@ -287,7 +294,7 @@ export default {
|
||||
this.destroyMutables();
|
||||
},
|
||||
methods: {
|
||||
async initialize() {
|
||||
initialize() {
|
||||
this.observers = {};
|
||||
this.mutables = {};
|
||||
this.isLoading = true;
|
||||
@@ -295,7 +302,8 @@ export default {
|
||||
this.treeResizeObserver = new ResizeObserver(this.handleTreeResize);
|
||||
this.treeResizeObserver.observe(this.$el);
|
||||
|
||||
await this.calculateHeights();
|
||||
// need to wait for the first tick to get the height of the tree
|
||||
this.$nextTick().then(this.calculateHeights);
|
||||
|
||||
return;
|
||||
},
|
||||
@@ -392,12 +400,12 @@ export default {
|
||||
this.abortItemLoad(path);
|
||||
}
|
||||
|
||||
this.$set(this.treeItemLoading, path, new AbortController());
|
||||
this.treeItemLoading[path] = new AbortController();
|
||||
|
||||
return this.treeItemLoading[path].signal;
|
||||
},
|
||||
endItemLoad(path) {
|
||||
this.$set(this.treeItemLoading, path, undefined);
|
||||
this.treeItemLoading[path] = undefined;
|
||||
delete this.treeItemLoading[path];
|
||||
},
|
||||
abortItemLoad(path) {
|
||||
@@ -590,7 +598,7 @@ export default {
|
||||
}
|
||||
|
||||
this.compositionCollections[navigationPath] = {};
|
||||
this.compositionCollections[navigationPath].collection = collection;
|
||||
this.compositionCollections[navigationPath].collection = markRaw(collection);
|
||||
this.compositionCollections[navigationPath].addHandler =
|
||||
this.compositionAddHandler(navigationPath);
|
||||
this.compositionCollections[navigationPath].removeHandler =
|
||||
|
||||
@@ -124,7 +124,7 @@ export default {
|
||||
this.previewAction.on('isVisible', this.togglePreviewState);
|
||||
this.fireAnnotationSelection = this.fireAnnotationSelection.bind(this);
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.previewAction.off('isVisible', this.togglePreviewState);
|
||||
this.openmct.selection.off('change', this.fireAnnotationSelection);
|
||||
},
|
||||
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
mounted() {
|
||||
this.getSearchResults = this.debounceAsyncFunction(this.getSearchResults, SEARCH_DEBOUNCE_TIME);
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
document.body.removeEventListener('click', this.handleOutsideClick);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
this.previewAction.on('isVisible', this.togglePreviewState);
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.previewAction.off('isVisible', this.togglePreviewState);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
:key="openmct.objects.makeKeyString(objectResult.identifier)"
|
||||
:result="objectResult"
|
||||
@preview-changed="previewChanged"
|
||||
@click.native="selectedResult"
|
||||
@click="selectedResult"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="annotationResults && annotationResults.length" ref="annotationResults">
|
||||
@@ -45,7 +45,7 @@
|
||||
v-for="annotationResult in annotationResults"
|
||||
:key="makeKeyForAnnotationResult(annotationResult)"
|
||||
:result="annotationResult"
|
||||
@click.native="selectedResult"
|
||||
@click="selectedResult"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="searchLoading" class="c-gsearch__result-pane-msg">
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
this.openmct.indicators.off('addIndicator', this.addIndicator);
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -189,9 +189,9 @@ export default {
|
||||
|
||||
this.$emit('tree-item-mounted', this.navigationPath);
|
||||
},
|
||||
destroyed() {
|
||||
unmounted() {
|
||||
this.openmct.router.off('change:path', this.highlightIfNavigated);
|
||||
this.$emit('tree-item-destoyed', this.navigationPath);
|
||||
this.$emit('tree-item-destroyed', this.navigationPath);
|
||||
},
|
||||
methods: {
|
||||
targetedPathAnimationEnd($event) {
|
||||
|
||||
Reference in New Issue
Block a user