mirror of
https://github.com/nasa/openmct.git
synced 2025-07-01 12:58:56 +00:00
Compare commits
4 Commits
fix-lint-e
...
new-tree-i
Author | SHA1 | Date | |
---|---|---|---|
55e9cafbef | |||
8cd91061f7 | |||
fab8bb516a | |||
6d526eaf42 |
@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global module,BUILD_CONSTANTS*/
|
||||
/*global module*/
|
||||
|
||||
const matcher = /\/openmct.js$/;
|
||||
if (document.currentScript) {
|
||||
|
@ -32,14 +32,6 @@ define(
|
||||
mockPromise,
|
||||
handler;
|
||||
|
||||
function asPromise(value) {
|
||||
return (value || {}).then ? value : {
|
||||
then: function (callback) {
|
||||
return asPromise(callback(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function makeMockFailure(id, index) {
|
||||
var mockFailure = jasmine.createSpyObj(
|
||||
'failure-' + id,
|
||||
|
@ -29,7 +29,7 @@ define([
|
||||
GenericSearchProvider
|
||||
) {
|
||||
|
||||
describe('GenericSearchProvider', function () {
|
||||
xdescribe('GenericSearchProvider', function () {
|
||||
var $q,
|
||||
$log,
|
||||
modelService,
|
||||
|
10
src/MCT.js
10
src/MCT.js
@ -95,12 +95,15 @@ define([
|
||||
*/
|
||||
function MCT() {
|
||||
EventEmitter.call(this);
|
||||
/* eslint-disable no-undef */
|
||||
this.buildInfo = {
|
||||
version: __OPENMCT_VERSION__,
|
||||
buildDate: __OPENMCT_BUILD_DATE__,
|
||||
revision: __OPENMCT_REVISION__,
|
||||
branch: __OPENMCT_BUILD_BRANCH__
|
||||
};
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
|
||||
this.legacyBundle = { extensions: {
|
||||
services: [
|
||||
@ -260,10 +263,6 @@ define([
|
||||
this.install(this.plugins.Tabs());
|
||||
this.install(this.plugins.FlexibleLayout());
|
||||
this.install(this.plugins.GoToOriginalAction());
|
||||
|
||||
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
||||
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
||||
}
|
||||
}
|
||||
|
||||
MCT.prototype = Object.create(EventEmitter.prototype);
|
||||
@ -375,7 +374,8 @@ define([
|
||||
* @event start
|
||||
* @memberof module:openmct.MCT~
|
||||
*/
|
||||
var startPromise = new Main().run(this)
|
||||
const startPromise = new Main()
|
||||
startPromise.run(this)
|
||||
.then(function (angular) {
|
||||
this.$angular = angular;
|
||||
// OpenMCT Object provider doesn't operate properly unless
|
||||
|
@ -3,17 +3,6 @@ define([
|
||||
], function (
|
||||
|
||||
) {
|
||||
const DEFAULT_VIEW_PRIORITY = 100;
|
||||
|
||||
const PRIORITY_LEVELS = {
|
||||
"fallback": Number.NEGATIVE_INFINITY,
|
||||
"default": -100,
|
||||
"none": 0,
|
||||
"optional": DEFAULT_VIEW_PRIORITY,
|
||||
"preferred": 1000,
|
||||
"mandatory": Number.POSITIVE_INFINITY
|
||||
};
|
||||
|
||||
function TypeInspectorViewProvider(typeDefinition, openmct, convertToLegacyObject) {
|
||||
console.warn(`DEPRECATION WARNING: Migrate ${typeDefinition.key} from ${typeDefinition.bundle.path} to use the new Inspector View APIs. Legacy Inspector view support will be removed soon.`);
|
||||
let representation = openmct.$injector.get('representations[]')
|
||||
|
@ -20,8 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([], function () {
|
||||
|
||||
define(['lodash'], function (_) {
|
||||
function DisplayLayoutToolbar(openmct) {
|
||||
return {
|
||||
name: "Display Layout Toolbar",
|
||||
@ -40,7 +39,7 @@ define([], function () {
|
||||
return (selectedParent && selectedParent.context.item && selectedParent.context.item.type === 'layout') ||
|
||||
(selectedObject.context.item && selectedObject.context.item.type === 'layout');
|
||||
},
|
||||
toolbar: function (selection) {
|
||||
toolbar: function (selectedObjects) {
|
||||
const DIALOG_FORM = {
|
||||
'text': {
|
||||
name: "Text Element Properties",
|
||||
@ -222,7 +221,7 @@ define([], function () {
|
||||
}
|
||||
],
|
||||
method: function (option) {
|
||||
selectionPath[1].context.orderItem(option.value, getAllTypes(selection));
|
||||
selectionPath[1].context.orderItem(option.value, getAllTypes(selectedObjects));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -441,11 +440,11 @@ define([], function () {
|
||||
return {
|
||||
control: "select-menu",
|
||||
domainObject: selectionPath[1].context.item,
|
||||
applicableSelectedItems: selection.filter(selectionPath => {
|
||||
return selectionPath[0].context.layoutItem.type === 'telemetry-view';
|
||||
applicableSelectedItems: selection.filter(path => {
|
||||
return path[0].context.layoutItem.type === 'telemetry-view';
|
||||
}),
|
||||
property: function (selectionPath) {
|
||||
return getPath(selectionPath) + ".value";
|
||||
property: function (path) {
|
||||
return getPath(path) + ".value";
|
||||
},
|
||||
title: "Set value",
|
||||
options: openmct.telemetry.getMetadata(selectionPath[0].context.item).values().map(value => {
|
||||
@ -500,8 +499,8 @@ define([], function () {
|
||||
!selectionPath[0].context.layoutItem;
|
||||
}
|
||||
|
||||
if (isMainLayoutSelected(selection[0])) {
|
||||
return [getAddButton(selection)];
|
||||
if (isMainLayoutSelected(selectedObjects[0])) {
|
||||
return [getAddButton(selectedObjects)];
|
||||
}
|
||||
|
||||
let toolbar = {
|
||||
@ -517,145 +516,145 @@ define([], function () {
|
||||
'remove': []
|
||||
};
|
||||
|
||||
selection.forEach(selectionPath => {
|
||||
selectedObjects.forEach(selectionPath => {
|
||||
let selectedParent = selectionPath[1].context.item;
|
||||
let layoutItem = selectionPath[0].context.layoutItem;
|
||||
|
||||
if (layoutItem.type === 'subobject-view') {
|
||||
if (toolbar['add-menu'].length === 0 && selectionPath[0].context.item.type === 'layout') {
|
||||
toolbar['add-menu'] = [getAddButton(selection, selectionPath)];
|
||||
toolbar['add-menu'] = [getAddButton(selectedObjects, selectionPath)];
|
||||
}
|
||||
if (toolbar['toggle-frame'].length === 0) {
|
||||
toolbar['toggle-frame'] = [getToggleFrameButton(selectedParent, selection)];
|
||||
toolbar['toggle-frame'] = [getToggleFrameButton(selectedParent, selectedObjects)];
|
||||
}
|
||||
if (toolbar.position.length === 0) {
|
||||
toolbar.position = [
|
||||
getStackOrder(selectedParent, selectionPath),
|
||||
getXInput(selectedParent, selection),
|
||||
getYInput(selectedParent, selection),
|
||||
getHeightInput(selectedParent, selection),
|
||||
getWidthInput(selectedParent, selection)
|
||||
getXInput(selectedParent, selectedObjects),
|
||||
getYInput(selectedParent, selectedObjects),
|
||||
getHeightInput(selectedParent, selectedObjects),
|
||||
getWidthInput(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.remove.length === 0) {
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selection)];
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||
}
|
||||
} else if (layoutItem.type === 'telemetry-view') {
|
||||
if (toolbar['display-mode'].length === 0) {
|
||||
toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selection)];
|
||||
toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selectedObjects)];
|
||||
}
|
||||
if (toolbar['telemetry-value'].length === 0) {
|
||||
toolbar['telemetry-value'] = [getTelemetryValueMenu(selectionPath, selection)];
|
||||
toolbar['telemetry-value'] = [getTelemetryValueMenu(selectionPath, selectedObjects)];
|
||||
}
|
||||
if (toolbar.style.length < 2) {
|
||||
toolbar.style = [
|
||||
getFillMenu(selectedParent, selection),
|
||||
getStrokeMenu(selectedParent, selection)
|
||||
getFillMenu(selectedParent, selectedObjects),
|
||||
getStrokeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar['text-style'].length === 0) {
|
||||
toolbar['text-style'] = [
|
||||
getTextColorMenu(selectedParent, selection),
|
||||
getTextSizeMenu(selectedParent, selection)
|
||||
getTextColorMenu(selectedParent, selectedObjects),
|
||||
getTextSizeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.position.length === 0) {
|
||||
toolbar.position = [
|
||||
getStackOrder(selectedParent, selectionPath),
|
||||
getXInput(selectedParent, selection),
|
||||
getYInput(selectedParent, selection),
|
||||
getHeightInput(selectedParent, selection),
|
||||
getWidthInput(selectedParent, selection)
|
||||
getXInput(selectedParent, selectedObjects),
|
||||
getYInput(selectedParent, selectedObjects),
|
||||
getHeightInput(selectedParent, selectedObjects),
|
||||
getWidthInput(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.remove.length === 0) {
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selection)];
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||
}
|
||||
} else if (layoutItem.type === 'text-view') {
|
||||
if (toolbar.style.length < 2) {
|
||||
toolbar.style = [
|
||||
getFillMenu(selectedParent, selection),
|
||||
getStrokeMenu(selectedParent, selection)
|
||||
getFillMenu(selectedParent, selectedObjects),
|
||||
getStrokeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar['text-style'].length === 0) {
|
||||
toolbar['text-style'] = [
|
||||
getTextColorMenu(selectedParent, selection),
|
||||
getTextSizeMenu(selectedParent, selection)
|
||||
getTextColorMenu(selectedParent, selectedObjects),
|
||||
getTextSizeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.position.length === 0) {
|
||||
toolbar.position = [
|
||||
getStackOrder(selectedParent, selectionPath),
|
||||
getXInput(selectedParent, selection),
|
||||
getYInput(selectedParent, selection),
|
||||
getHeightInput(selectedParent, selection),
|
||||
getWidthInput(selectedParent, selection)
|
||||
getXInput(selectedParent, selectedObjects),
|
||||
getYInput(selectedParent, selectedObjects),
|
||||
getHeightInput(selectedParent, selectedObjects),
|
||||
getWidthInput(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.text.length === 0) {
|
||||
toolbar.text = [getTextButton(selectedParent, selection)];
|
||||
toolbar.text = [getTextButton(selectedParent, selectedObjects)];
|
||||
}
|
||||
if (toolbar.remove.length === 0) {
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selection)];
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||
}
|
||||
} else if (layoutItem.type === 'box-view') {
|
||||
if (toolbar.style.length < 2) {
|
||||
toolbar.style = [
|
||||
getFillMenu(selectedParent, selection),
|
||||
getStrokeMenu(selectedParent, selection)
|
||||
getFillMenu(selectedParent, selectedObjects),
|
||||
getStrokeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.position.length === 0) {
|
||||
toolbar.position = [
|
||||
getStackOrder(selectedParent, selectionPath),
|
||||
getXInput(selectedParent, selection),
|
||||
getYInput(selectedParent, selection),
|
||||
getHeightInput(selectedParent, selection),
|
||||
getWidthInput(selectedParent, selection)
|
||||
getXInput(selectedParent, selectedObjects),
|
||||
getYInput(selectedParent, selectedObjects),
|
||||
getHeightInput(selectedParent, selectedObjects),
|
||||
getWidthInput(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.remove.length === 0) {
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selection)];
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||
}
|
||||
} else if (layoutItem.type === 'image-view') {
|
||||
if (toolbar.style.length === 0) {
|
||||
toolbar.style = [
|
||||
getStrokeMenu(selectedParent, selection)
|
||||
getStrokeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.position.length === 0) {
|
||||
toolbar.position = [
|
||||
getStackOrder(selectedParent, selectionPath),
|
||||
getXInput(selectedParent, selection),
|
||||
getYInput(selectedParent, selection),
|
||||
getHeightInput(selectedParent, selection),
|
||||
getWidthInput(selectedParent, selection)
|
||||
getXInput(selectedParent, selectedObjects),
|
||||
getYInput(selectedParent, selectedObjects),
|
||||
getHeightInput(selectedParent, selectedObjects),
|
||||
getWidthInput(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.url.length === 0) {
|
||||
toolbar.url = [getURLButton(selectedParent, selection)];
|
||||
toolbar.url = [getURLButton(selectedParent, selectedObjects)];
|
||||
}
|
||||
if (toolbar.remove.length === 0) {
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selection)];
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||
}
|
||||
} else if (layoutItem.type === 'line-view') {
|
||||
if (toolbar.style.length === 0) {
|
||||
toolbar.style = [
|
||||
getStrokeMenu(selectedParent, selection)
|
||||
getStrokeMenu(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.position.length === 0) {
|
||||
toolbar.position = [
|
||||
getStackOrder(selectedParent, selectionPath),
|
||||
getXInput(selectedParent, selection),
|
||||
getYInput(selectedParent, selection),
|
||||
getX2Input(selectedParent, selection),
|
||||
getY2Input(selectedParent, selection)
|
||||
getXInput(selectedParent, selectedObjects),
|
||||
getYInput(selectedParent, selectedObjects),
|
||||
getX2Input(selectedParent, selectedObjects),
|
||||
getY2Input(selectedParent, selectedObjects)
|
||||
];
|
||||
}
|
||||
if (toolbar.remove.length === 0) {
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selection)];
|
||||
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -83,7 +83,7 @@ function (
|
||||
mounted: self.focusOnEntry
|
||||
};
|
||||
|
||||
var notebookVue = Vue.extend({
|
||||
var NotebookVue = Vue.extend({
|
||||
template: NotebookTemplate,
|
||||
provide: {openmct: self.openmct, domainObject: self.domainObject},
|
||||
components: {
|
||||
@ -114,7 +114,7 @@ function (
|
||||
}
|
||||
});
|
||||
|
||||
this.NotebookVue = new notebookVue();
|
||||
this.NotebookVue = new NotebookVue();
|
||||
container.appendChild(this.NotebookVue.$mount().$el);
|
||||
};
|
||||
|
||||
|
@ -63,10 +63,10 @@ define([
|
||||
|
||||
Object.keys(panels).forEach(key => {
|
||||
let panel = panels[key];
|
||||
let domainObject = childObjects[key];
|
||||
let childDomainObject = childObjects[key];
|
||||
let identifier = undefined;
|
||||
|
||||
if (isTelemetry(domainObject)) {
|
||||
if (isTelemetry(childDomainObject)) {
|
||||
// If object is a telemetry point, convert it to a plot and
|
||||
// replace the object in migratedObject composition with the plot.
|
||||
identifier = {
|
||||
@ -75,19 +75,19 @@ define([
|
||||
};
|
||||
let plotObject = {
|
||||
identifier: identifier,
|
||||
location: domainObject.location,
|
||||
name: domainObject.name,
|
||||
location: childDomainObject.location,
|
||||
name: childDomainObject.name,
|
||||
type: "telemetry.plot.overlay"
|
||||
};
|
||||
let plotType = openmct.types.get('telemetry.plot.overlay');
|
||||
plotType.definition.initialize(plotObject);
|
||||
plotObject.composition.push(domainObject.identifier);
|
||||
plotObject.composition.push(childDomainObject.identifier);
|
||||
openmct.objects.mutate(plotObject, 'persisted', Date.now());
|
||||
|
||||
let keyString = openmct.objects.makeKeyString(domainObject.identifier);
|
||||
let keyString = openmct.objects.makeKeyString(childDomainObject.identifier);
|
||||
let clonedComposition = Object.assign([], migratedObject.composition);
|
||||
clonedComposition.forEach((identifier, index) => {
|
||||
if (openmct.objects.makeKeyString(identifier) === keyString) {
|
||||
clonedComposition.forEach((objIdentifier, index) => {
|
||||
if (openmct.objects.makeKeyString(objIdentifier) === keyString) {
|
||||
migratedObject.composition[index] = plotObject.identifier;
|
||||
}
|
||||
});
|
||||
@ -98,7 +98,7 @@ define([
|
||||
height: panel.dimensions[1],
|
||||
x: panel.position[0],
|
||||
y: panel.position[1],
|
||||
identifier: identifier || domainObject.identifier,
|
||||
identifier: identifier || childDomainObject.identifier,
|
||||
id: uuid(),
|
||||
type: 'subobject-view',
|
||||
hasFrame: panel.hasFrame
|
||||
|
@ -214,11 +214,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gl-plot-axis-area gl-plot-x"
|
||||
ng-style="{
|
||||
left: (tickWidth - 30) + 'px'
|
||||
}">
|
||||
|
||||
<div class="gl-plot-axis-area gl-plot-x">
|
||||
<mct-ticks axis="xAxis">
|
||||
<div ng-repeat="tick in ticks track by tick.value"
|
||||
class="gl-plot-tick gl-plot-x-tick-label"
|
||||
|
@ -140,7 +140,7 @@ define([
|
||||
* @returns {Promise}
|
||||
*/
|
||||
fetch: function (options) {
|
||||
const strategy = options.shouldUseMinMax ? 'minMax' : undefined;
|
||||
const strategy = options.shouldUseMinMax ? 'minMax' : undefined;
|
||||
options = _.extend({}, { size: 1000, strategy, filters: this.filters }, options || {});
|
||||
if (!this.unsubscribe) {
|
||||
this.unsubscribe = this.openmct
|
||||
|
@ -31,6 +31,7 @@ define([
|
||||
var XAxisModel = Model.extend({
|
||||
initialize: function (options) {
|
||||
this.plot = options.plot;
|
||||
this.set('label', options.model.name || '');
|
||||
this.on('change:range', function (newValue, oldValue, model) {
|
||||
if (!model.get('frozen')) {
|
||||
model.set('displayRange', newValue);
|
||||
|
@ -138,7 +138,7 @@ define([
|
||||
this.listenTo(series, 'change:interpolate', function () {
|
||||
this.loadSeriesData(series);
|
||||
}, this);
|
||||
|
||||
|
||||
this.loadSeriesData(series);
|
||||
};
|
||||
|
||||
|
@ -215,9 +215,7 @@ define([
|
||||
* Update the widget's appearance from the configuration of the active rule
|
||||
*/
|
||||
SummaryWidget.prototype.updateWidget = function () {
|
||||
const WIDGET_CLASS = 'c-sw js-sw',
|
||||
WIDGET_LABEL_CLASS = 'c-sw__label js-sw__label',
|
||||
WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
|
||||
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
|
||||
var activeRule = this.rulesById[this.activeId];
|
||||
this.applyStyle($('#widget', this.domElement), activeRule.getProperty('style'));
|
||||
$('#widget', this.domElement).prop('title', activeRule.getProperty('message'));
|
||||
|
@ -86,7 +86,7 @@ define(
|
||||
*/
|
||||
matchesFilters(row) {
|
||||
let doesMatchFilters = true;
|
||||
for (const key in this.columnFilters) {
|
||||
Object.keys(this.columnFilters).forEach((key) => {
|
||||
if (!doesMatchFilters || !this.rowHasColumn(row, key)) {
|
||||
return false;
|
||||
}
|
||||
@ -97,8 +97,7 @@ define(
|
||||
}
|
||||
|
||||
doesMatchFilters = formattedValue.toLowerCase().indexOf(this.columnFilters[key]) !== -1;
|
||||
}
|
||||
|
||||
});
|
||||
return doesMatchFilters;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ $tabularTdPadTB: 2px;
|
||||
$plotYBarW: 60px;
|
||||
$plotYLabelMinH: 20px;
|
||||
$plotYLabelW: 10px;
|
||||
$plotXBarH: 20px;
|
||||
$plotXBarH: 35px;
|
||||
$plotLegendH: 20px;
|
||||
$plotSwatchD: 8px;
|
||||
$plotDisplayArea: (0, 0, $plotXBarH, $plotYBarW); // 1: Top, 2: right, 3: bottom, 4: left
|
||||
|
@ -301,7 +301,7 @@
|
||||
|
||||
<script>
|
||||
import Inspector from '../inspector/Inspector.vue';
|
||||
import MctTree from './mct-tree.vue';
|
||||
import MctTree from './mct-tree-prototype.vue';
|
||||
import ObjectView from '../components/ObjectView.vue';
|
||||
import MctTemplate from '../legacy/mct-template.vue';
|
||||
import CreateButton from './CreateButton.vue';
|
||||
|
374
src/ui/layout/mct-tree-prototype.vue
Normal file
374
src/ui/layout/mct-tree-prototype.vue
Normal file
@ -0,0 +1,374 @@
|
||||
<template>
|
||||
<div class="c-tree-and-search">
|
||||
<div class="c-tree-and-search__search">
|
||||
<search class="c-search" ref="shell-search"
|
||||
:value="searchValue"
|
||||
@input="searchTree"
|
||||
@clear="searchTree">
|
||||
</search>
|
||||
</div>
|
||||
|
||||
<!-- loading -->
|
||||
<div class="c-tree-and-search__loading loading"
|
||||
v-if="isLoading"></div>
|
||||
<!-- end loading -->
|
||||
|
||||
<!-- main tree -->
|
||||
<template v-if="parentNode && parentNode.id !== 'ROOT'">
|
||||
<tree-item
|
||||
:key="parentNode.id"
|
||||
:node="parentNode"
|
||||
:isExpanded="true"
|
||||
@notExpanded="navigateToParent">
|
||||
</tree-item>
|
||||
|
||||
<div style="min-width: 100%; height: 2px; background: rgb(201,201,201);"></div>
|
||||
</template>
|
||||
|
||||
<ul class="c-tree-and-search__tree c-tree"
|
||||
v-if="!isLoading"
|
||||
v-show="!searchValue"
|
||||
@scroll="scrollPage">
|
||||
|
||||
<tree-item
|
||||
v-for="treeItem in pagedChildren"
|
||||
:key="treeItem.id"
|
||||
:node="treeItem"
|
||||
@expanded="setParentAndLoadChildren">
|
||||
</tree-item>
|
||||
</ul>
|
||||
<!-- end main tree -->
|
||||
|
||||
<!-- search tree -->
|
||||
<ul class="c-tree-and-search__tree c-tree"
|
||||
v-if="searchValue">
|
||||
<tree-item v-for="treeItem in filteredTreeItems"
|
||||
:key="treeItem.id"
|
||||
:node="treeItem">
|
||||
</tree-item>
|
||||
</ul>
|
||||
<!-- end search tree -->
|
||||
|
||||
<div class="c-tree-and-search__no-results"
|
||||
v-if="(allTreeItems.length === 0) || (searchValue && filteredTreeItems.length === 0)">
|
||||
No results found
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-tree-and-search {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-right: $interiorMarginSm;
|
||||
overflow: auto;
|
||||
|
||||
> * + * { margin-top: $interiorMargin; }
|
||||
|
||||
&__search {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&__loading {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&__no-results {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&__tree {
|
||||
flex: 1 1 auto;
|
||||
height: 0; // Chrome 73 overflow bug fix
|
||||
}
|
||||
}
|
||||
|
||||
.c-tree {
|
||||
@include userSelectNone();
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-right: $interiorMargin;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
&.c-tree__item-h { display: block; }
|
||||
}
|
||||
|
||||
.c-tree {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
$aPad: $interiorMarginSm;
|
||||
border-radius: $controlCr;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
line-height: 110%;
|
||||
padding: $interiorMargin - $aPad;
|
||||
transition: background 150ms ease;
|
||||
|
||||
> * + * {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $colorItemTreeHoverBg;
|
||||
.c-tree__item__type-icon:before {
|
||||
color: $colorItemTreeIconHover;
|
||||
}
|
||||
|
||||
.c-tree__item__name {
|
||||
color: $colorItemTreeHoverFg;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-navigated-object,
|
||||
&.is-selected {
|
||||
background: $colorItemTreeSelectedBg;
|
||||
.c-tree__item__type-icon:before {
|
||||
color: $colorItemTreeIconHover;
|
||||
}
|
||||
|
||||
.c-tree__item__name {
|
||||
color: $colorItemTreeSelectedFg;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-being-edited {
|
||||
background: $colorItemTreeEditingBg;
|
||||
.c-tree__item__type-icon:before {
|
||||
color: $colorItemTreeEditingIcon;
|
||||
}
|
||||
|
||||
.c-tree__item__name {
|
||||
color: $colorItemTreeEditingFg;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
// Object labels in trees
|
||||
&__label {
|
||||
// <a> tag that holds type icon and name.
|
||||
// Draggable element.
|
||||
/*border-radius: $controlCr;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
padding: $aPad;
|
||||
white-space: nowrap;*/
|
||||
}
|
||||
|
||||
&__name {
|
||||
// @include ellipsize();
|
||||
// display: inline;
|
||||
color: $colorItemTreeFg;
|
||||
// width: 100%;
|
||||
}
|
||||
|
||||
&__type-icon {
|
||||
// Type icon. Must be an HTML entity to allow inclusion of alias indicator.
|
||||
// display: block;
|
||||
// flex: 0 0 auto;
|
||||
// font-size: 1.3em;
|
||||
// margin-right: $interiorMarginSm;
|
||||
color: $colorItemTreeIcon;
|
||||
// width: $treeTypeIconW;
|
||||
}
|
||||
|
||||
&.is-alias {
|
||||
// Object is an alias to an original.
|
||||
[class*='__type-icon'] {
|
||||
@include isAlias();
|
||||
}
|
||||
}
|
||||
|
||||
body.mobile & {
|
||||
@include button($bg: $colorMobilePaneLeftTreeItemBg, $fg: $colorMobilePaneLeftTreeItemFg);
|
||||
height: $mobileTreeItemH;
|
||||
margin-bottom: $interiorMarginSm;
|
||||
[class*="view-control"] {
|
||||
width: ceil($mobileTreeItemH * 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import treeItem from './tree-item-prototype.vue'
|
||||
import search from '../components/search.vue';
|
||||
|
||||
const PAGE_THRESHOLD = 50;
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
name: 'mct-tree',
|
||||
components: {
|
||||
search,
|
||||
treeItem
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchValue: '',
|
||||
allTreeItems: [],
|
||||
filteredTreeItems: [],
|
||||
isLoading: false,
|
||||
currentObjectPath: [],
|
||||
parentNode: undefined,
|
||||
page: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pagedChildren() {
|
||||
if (this.allTreeItems.length > PAGE_THRESHOLD) {
|
||||
let maxIndex = this.page * PAGE_THRESHOLD,
|
||||
minIndex = maxIndex - PAGE_THRESHOLD;
|
||||
|
||||
return this.allTreeItems.slice(minIndex, maxIndex);
|
||||
} else {
|
||||
return this.allTreeItems;
|
||||
}
|
||||
},
|
||||
lastPage() {
|
||||
return Math.floor(this.allTreeItems.length / PAGE_THRESHOLD);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getRootChildren() {
|
||||
this.openmct.objects.get('ROOT')
|
||||
.then(root => {
|
||||
let rootNode = this.buildTreeItems(root);
|
||||
this.getAllChildren(rootNode);
|
||||
})
|
||||
},
|
||||
getAllChildren(node) {
|
||||
this.isLoading = true;
|
||||
|
||||
if (this.composition) {
|
||||
this.composition.off('add', this.addChild);
|
||||
this.composition.off('remove', this.removeChild);
|
||||
delete this.composition;
|
||||
}
|
||||
|
||||
this.parentNode = node;
|
||||
this.currentObjectPath = this.parentNode.objectPath;
|
||||
this.allTreeItems = [];
|
||||
|
||||
this.composition = this.openmct.composition.get(node.object);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load().then(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
buildTreeItems(domainObject) {
|
||||
return {
|
||||
id: this.openmct.objects.makeKeyString(domainObject.identifier),
|
||||
object: domainObject,
|
||||
objectPath: [domainObject].concat(this.currentObjectPath),
|
||||
navigateToParent: '/browse'
|
||||
};
|
||||
},
|
||||
getFilteredChildren() {
|
||||
this.searchService.query(this.searchValue).then(children => {
|
||||
this.filteredTreeItems = children.hits.map(child => {
|
||||
|
||||
let context = child.object.getCapability('context'),
|
||||
object = child.object.useCapability('adapter'),
|
||||
objectPath = [],
|
||||
navigateToParent;
|
||||
|
||||
if (context) {
|
||||
objectPath = context.getPath().slice(1)
|
||||
.map(oldObject => oldObject.useCapability('adapter'))
|
||||
.reverse();
|
||||
navigateToParent = '/browse/' + objectPath.slice(1)
|
||||
.map((parent) => this.openmct.objects.makeKeyString(parent.identifier))
|
||||
.join('/');
|
||||
}
|
||||
|
||||
return {
|
||||
id: this.openmct.objects.makeKeyString(object.identifier),
|
||||
object,
|
||||
objectPath,
|
||||
navigateToParent
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
searchTree(value) {
|
||||
this.searchValue = value;
|
||||
|
||||
if (this.searchValue !== '') {
|
||||
this.getFilteredChildren();
|
||||
}
|
||||
},
|
||||
buildPathString(parentPath) {
|
||||
return [parentPath, this.parentNode.id].join('/');
|
||||
},
|
||||
addChild (child) {
|
||||
this.allTreeItems.push(this.buildTreeItems(child));
|
||||
},
|
||||
removeChild(identifier) {
|
||||
let removeId = this.openmct.objects.makeKeyString(identifier);
|
||||
this.allChildren = this.children
|
||||
.filter(c => c.id !== removeId);
|
||||
},
|
||||
navigateToParent(node) {
|
||||
let parentDomainObject = node.objectPath[1],
|
||||
parentNode = {
|
||||
id: this.openmct.objects.makeKeyString(parentDomainObject.identifier),
|
||||
object: parentDomainObject,
|
||||
objectPath: node.objectPath.slice(1),
|
||||
navigateToParent: '/browse'
|
||||
}
|
||||
|
||||
this.getAllChildren(parentNode);
|
||||
},
|
||||
setParentAndLoadChildren(node){
|
||||
this.getAllChildren(node);
|
||||
},
|
||||
nextPage() {
|
||||
if (this.page < this.lastPage) {
|
||||
this.page += 1;
|
||||
}
|
||||
},
|
||||
previousPage() {
|
||||
if (this.page >= 1) {
|
||||
this.page -= 1;
|
||||
}
|
||||
},
|
||||
scrollPage(event) {
|
||||
let offsetHeight = event.target.offsetHeight,
|
||||
scrollHeight = event.target.scrollHeight,
|
||||
scrollTop = event.target.scrollTop,
|
||||
changePage = true;
|
||||
|
||||
if (scrollTop + offsetHeight === scrollHeight) {
|
||||
this.scrollLoading = window.setTimeout(() => {
|
||||
if (this.page < this.lastPage) {
|
||||
this.nextPage();
|
||||
event.target.scrollTop = 1;
|
||||
}
|
||||
}, 500);
|
||||
} else if (scrollTop === 0) {
|
||||
this.scrollLoading = window.setTimeout(() => {
|
||||
if (this.page > 1) {
|
||||
this.previousPage();
|
||||
event.target.scrollTop = offsetHeight - 1;
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.searchService = this.openmct.$injector.get('searchService');
|
||||
this.getRootChildren();
|
||||
}
|
||||
}
|
||||
</script>
|
94
src/ui/layout/tree-item-prototype.vue
Normal file
94
src/ui/layout/tree-item-prototype.vue
Normal file
@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<li class="c-tree__item-h">
|
||||
<div class="c-tree__item"
|
||||
:class="{ 'is-alias': isAlias, 'is-navigated-object': isNavigated }">
|
||||
<view-control class="c-tree__item__view-control"
|
||||
:enabled="hasChildren"
|
||||
v-model="expanded">
|
||||
</view-control>
|
||||
<object-label :domainObject="node.object"
|
||||
:objectPath="node.objectPath"
|
||||
:navigateToPath="navigateToPath">
|
||||
</object-label>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import viewControl from '../components/viewControl.vue';
|
||||
import ObjectLabel from '../components/ObjectLabel.vue';
|
||||
|
||||
export default {
|
||||
name: 'tree-item',
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
node: Object,
|
||||
isExpanded: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.navigateToPath = this.buildPathString(this.node.navigateToParent)
|
||||
return {
|
||||
hasChildren: false,
|
||||
isLoading: false,
|
||||
loaded: false,
|
||||
isNavigated: this.navigateToPath === this.openmct.router.currentLocation.path,
|
||||
children: [],
|
||||
expanded: this.isExpanded
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isAlias() {
|
||||
let parent = this.node.objectPath[1];
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
let parentKeyString = this.openmct.objects.makeKeyString(parent.identifier);
|
||||
return parentKeyString !== this.node.object.location;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
expanded(isExpanded) {
|
||||
if (isExpanded) {
|
||||
this.$emit('expanded', this.node);
|
||||
} else {
|
||||
this.$emit('notExpanded', this.node);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.domainObject = this.node.object;
|
||||
let removeListener = this.openmct.objects.observe(this.domainObject, '*', (newObject) => {
|
||||
this.domainObject = newObject;
|
||||
});
|
||||
|
||||
this.$once('hook:destroyed', removeListener);
|
||||
if (this.openmct.composition.get(this.node.object)) {
|
||||
this.hasChildren = true;
|
||||
}
|
||||
|
||||
this.openmct.router.on('change:path', this.highlightIfNavigated);
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.router.off('change:path', this.highlightIfNavigated);
|
||||
},
|
||||
methods: {
|
||||
buildPathString(parentPath) {
|
||||
return [parentPath, this.openmct.objects.makeKeyString(this.node.object.identifier)].join('/');
|
||||
},
|
||||
highlightIfNavigated(newPath, oldPath){
|
||||
if (newPath === this.navigateToPath) {
|
||||
this.isNavigated = true;
|
||||
} else if (oldPath === this.navigateToPath) {
|
||||
this.isNavigated = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
viewControl,
|
||||
ObjectLabel
|
||||
}
|
||||
}
|
||||
</script>
|
@ -3,6 +3,7 @@
|
||||
Application router -- must
|
||||
|
||||
*/
|
||||
/*global _,module*/
|
||||
|
||||
const LocationBar = require('location-bar');
|
||||
const EventEmitter = require('EventEmitter');
|
||||
@ -117,7 +118,7 @@ class ApplicationRouter extends EventEmitter {
|
||||
changedParams[key] = value;
|
||||
}
|
||||
}
|
||||
for (let [key, value] of Object.entries(oldParams)) {
|
||||
for (let key of Object.keys(oldParams)) {
|
||||
if (!newParams.hasOwnProperty(key)) {
|
||||
changedParams[key] = undefined;
|
||||
}
|
||||
|
Reference in New Issue
Block a user