mirror of
https://github.com/nasa/openmct.git
synced 2025-06-26 03:00:13 +00:00
Compare commits
6 Commits
plotly-and
...
tree-refac
Author | SHA1 | Date | |
---|---|---|---|
15bef1c162 | |||
a2d21e3479 | |||
5693b153cb | |||
13e9541ad2 | |||
c0e3f6b577 | |||
f763d1dea1 |
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<span
|
<span
|
||||||
class="c-disclosure-triangle"
|
:class="[
|
||||||
:class="{
|
controlClass,
|
||||||
'c-disclosure-triangle--expanded' : value,
|
{ 'c-disclosure-triangle--expanded' : value },
|
||||||
'is-enabled' : enabled
|
{'is-enabled' : enabled }
|
||||||
}"
|
]"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
></span>
|
></span>
|
||||||
</template>
|
</template>
|
||||||
@ -25,6 +25,10 @@ export default {
|
|||||||
propagate: {
|
propagate: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
controlClass: {
|
||||||
|
type: String,
|
||||||
|
default: 'c-disclosure-triangle'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
class="l-browse-bar__context-actions c-disclosure-button"
|
class="l-browse-bar__context-actions c-disclosure-button"
|
||||||
@click.prevent.stop="showContextMenu"
|
@click.prevent.stop="showContextMenu"
|
||||||
></div>
|
></div>
|
||||||
|
<div
|
||||||
|
class="l-browse-sync-tree"
|
||||||
|
@click="syncNavigationTree"
|
||||||
|
>Sync</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="l-browse-bar__end">
|
<div class="l-browse-bar__end">
|
||||||
@ -271,6 +275,9 @@ export default {
|
|||||||
},
|
},
|
||||||
goToParent() {
|
goToParent() {
|
||||||
window.location.hash = this.parentUrl;
|
window.location.hash = this.parentUrl;
|
||||||
|
},
|
||||||
|
syncNavigationTree() {
|
||||||
|
this.$emit('syncTreeNavigation');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,16 @@
|
|||||||
label="Browse"
|
label="Browse"
|
||||||
collapsable
|
collapsable
|
||||||
>
|
>
|
||||||
<mct-tree class="l-shell__tree" />
|
<mct-tree
|
||||||
|
:sync-tree-navigation="triggerSync"
|
||||||
|
class="l-shell__tree"
|
||||||
|
/>
|
||||||
</pane>
|
</pane>
|
||||||
<pane class="l-shell__pane-main">
|
<pane class="l-shell__pane-main">
|
||||||
<browse-bar
|
<browse-bar
|
||||||
ref="browseBar"
|
ref="browseBar"
|
||||||
class="l-shell__main-view-browse-bar"
|
class="l-shell__main-view-browse-bar"
|
||||||
|
@syncTreeNavigation="handleSyncTreeNavigation"
|
||||||
/>
|
/>
|
||||||
<toolbar
|
<toolbar
|
||||||
v-if="toolbar"
|
v-if="toolbar"
|
||||||
@ -154,7 +158,8 @@ export default {
|
|||||||
conductorComponent: undefined,
|
conductorComponent: undefined,
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
hasToolbar: false,
|
hasToolbar: false,
|
||||||
headExpanded
|
headExpanded,
|
||||||
|
triggerSync: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -204,6 +209,9 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.hasToolbar = structure.length > 0;
|
this.hasToolbar = structure.length > 0;
|
||||||
|
},
|
||||||
|
handleSyncTreeNavigation() {
|
||||||
|
this.triggerSync = !this.triggerSync;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
.c-tree-and-search {
|
.c-tree-and-search {
|
||||||
|
$hoverBg: rgba(#000, 0.1);
|
||||||
|
$hoverFg: #ccc;
|
||||||
|
$selected: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
//TODO: Do we need this???
|
//TODO: Do we need this???
|
||||||
//padding-right: $interiorMarginSm;
|
//padding-right: $interiorMarginSm;
|
||||||
overflow: auto;
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
> * + * { margin-top: $interiorMargin; }
|
> * + * { margin-top: $interiorMargin; }
|
||||||
|
|
||||||
@ -26,6 +30,105 @@
|
|||||||
height: 0; // Chrome 73 overflow bug fix
|
height: 0; // Chrome 73 overflow bug fix
|
||||||
padding-right: $interiorMarginSm;
|
padding-right: $interiorMarginSm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new tree refactor
|
||||||
|
.c-tree,
|
||||||
|
.c-list {
|
||||||
|
&__item {
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $hoverBg;
|
||||||
|
|
||||||
|
[class*="__name"] {
|
||||||
|
color: darken($colorKeyFg, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-navigated-object,
|
||||||
|
&.is-selected {
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
[class*="__name"] {
|
||||||
|
color: $selected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// new tree refactor
|
||||||
|
.c-tree {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
transition: all;
|
||||||
|
|
||||||
|
.c-tree {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
border-bottom: 1px solid $colorInteriorBorder;
|
||||||
|
|
||||||
|
&.is-navigated-object,
|
||||||
|
&.is-selected {
|
||||||
|
.c-tree__item__type-icon:before {
|
||||||
|
color: $selected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-nav {
|
||||||
|
$dimension: 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
&__up, &__down {
|
||||||
|
color: #fff;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
height: $dimension;
|
||||||
|
width: $dimension;
|
||||||
|
opacity: 0;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.is-enabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: darken($colorKeyFg, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Nav arrow
|
||||||
|
$color: rgba(#999, 0.5);
|
||||||
|
$dimension: 7px;
|
||||||
|
$width: 3px;
|
||||||
|
border: solid $color;
|
||||||
|
border-width: $width;
|
||||||
|
border-width: 0 $width $width 0;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%; top: 50%;
|
||||||
|
height: $dimension;
|
||||||
|
width: $dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover:before {
|
||||||
|
border-color: $colorItemTreeHoverFg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__up:before {
|
||||||
|
transform: translate(-30%, -50%) rotate(135deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__down:before {
|
||||||
|
transform: translate(-70%, -50%) rotate(-45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-tree,
|
.c-tree,
|
||||||
@ -72,8 +175,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.c-tree {
|
.c-tree {
|
||||||
|
|
||||||
.c-tree {
|
.c-tree {
|
||||||
margin-left: 15px;
|
padding-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
@ -157,3 +261,32 @@
|
|||||||
padding: $interiorMargin;
|
padding: $interiorMargin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TRANSITIONS
|
||||||
|
.slide-left,
|
||||||
|
.slide-right {
|
||||||
|
animation-duration: 500ms;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
transition: all;
|
||||||
|
transition-timing-function: ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left {
|
||||||
|
animation-name: animSlideLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-right {
|
||||||
|
animation-name: animSlideRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animSlideLeft {
|
||||||
|
0% {opactiy: 0; transform: translateX(100%);}
|
||||||
|
10% {opacity: 1;}
|
||||||
|
100% {transform: translateX(0);}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animSlideRight {
|
||||||
|
0% {opactiy: 0; transform: translateX(-100%);}
|
||||||
|
10% {opacity: 1;}
|
||||||
|
100% {transform: translateX(0);}
|
||||||
|
}
|
@ -31,9 +31,11 @@
|
|||||||
class="c-tree-and-search__tree c-tree"
|
class="c-tree-and-search__tree c-tree"
|
||||||
>
|
>
|
||||||
<tree-item
|
<tree-item
|
||||||
v-for="treeItem in allTreeItems"
|
v-for="item in allTreeItems"
|
||||||
:key="treeItem.id"
|
:key="item.id"
|
||||||
:node="treeItem"
|
:class="childrenSlideClass"
|
||||||
|
:node="item"
|
||||||
|
:sync-check="checkForSync"
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- end main tree -->
|
<!-- end main tree -->
|
||||||
@ -44,9 +46,9 @@
|
|||||||
class="c-tree-and-search__tree c-tree"
|
class="c-tree-and-search__tree c-tree"
|
||||||
>
|
>
|
||||||
<tree-item
|
<tree-item
|
||||||
v-for="treeItem in filteredTreeItems"
|
v-for="item in filteredTreeItems"
|
||||||
:key="treeItem.id"
|
:key="item.id"
|
||||||
:node="treeItem"
|
:node="item"
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- end search tree -->
|
<!-- end search tree -->
|
||||||
@ -64,26 +66,43 @@ export default {
|
|||||||
search,
|
search,
|
||||||
treeItem
|
treeItem
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
syncTreeNavigation: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
allTreeItems: [],
|
allTreeItems: [],
|
||||||
filteredTreeItems: [],
|
filteredTreeItems: [],
|
||||||
isLoading: false
|
isLoading: false,
|
||||||
|
childrenSlideClass: 'slide-left',
|
||||||
|
checkForSync: this.makeHash()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
syncTreeNavigation() {
|
||||||
|
console.log('sync in mct-tree');
|
||||||
|
this.checkForSync = this.makeHash();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.searchService = this.openmct.$injector.get('searchService');
|
this.searchService = this.openmct.$injector.get('searchService');
|
||||||
this.getAllChildren();
|
this.getAllChildren();
|
||||||
|
console.log('tree: mounted');
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getAllChildren() {
|
getAllChildren() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.openmct.objects.get('ROOT')
|
this.openmct.objects.get('ROOT')
|
||||||
.then(root => {
|
.then(root => {
|
||||||
|
console.log('tree: root', root);
|
||||||
return this.openmct.composition.get(root).load()
|
return this.openmct.composition.get(root).load()
|
||||||
})
|
})
|
||||||
.then(children => {
|
.then(children => {
|
||||||
|
console.log('tree: children', children);
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.allTreeItems = children.map(c => {
|
this.allTreeItems = children.map(c => {
|
||||||
return {
|
return {
|
||||||
@ -128,6 +147,14 @@ export default {
|
|||||||
if (this.searchValue !== '') {
|
if (this.searchValue !== '') {
|
||||||
this.getFilteredChildren();
|
this.getFilteredChildren();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
makeHash(length = 20) {
|
||||||
|
let hash = '',
|
||||||
|
characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
hash += characters.charAt(Math.floor(Math.random() * characters.length)) + Date.now();
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,26 @@
|
|||||||
<div
|
<div
|
||||||
class="c-tree__item"
|
class="c-tree__item"
|
||||||
:class="{ 'is-alias': isAlias, 'is-navigated-object': navigated }"
|
:class="{ 'is-alias': isAlias, 'is-navigated-object': navigated }"
|
||||||
|
:style="{ paddingLeft: ancestors * 10 + 10 + 'px' }"
|
||||||
>
|
>
|
||||||
<view-control
|
<view-control
|
||||||
v-model="expanded"
|
v-model="expanded"
|
||||||
class="c-tree__item__view-control"
|
class="c-tree__item__view-control"
|
||||||
:enabled="hasChildren"
|
:enabled="hasChildren && activeChild !== undefined"
|
||||||
|
:control-class="'c-nav__up'"
|
||||||
|
@input="resetTreeHere"
|
||||||
/>
|
/>
|
||||||
<object-label
|
<object-label
|
||||||
:domain-object="node.object"
|
:domain-object="node.object"
|
||||||
:object-path="node.objectPath"
|
:object-path="node.objectPath"
|
||||||
:navigate-to-path="navigateToPath"
|
:navigate-to-path="navigateToPath"
|
||||||
/>
|
/>
|
||||||
|
<view-control
|
||||||
|
v-model="expanded"
|
||||||
|
class="c-tree__item__view-control"
|
||||||
|
:control-class="'c-nav__down'"
|
||||||
|
:enabled="hasChildren && !activeChild && !expanded"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
v-if="expanded"
|
v-if="expanded"
|
||||||
@ -27,11 +36,21 @@
|
|||||||
<span class="c-tree__item__label">Loading...</span>
|
<span class="c-tree__item__label">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<tree-item
|
<template
|
||||||
v-for="child in children"
|
v-for="child in children"
|
||||||
:key="child.id"
|
>
|
||||||
:node="child"
|
<tree-item
|
||||||
/>
|
v-if="activeChild && child.id === activeChild || !activeChild"
|
||||||
|
:key="child.id"
|
||||||
|
:class="{[childrenSlideClass] : child.id !== activeChild}"
|
||||||
|
:node="child"
|
||||||
|
:collapse-children="collapseMyChildren"
|
||||||
|
:ancestors="ancestors + 1"
|
||||||
|
:sync-check="triggerChildSync"
|
||||||
|
@expanded="handleExpanded"
|
||||||
|
@childState="handleChildState"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
@ -41,6 +60,12 @@ import viewControl from '../components/viewControl.vue';
|
|||||||
import ObjectLabel from '../components/ObjectLabel.vue';
|
import ObjectLabel from '../components/ObjectLabel.vue';
|
||||||
|
|
||||||
const LOCAL_STORAGE_KEY__TREE_EXPANDED = 'mct-tree-expanded';
|
const LOCAL_STORAGE_KEY__TREE_EXPANDED = 'mct-tree-expanded';
|
||||||
|
const SLIDE_RIGHT = 'slide-right';
|
||||||
|
const SLIDE_LEFT = 'slide-left';
|
||||||
|
|
||||||
|
function copyItem(item) {
|
||||||
|
return JSON.parse(JSON.stringify(item));
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TreeItem',
|
name: 'TreeItem',
|
||||||
@ -53,6 +78,18 @@ export default {
|
|||||||
node: {
|
node: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
ancestors: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
collapseChildren: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
syncCheck: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -63,7 +100,14 @@ export default {
|
|||||||
loaded: false,
|
loaded: false,
|
||||||
navigated: this.navigateToPath === this.openmct.router.currentLocation.path,
|
navigated: this.navigateToPath === this.openmct.router.currentLocation.path,
|
||||||
children: [],
|
children: [],
|
||||||
expanded: false
|
expanded: false,
|
||||||
|
activeChild: undefined,
|
||||||
|
collapseMyChildren: '',
|
||||||
|
childrenSlideClass: SLIDE_LEFT,
|
||||||
|
triggerChildSync: '',
|
||||||
|
onChildrenLoaded: [],
|
||||||
|
mountedChildren: [],
|
||||||
|
onChildMounted: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -81,23 +125,77 @@ export default {
|
|||||||
if (!this.hasChildren) {
|
if (!this.hasChildren) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.loaded && !this.isLoading) {
|
if(this.expanded) {
|
||||||
this.composition = this.openmct.composition.get(this.domainObject);
|
this.$emit('expanded', this.domainObject);
|
||||||
this.composition.on('add', this.addChild);
|
this.loadChildren();
|
||||||
this.composition.on('remove', this.removeChild);
|
|
||||||
this.composition.load().then(this.finishLoading);
|
|
||||||
this.isLoading = true;
|
|
||||||
}
|
}
|
||||||
this.setLocalStorageExpanded(this.navigateToPath);
|
this.setLocalStorageExpanded(this.navigateToPath);
|
||||||
|
},
|
||||||
|
collapseChildren() {
|
||||||
|
if(this.collapseChildren) {
|
||||||
|
this.expanded = false;
|
||||||
|
this.activeChild = undefined;
|
||||||
|
this.loaded = false;
|
||||||
|
this.children = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
syncCheck() {
|
||||||
|
let currentLocationPath = this.openmct.router.currentLocation.path;
|
||||||
|
if(currentLocationPath) {
|
||||||
|
let isAncestor = currentLocationPath.includes(this.navigateToPath);
|
||||||
|
|
||||||
|
// not the currently navigated object, but it is an ancestor
|
||||||
|
if(isAncestor && !this.navigated) {
|
||||||
|
let descendantPath = currentLocationPath.split(this.navigateToPath + '/')[1],
|
||||||
|
descendants = descendantPath.split('/'),
|
||||||
|
descendantCount = descendants.length,
|
||||||
|
immediateDescendant = descendants[0];
|
||||||
|
|
||||||
|
this.activeChild = undefined;
|
||||||
|
|
||||||
|
if(descendantCount > 1) {
|
||||||
|
this.activeChild = immediateDescendant;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if current path is not expanded, need to expand (load children) and trigger sync
|
||||||
|
if(!this.expanded) {
|
||||||
|
if(descendantCount > 1) {
|
||||||
|
this.onChildrenLoaded.push(() => {
|
||||||
|
this.triggerChildrenSyncCheck()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.expanded = true;
|
||||||
|
|
||||||
|
// if current path IS expanded, then we need to check that child is mounted
|
||||||
|
// as it could have been unmounted previously if it was not the activeChild
|
||||||
|
} else {
|
||||||
|
let alreadyMounted = this.mountedChildren.includes(immediateDescendant);
|
||||||
|
if(alreadyMounted) {
|
||||||
|
this.triggerChildrenSyncCheck()
|
||||||
|
} else {
|
||||||
|
this.onChildMounted.push({
|
||||||
|
child: immediateDescendant,
|
||||||
|
callback: () => {
|
||||||
|
this.triggerChildrenSyncCheck()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.expanded = false;
|
||||||
|
this.activeChild = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// TODO: should update on mutation.
|
let objectComposition = this.openmct.composition.get(this.node.object);
|
||||||
// TODO: click navigation should not fubar hash quite so much.
|
|
||||||
// TODO: should highlight if navigated to.
|
this.$emit('childState', {
|
||||||
// TODO: should have context menu.
|
type: 'mounted',
|
||||||
// TODO: should support drag/drop composition
|
id: this.openmct.objects.makeKeyString(this.node.object.identifier),
|
||||||
// TODO: set isAlias per tree-item
|
name: this.node.object.name
|
||||||
|
});
|
||||||
|
|
||||||
this.domainObject = this.node.object;
|
this.domainObject = this.node.object;
|
||||||
let removeListener = this.openmct.objects.observe(this.domainObject, '*', (newObject) => {
|
let removeListener = this.openmct.objects.observe(this.domainObject, '*', (newObject) => {
|
||||||
@ -105,7 +203,7 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.$once('hook:destroyed', removeListener);
|
this.$once('hook:destroyed', removeListener);
|
||||||
if (this.openmct.composition.get(this.node.object)) {
|
if (objectComposition && objectComposition.domainObject.composition.length > 0) {
|
||||||
this.hasChildren = true;
|
this.hasChildren = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,8 +219,14 @@ export default {
|
|||||||
*****/
|
*****/
|
||||||
this.expanded = false;
|
this.expanded = false;
|
||||||
this.setLocalStorageExpanded();
|
this.setLocalStorageExpanded();
|
||||||
|
this.activeChild = undefined;
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
|
this.$emit('childState', {
|
||||||
|
type: 'destroyed',
|
||||||
|
id: this.openmct.objects.makeKeyString(this.domainObject.identifier),
|
||||||
|
name: this.domainObject.name
|
||||||
|
});
|
||||||
this.openmct.router.off('change:path', this.highlightIfNavigated);
|
this.openmct.router.off('change:path', this.highlightIfNavigated);
|
||||||
if (this.composition) {
|
if (this.composition) {
|
||||||
this.composition.off('add', this.addChild);
|
this.composition.off('add', this.addChild);
|
||||||
@ -144,9 +248,26 @@ export default {
|
|||||||
this.children = this.children
|
this.children = this.children
|
||||||
.filter(c => c.id !== removeId);
|
.filter(c => c.id !== removeId);
|
||||||
},
|
},
|
||||||
|
loadChildren() {
|
||||||
|
if (!this.loaded && !this.isLoading) {
|
||||||
|
this.composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
this.composition.on('add', this.addChild);
|
||||||
|
this.composition.on('remove', this.removeChild);
|
||||||
|
this.composition.load().then(this.finishLoading);
|
||||||
|
this.isLoading = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
finishLoading() {
|
finishLoading() {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
// specifically for sync child loading
|
||||||
|
for(let callback of this.onChildrenLoaded) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
this.onChildrenLoaded = [];
|
||||||
|
},
|
||||||
|
triggerChildrenSyncCheck() {
|
||||||
|
this.triggerChildSync = this.makeHash();
|
||||||
},
|
},
|
||||||
buildPathString(parentPath) {
|
buildPathString(parentPath) {
|
||||||
return [parentPath, this.openmct.objects.makeKeyString(this.node.object.identifier)].join('/');
|
return [parentPath, this.openmct.objects.makeKeyString(this.node.object.identifier)].join('/');
|
||||||
@ -160,7 +281,6 @@ export default {
|
|||||||
},
|
},
|
||||||
getLocalStorageExpanded() {
|
getLocalStorageExpanded() {
|
||||||
let expandedPaths = localStorage.getItem(LOCAL_STORAGE_KEY__TREE_EXPANDED);
|
let expandedPaths = localStorage.getItem(LOCAL_STORAGE_KEY__TREE_EXPANDED);
|
||||||
|
|
||||||
if (expandedPaths) {
|
if (expandedPaths) {
|
||||||
expandedPaths = JSON.parse(expandedPaths);
|
expandedPaths = JSON.parse(expandedPaths);
|
||||||
this.expanded = expandedPaths.includes(this.navigateToPath);
|
this.expanded = expandedPaths.includes(this.navigateToPath);
|
||||||
@ -170,7 +290,6 @@ export default {
|
|||||||
setLocalStorageExpanded() {
|
setLocalStorageExpanded() {
|
||||||
let expandedPaths = localStorage.getItem(LOCAL_STORAGE_KEY__TREE_EXPANDED);
|
let expandedPaths = localStorage.getItem(LOCAL_STORAGE_KEY__TREE_EXPANDED);
|
||||||
expandedPaths = expandedPaths ? JSON.parse(expandedPaths) : [];
|
expandedPaths = expandedPaths ? JSON.parse(expandedPaths) : [];
|
||||||
|
|
||||||
if (this.expanded) {
|
if (this.expanded) {
|
||||||
if (!expandedPaths.includes(this.navigateToPath)) {
|
if (!expandedPaths.includes(this.navigateToPath)) {
|
||||||
expandedPaths.push(this.navigateToPath);
|
expandedPaths.push(this.navigateToPath);
|
||||||
@ -187,6 +306,39 @@ export default {
|
|||||||
expandedPaths = expandedPaths ? JSON.parse(expandedPaths) : [];
|
expandedPaths = expandedPaths ? JSON.parse(expandedPaths) : [];
|
||||||
expandedPaths = expandedPaths.filter(path => !path.startsWith(this.navigateToPath));
|
expandedPaths = expandedPaths.filter(path => !path.startsWith(this.navigateToPath));
|
||||||
localStorage.setItem(LOCAL_STORAGE_KEY__TREE_EXPANDED, JSON.stringify(expandedPaths));
|
localStorage.setItem(LOCAL_STORAGE_KEY__TREE_EXPANDED, JSON.stringify(expandedPaths));
|
||||||
|
},
|
||||||
|
handleExpanded(expandedObject) {
|
||||||
|
this.activeChild = this.openmct.objects.makeKeyString(expandedObject.identifier);
|
||||||
|
this.childrenSlideClass = SLIDE_LEFT;
|
||||||
|
},
|
||||||
|
handleChildState(opts) {
|
||||||
|
if(opts.type === 'mounted') {
|
||||||
|
this.mountedChildren.push(opts.id);
|
||||||
|
if(this.onChildMounted.length && this.onChildMounted[0].child === opts.id) {
|
||||||
|
this.onChildMounted[0].callback();
|
||||||
|
this.onChildMounted = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(this.mountedChildren.includes(opts.id)) {
|
||||||
|
let removeIndex = this.mountedChildren.indexOf(opts.id);
|
||||||
|
this.mountedChildren.splice(removeIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetTreeHere() {
|
||||||
|
this.childrenSlideClass = SLIDE_RIGHT;
|
||||||
|
this.activeChild = undefined;
|
||||||
|
this.collapseMyChildren = this.makeHash();
|
||||||
|
this.expanded = true;
|
||||||
|
},
|
||||||
|
makeHash(length = 20) {
|
||||||
|
let hash = String(Date.now()),
|
||||||
|
characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
length -= hash.length;
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
hash += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user