Compare commits

..

5 Commits

43 changed files with 1218 additions and 379 deletions

View File

@ -1,6 +1,6 @@
{
"name": "openmct",
"version": "1.6.3-SNAPSHOT",
"version": "1.7.1-SNAPSHOT",
"description": "The Open MCT core platform",
"dependencies": {},
"devDependencies": {

View File

@ -26,7 +26,6 @@ define([
"./src/controllers/EditObjectController",
"./src/actions/EditAndComposeAction",
"./src/actions/EditAction",
"./src/actions/PropertiesAction",
"./src/actions/SaveAction",
"./src/actions/SaveAndStopEditingAction",
"./src/actions/SaveAsAction",
@ -55,7 +54,6 @@ define([
EditObjectController,
EditAndComposeAction,
EditAction,
PropertiesAction,
SaveAction,
SaveAndStopEditingAction,
SaveAsAction,
@ -143,22 +141,6 @@ define([
"group": "action",
"priority": 10
},
{
"key": "properties",
"category": [
"contextual",
"view-control"
],
"implementation": PropertiesAction,
"cssClass": "major icon-pencil",
"name": "Edit Properties...",
"group": "action",
"priority": 10,
"description": "Edit properties of this object.",
"depends": [
"dialogService"
]
},
{
"key": "save-and-stop-editing",
"category": "save",

View File

@ -21,11 +21,11 @@
*****************************************************************************/
define([
'../creation/CreateWizard',
// '../creation/CreateWizard',
'./SaveInProgressDialog'
],
function (
CreateWizard,
// CreateWizard,
SaveInProgressDialog
) {
@ -100,7 +100,8 @@ function (
toUndirty = [];
function doWizardSave(parent) {
var wizard = self.createWizard(parent);
console.log('SaveAsAction');
// var wizard = self.createWizard(parent);
return self.dialogService
.getUserInput(wizard.getFormStructure(true),

View File

@ -252,6 +252,8 @@ define([
this.status = new api.StatusAPI(this);
this.forms = new api.FormsAPI.default(this);
this.router = new ApplicationRouter();
this.branding = BrandingAPI.default;
@ -284,7 +286,6 @@ define([
this.install(this.plugins.ViewDatumAction());
this.install(this.plugins.ObjectInterceptors());
this.install(this.plugins.NonEditableFolder());
this.install(this.plugins.Devices());
}
MCT.prototype = Object.create(EventEmitter.prototype);
@ -404,24 +405,39 @@ define([
this.router.setPath('/browse/');
});
if (!isHeadlessMode) {
const appLayout = new Vue({
components: {
'Layout': Layout.default
},
provide: {
openmct: this
},
template: '<Layout ref="layout"></Layout>'
});
domElement.appendChild(appLayout.$mount().$el);
/**
* Fired by [MCT]{@link module:openmct.MCT} when the application
* is started.
* @event start
* @memberof module:openmct.MCT~
*/
const startPromise = new Main();
startPromise.run(this)
.then(function (angular) {
this.$angular = angular;
// OpenMCT Object provider doesn't operate properly unless
// something has depended upon objectService. Cool, right?
this.$injector.get('objectService');
this.layout = appLayout.$refs.layout;
Browse(this);
}
if (!isHeadlessMode) {
const appLayout = new Vue({
components: {
'Layout': Layout.default
},
provide: {
openmct: this
},
template: '<Layout ref="layout"></Layout>'
});
domElement.appendChild(appLayout.$mount().$el);
this.router.start();
this.emit('start');
this.layout = appLayout.$refs.layout;
Browse(this);
}
this.router.start();
this.emit('start');
}.bind(this));
};
MCT.prototype.startHeadless = function () {

View File

@ -21,7 +21,7 @@
*****************************************************************************/
import _ from 'lodash';
const INSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "link", "locate", "move", "link"];
const OUTSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "properties", "move", "link", "remove", "locate"];
const OUTSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "move", "link", "remove", "locate"];
export default class LegacyContextMenuAction {
constructor(openmct, LegacyAction) {

View File

@ -21,41 +21,44 @@
*****************************************************************************/
define([
'./time/TimeAPI',
'./objects/ObjectAPI',
'./composition/CompositionAPI',
'./types/TypeRegistry',
'./telemetry/TelemetryAPI',
'./indicators/IndicatorAPI',
'./notifications/NotificationAPI',
'./Editor',
'./menu/MenuAPI',
'./actions/ActionsAPI',
'./status/StatusAPI'
'./composition/CompositionAPI',
'./Editor',
'./forms/FormsAPI',
'./indicators/IndicatorAPI',
'./menu/MenuAPI',
'./notifications/NotificationAPI',
'./objects/ObjectAPI',
'./status/StatusAPI',
'./telemetry/TelemetryAPI',
'./time/TimeAPI',
'./types/TypeRegistry'
], function (
TimeAPI,
ObjectAPI,
CompositionAPI,
TypeRegistry,
TelemetryAPI,
IndicatorAPI,
NotificationAPI,
EditorAPI,
MenuAPI,
ActionsAPI,
StatusAPI
CompositionAPI,
EditorAPI,
FormsAPI,
IndicatorAPI,
MenuAPI,
NotificationAPI,
ObjectAPI,
StatusAPI,
TelemetryAPI,
TimeAPI,
TypeRegistry
) {
return {
TimeAPI: TimeAPI,
ObjectAPI: ObjectAPI,
CompositionAPI: CompositionAPI,
TypeRegistry: TypeRegistry,
TelemetryAPI: TelemetryAPI,
IndicatorAPI: IndicatorAPI,
NotificationAPI: NotificationAPI.default,
EditorAPI: EditorAPI,
MenuAPI: MenuAPI.default,
ActionsAPI: ActionsAPI.default,
StatusAPI: StatusAPI.default
CompositionAPI: CompositionAPI,
EditorAPI: EditorAPI,
FormsAPI: FormsAPI,
IndicatorAPI: IndicatorAPI,
MenuAPI: MenuAPI.default,
NotificationAPI: NotificationAPI.default,
ObjectAPI: ObjectAPI,
StatusAPI: StatusAPI.default,
TelemetryAPI: TelemetryAPI,
TimeAPI: TimeAPI,
TypeRegistry: TypeRegistry,
};
});

View File

@ -0,0 +1,178 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* A class for capturing user input data from an object creation
* dialog, and populating a domain object with that data.
*
* @param {DomainObject} domainObject the newly created object to
* populate with user input
* @param {DomainObject} parent the domain object to serve as
* the initial parent for the created object, in the dialog
* @memberof platform/commonUI/browse
* @constructor
*/
export default class CreateWizard {
constructor(domainObject, parent, openmct) {
this.type = openmct.types.get(domainObject.type);
this.model = domainObject;
this.domainObject = domainObject;
this.properties = this.type.definition.form || [];
this.parent = parent;
this.openmct = openmct;
}
/**
* Get the form model for this wizard; this is a description
* that will be rendered to an HTML form. See the
* platform/forms bundle
* @param {boolean} includeLocation if true, a 'location' section
* will be included that will allow the user to select the location
* of the newly created object, otherwise the .location property of
* the model will be used.
* @return {FormModel} formModel the form model to
* show in the create dialog
*/
getFormStructure(includeLocation) {
let sections = [];
let domainObject = this.domainObject;
let self = this;
function validateLocation(parent) {
return parent && self.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
}
sections.push({
name: "Properties",
rows: this.properties.map(function (property, index) {
// Property definition is same as form row definition
let row = JSON.parse(JSON.stringify(property));
// Use index as the key into the formValue;
// this correlates to the indexing provided by
// getInitialFormValue
row.key = index;
return row;
}).filter(function (row) {
// Only show rows which have defined controls
return row && row.control;
})
});
// Ensure there is always a "save in" section
if (includeLocation) {
sections.push({
name: 'Location',
cssClass: "grows",
rows: [{
name: "Save In",
control: "locator",
validate: validateLocation.bind(this),
key: "createParent"
}]
});
}
return {
sections: sections,
name: "Create a New " + this.type.definition.name
};
}
/**
* Given some form input values and a domain object, populate the
* domain object used to create this wizard from the given form values.
* @param formValue
* @returns {DomainObject}
*/
populateObjectFromInput(formValue) {
let parent = this.getLocation(formValue);
let formModel = this.createModel(formValue);
formModel.location = parent.getId();
this.updateNamespaceFromParent(parent);
this.domainObject.useCapability("mutation", function () {
return formModel;
});
return this.domainObject;
}
updateNamespaceFromParent(parent) {
let childIdentifier = this.domainObject.useCapability('adapter').identifier;
let parentIdentifier = parent.useCapability('adapter').identifier;
childIdentifier.namespace = parentIdentifier.namespace;
this.domainObject.id = this.openmct.objects.makeKeyString(childIdentifier);
}
/**
* Get the initial value for the form being described.
* This will include the values for all properties described
* in the structure.
*
* @returns {object} the initial value of the form
*/
getInitialFormValue() {
// Start with initial values for properties
let model = this.model;
let formValue = this.properties.map(function (property) {
return property.getValue(model);
});
// Include the createParent
formValue.createParent = this.parent;
return formValue;
}
/**
* Based on a populated form, get the domain object which
* should be used as a parent for the newly-created object.
* @private
* @return {DomainObject}
*/
getLocation(formValue) {
return formValue.createParent || this.parent;
}
/**
* Create the domain object model for a newly-created object,
* based on user input read from a formModel.
* @private
* @return {object} the domain object model
*/
createModel(formValue) {
// Clone
let newModel = JSON.parse(JSON.stringify(this.domainObject));
// Update all properties
this.properties.forEach(function (property, index) {
property.setValue(newModel, formValue[index]);
});
return newModel;
}
}

View File

@ -19,13 +19,22 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import EditPropertiesAction from './actions/EditPropertiesAction';
export default function plugin() {
return function install(openmct) {
openmct.on('start', () => {
const body = document.getElementsByTagName('body')[0];
body.classList.add('desktop');
body.classList.add('portrait');
});
};
export default class FormsAPI {
constructor(openmct) {
openmct.actions.register(new EditPropertiesAction(openmct));
}
addControl(name, actions) {
// TODO:
}
showForm() {
}
save() {
}
}

View File

@ -0,0 +1,108 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* 'License'); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import PropertiesAction from './PropertiesAction';
import FormProperties from '../components/Form-properties.vue';
import CreateWizard from '../CreateWizard';
import Vue from "vue";
export default class CreateAction extends PropertiesAction {
constructor(openmct, key, parentDomainObject) {
super(openmct);
this.key = key;
this.parentDomainObject = parentDomainObject;
}
invoke() {
const definition = this._getTypeDefination(this.key);
console.log('CreateAction invoke, Show form', definition.form);
let newModel = {
type: this.key,
location: this.openmct.objects.makeKeyString(this.parentDomainObject.identifier)
};
if (definition.initialize) {
definition.initialize(newModel);
}
let openmct = this.openmct;
newModel.modified = Date.now();
let wizard = new CreateWizard(newModel, this.parentDomainObject, openmct);
let formStructure = wizard.getFormStructure(true);
// let initialFormValue = wizard.getInitialFormValue();
// if save navigateAndEdit
// this.openmct.editor.cancel();
this.showForm(formStructure);
}
showForm(formStructure) {
let vm = new Vue({
components: { FormProperties },
provide: {
openmct: this.openmct
},
data() {
return {
formStructure
};
},
template: '<form-properties :model="formStructure"></form-properties>'
}).$mount();
function dismissDialog(overlay, initialize) {
overlay.dismiss();
}
let overlay = this.openmct.overlays.overlay({
element: vm.$el, //TODO: create and show new form component
size: 'small',
buttons: [
{
label: 'OK',
emphasis: 'true',
callback: () => dismissDialog(overlay, true)
},
{
label: 'Cancel',
callback: () => dismissDialog(overlay, false)
}
],
onDestroy: () => vm.$destroy()
});
}
navigateAndEdit(object) {
let objectPath = object.getCapability('context').getPath();
let url = '#/browse/' + objectPath
.slice(1)
.map(function (o) {
return o && openmct.objects.makeKeyString(o.getId());
})
.join('/');
window.location.href = url;
if (isFirstViewEditable(object.useCapability('adapter'), objectPath)) {
openmct.editor.edit();
}
}
}

View File

@ -0,0 +1,73 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* 'License'); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import PropertiesAction from './PropertiesAction';
export default class EditPropertiesAction extends PropertiesAction {
constructor(openmct) {
super(openmct);
this.name = 'Edit Properties...';
this.key = 'properties';
this.description = 'Edit properties of this object.';
this.cssClass = 'major icon-pencil';
this.hideInDefaultMenu = true;
this.group= 'action';
this.priority= 10;
}
appliesTo(objectPath) {
return Boolean(this._getForm(objectPath));
}
invoke(objectPath) {
const formElements = this._getFormElements(objectPath);
// Start:Testing
const parent = document.createElement('div');
formElements.forEach(e => {
const child = document.createElement('div');
const spanKey = document.createElement('span');
const spanValue = document.createElement('span');
spanKey.textContent = e.key;
spanValue.textContent = e.value;
child.appendChild(spanKey);
child.appendChild(spanValue);
parent.appendChild(child);
});
// End:Testing
let overlay = this.openmct.overlays.overlay({
element: parent, //TODO: create and show new form component
size: 'small',
buttons: [
{
label: 'Done',
// TODO: save form values into domain object properties
callback: () => overlay.dismiss()
}
],
onDestroy: () => {
}
});
}
}

View File

@ -0,0 +1,91 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2021, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* 'License'); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
export default class PropertiesAction {
constructor(openmct) {
this.openmct = openmct;
}
invoke(objectPath) {
// Start:Testing
// const parent = document.createElement('div');
// formElements.forEach(e => {
// const child = document.createElement('div');
// const spanKey = document.createElement('span');
// const spanValue = document.createElement('span');
// spanKey.textContent = e.key;
// spanValue.textContent = e.value;
// child.appendChild(spanKey);
// child.appendChild(spanValue);
// parent.appendChild(child);
// });
// End:Testing
// let overlay = this.openmct.overlays.overlay({
// element: parent, //TODO: create and show new form component
// size: 'small',
// buttons: [
// {
// label: 'Done',
// // TODO: save form values into domain object properties
// callback: () => overlay.dismiss()
// }
// ],
// onDestroy: () => {
// }
// });
}
/**
* @private
*/
_getForm(objectPath) {
const definition = this._getTypeDefination(objectPath[0].type);
return definition.form;
}
/**
* @private
*/
_getFormElements(objectPath) {
const form = this._getForm(objectPath);
const domainObject = objectPath[0];
const formElements = [];
form.forEach(element => {
const value = element.property.reduce((acc, property) => acc[property], domainObject);
formElements.push({key: element.key, value});
});
return formElements;
}
/**
* @private
*/
_getTypeDefination(type) {
const TypeDefinition = this.openmct.types.get(type);
return TypeDefinition.definition;
}
}

View File

@ -0,0 +1,53 @@
<template>
<form name="mctForm"
novalidate
class="form c-form"
autocomplete="off"
>
<span v-for="section in model.sections"
:key="section.name"
class="l-form-section c-form__section"
:class="section.cssClass"
>
<h2 class="c-form__header"
ng-if="section.name"
>
{{ section.name }}
</h2>
<div v-for="(row, index) in section.rows"
:key="row.name"
>
<form-row :css-class="section.cssClass"
:first="index < 1"
:row="row"
/>
</div>
</span>
</form>
</template>
<script>
import FormRow from "@/api/forms/components/FormRow.vue";
export default {
components: {
FormRow
},
props: {
model: {
type: Object,
required: true
},
value: {
type: Object,
required: false,
default() {
return {};
}
}
},
mounted() {
console.log(this.model, this.value);
}
};
</script>

View File

@ -0,0 +1,115 @@
<template>
<div class="form-row c-form__row validates"
:class="rowClass"
>
<div class="c-form__row__label label flex-elem"
:title="row.description"
>
{{ row.name }}
</div>
<div class="c-form__row__controls controls flex-elem">
<div v-if="row.control && row.control !== 'locator'"
class="c-form__controls-wrapper wrapper"
>
<component
:is="row.control"
:key="row.key"
:ref="`form-control-${row.key}`"
:model="row"
:required="isRequired"
/>
</div>
</div>
</div>
</template>
<script>
import TextField from "@/api/forms/components/controls/TextField.vue";
import NumberField from "@/api/forms/components/controls/NumberField.vue";
import Composite from "@/api/forms/components/controls/Composite.vue";
import AutoCompleteField from "@/api/forms/components/controls/AutoCompleteField.vue";
const CONTROL_TYPE_VIEW_MAP = {
'textfield': TextField,
'numberfield': NumberField,
'composite': Composite,
'autocomplete': AutoCompleteField
};
export default {
name: 'FormRow',
components: CONTROL_TYPE_VIEW_MAP,
props: {
cssClass: {
type: String,
default: '',
required: true
},
first: {
type: Boolean,
default: false,
required: true
},
row: {
type: Object,
required: true
}
},
data() {
return {
valid: true
};
},
computed: {
isRequired() {
//TODO: Check if field is required
return false;
},
rowClass() {
let cssClass = this.cssClass;
if (this.first === true) {
cssClass = `${cssClass} first`;
}
if (this.row.required) {
cssClass = `${cssClass} req`;
}
if (this.row.layout === 'controls-first') {
cssClass = `${cssClass} l-controls-first`;
}
if (this.row.layout === 'controls-under') {
cssClass = `${cssClass} l-controls-under`;
}
if (this.valid === true) {
cssClass = `${cssClass} valid`;
} else {
cssClass = `${cssClass} invalid`;
}
return cssClass;
}
},
methods: {
// Check if an element is defined; the map step of isNonEmpty
isDefined(element) {
return typeof element !== 'undefined';
},
/**
* Check if an array contains anything other than
* undefined elements.
* @param {Array} value the array to check
* @returns {boolean} true if any non-undefined
* element is in the array
* @memberof platform/forms.CompositeController#
*/
isNonEmpty(value) {
return Array.isArray(value) && value.some(this.isDefined);
}
}
};
</script>

View File

@ -0,0 +1,172 @@
<!--
Open MCT, Copyright (c) 2014-2021, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<template>
<div class="form-control autocomplete">
<input v-model="field"
class="autocompleteInput"
type="text"
@change="filterOptions(field)"
@click="inputClicked()"
@keydown="keyDown($event)"
>
<span class="icon-arrow-down"
@click="arrowClicked()"
></span>
<div v-show="hideOptions"
class="autocompleteOptions"
@blur="hideOptions = true"
>
<ul>
<li v-for="opt in filteredOptions"
:key="opt.optionId"
:class="{'optionPreSelected': optionIndex === opt.optionId}"
@click="fillInput(opt.name)"
@mouseover="optionMouseover(opt.optionId)"
>
<span class="optionText">{{ opt.name }}</span>
</li>
</ul>
</div>
</div>
</template>
<script>
const key = {
down: 40,
up: 38,
enter: 13
};
export default {
props: {
model: {
type: Object,
required: true
}
},
data() {
return {
hideOptions: true,
filteredOptions: [],
optionIndex: 0,
field: ''
};
},
mounted() {
this.options = this.model.options;
this.autocompleteInputElement = this.$el.getElementsByClassName('autocompleteInput')[0];
if (this.options[0].name) {
// If "options" include name, value pair
this.optionNames = this.options.map((opt) => {
return opt.name;
});
} else {
// If options is only an array of string.
this.optionNames = this.options;
}
},
methods: {
fillInputWithIndexedOption() {
if (this.filteredOptions[this.optionIndex]) {
this.ngModel[this.field] = this.filteredOptions[this.optionIndex].name;
}
},
decrementOptionIndex() {
if (this.optionIndex === 0) {
this.optionIndex = this.filteredOptions.length;
}
this.optionIndex--;
this.fillInputWithIndexedOption();
},
incrementOptionIndex() {
if (this.optionIndex === this.filteredOptions.length - 1) {
this.optionIndex = -1;
}
this.optionIndex++;
this.fillInputWithIndexedOption();
},
fillInputWithString(string) {
this.hideOptions = true;
this.ngModel[this.field] = string;
},
showOptions(string) {
this.hideOptions = false;
this.filterOptions(string);
this.optionIndex = 0;
},
keyDown($event) {
if (this.filteredOptions) {
let keyCode = $event.keyCode;
switch (keyCode) {
case key.down:
this.incrementOptionIndex();
break;
case key.up:
$event.preventDefault(); // Prevents cursor jumping back and forth
this.decrementOptionIndex();
break;
case key.enter:
if (this.filteredOptions[this.optionIndex]) {
this.fillInputWithString(this.filteredOptions[this.optionIndex].name);
}
}
}
},
filterOptions() {
this.hideOptions = false;
this.filteredOptions = this.optionNames.filter((option) => {
return option.toLowerCase().indexOf(this.field.toLowerCase()) >= 0;
}).map((option, index) => {
return {
optionId: index,
name: option
};
});
},
inputClicked() {
this.autocompleteInputElement.select();
this.showOptions(this.autocompleteInputElement.value);
},
arrowClicked() {
this.autocompleteInputElement.select();
this.showOptions('');
},
fillInput(string) {
this.fillInputWithString(string);
},
optionMouseover(optionId) {
this.optionIndex = optionId;
}
}
};
</script>

View File

@ -0,0 +1,46 @@
<!--
Open MCT, Copyright (c) 2014-2021, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<template>
<span>
<composite-item v-for="(item, index) in model.items"
:key="item.name"
:first="index < 1"
:item="item"
/>
</span>
</template>
<script>
import CompositeItem from "@/api/forms/components/controls/CompositeItem.vue";
export default {
components: {
CompositeItem
},
props: {
model: {
type: Object,
required: true
}
}
};
</script>

View File

@ -0,0 +1,57 @@
<!--
Open MCT, Copyright (c) 2014-2021, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<template>
<div :class="compositeCssClass">
<form-row :css-class="item.cssClass"
:first="first"
:row="item"
/>
<span class="composite-control-label">
{{ item.name }}
</span>
</div>
</template>
<script>
import FormRow from "@/api/forms/components/FormRow.vue";
export default {
components: {
FormRow
},
props: {
item: {
type: Object,
required: true
},
first: {
type: Boolean,
required: true
}
},
computed: {
compositeCssClass() {
return `l-composite-control l-${this.item.control}`;
}
}
};
</script>

View File

@ -0,0 +1,58 @@
<!--
Open MCT, Copyright (c) 2014-2021, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<template>
<span class="form-control shell">
<span class="field control"
:class="model.cssClass"
>
<input v-model="field"
type="number"
:min="model.min"
:max="model.max"
:step="model.step"
@blur="blur()"
>
<!-- ng-pattern="ngPattern"-->
</span>
</span>
</template>
<script>
export default {
props: {
model: {
type: Object,
required: true
}
},
data() {
return {
field: ''
};
},
methods: {
blur() {
}
}
};
</script>

View File

@ -0,0 +1,56 @@
<!--
Open MCT, Copyright (c) 2014-2021, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<template>
<span class="form-control shell">
<span class="field control"
:class="model.cssClass"
>
<input v-model="field"
type="text"
:size="model.size"
@blur="blur()"
>
<!-- ng-pattern="ngPattern"-->
</span>
</span>
</template>
<script>
export default {
props: {
model: {
type: Object,
required: true
}
},
data() {
return {
field: ''
};
},
methods: {
blur() {
}
}
};
</script>

View File

@ -38,6 +38,9 @@ function ObjectAPI(typeRegistry, openmct) {
this.eventEmitter = new EventEmitter();
this.providers = {};
this.rootRegistry = new RootRegistry();
this.injectIdentifierService = function () {
this.identifierService = openmct.$injector.get("identifierService");
};
this.rootProvider = new RootObjectProvider(this.rootRegistry);
this.cache = {};
@ -52,16 +55,33 @@ ObjectAPI.prototype.supersecretSetFallbackProvider = function (p) {
this.fallbackProvider = p;
};
/**
* @private
*/
ObjectAPI.prototype.getIdentifierService = function () {
// Lazily acquire identifier service
if (!this.identifierService) {
this.injectIdentifierService();
}
return this.identifierService;
};
/**
* Retrieve the provider for a given identifier.
* @private
*/
ObjectAPI.prototype.getProvider = function (identifier) {
//handles the '' vs 'mct' namespace issue
const keyString = utils.makeKeyString(identifier);
const identifierService = this.getIdentifierService();
const namespace = identifierService.parse(keyString).getSpace();
if (identifier.key === 'ROOT') {
return this.rootProvider;
}
return this.providers[identifier.namespace] || this.fallbackProvider;
return this.providers[namespace] || this.fallbackProvider;
};
/**

View File

@ -116,9 +116,11 @@ define([
* @private
*/
DefaultMetadataProvider.prototype.typeHasTelemetry = function (domainObject) {
const type = this.openmct.types.get(domainObject.type);
if (!this.typeService) {
this.typeService = this.openmct.$injector.get('typeService');
}
return Boolean(type.definition.telemetry);
return Boolean(this.typeService.getType(domainObject.type).typeDef.telemetry);
};
return DefaultMetadataProvider;

View File

@ -142,8 +142,6 @@ define([
this.metadataCache = new WeakMap();
this.formatMapCache = new WeakMap();
this.valueFormatterCache = new WeakMap();
this.formatters = new Map();
}
/**
@ -415,6 +413,17 @@ define([
return _.sortBy(options, sortKeys);
};
/**
* @private
*/
TelemetryAPI.prototype.getFormatService = function () {
if (!this.formatService) {
this.formatService = this.openmct.$injector.get('formatService');
}
return this.formatService;
};
/**
* Get a value formatter for a given valueMetadata.
*
@ -424,7 +433,7 @@ define([
if (!this.valueFormatterCache.has(valueMetadata)) {
this.valueFormatterCache.set(
valueMetadata,
new TelemetryValueFormatter(valueMetadata, this.formatters)
new TelemetryValueFormatter(valueMetadata, this.getFormatService())
);
}
@ -438,11 +447,9 @@ define([
* @returns {Format}
*/
TelemetryAPI.prototype.getFormatter = function (key) {
if (this.formatters.has(key)) {
return this.formatters.get(key);
} else {
throw new Error(`Unknown type ${key}`);
}
const formatMap = this.getFormatService().formatMap;
return formatMap[key];
};
/**
@ -469,7 +476,12 @@ define([
* @param {Format} format the
*/
TelemetryAPI.prototype.addFormat = function (format) {
this.formatters.set(format.key, format);
this.openmct.legacyExtension('formats', {
key: format.key,
implementation: function () {
return format;
}
});
};
/**

View File

@ -28,7 +28,8 @@ define([
printj
) {
function TelemetryValueFormatter(valueMetadata, formatters) {
// TODO: needs reference to formatService;
function TelemetryValueFormatter(valueMetadata, formatService) {
const numberFormatter = {
parse: function (x) {
return Number(x);
@ -42,7 +43,13 @@ define([
};
this.valueMetadata = valueMetadata;
this.formatter = formatters.get(valueMetadata.format) || numberFormatter;
try {
this.formatter = formatService
.getFormat(valueMetadata.format, valueMetadata);
} catch (e) {
// TODO: Better formatting
this.formatter = numberFormatter;
}
if (valueMetadata.format === 'enum') {
this.formatter = {};

View File

@ -40,7 +40,6 @@ const DEFAULTS = [
'platform/features/clock',
'platform/features/hyperlink',
'platform/features/timeline',
'platform/forms',
'platform/identity',
'platform/persistence/aggregator',
'platform/persistence/queue',
@ -85,7 +84,6 @@ define([
'../platform/features/hyperlink/bundle',
'../platform/features/static-markup/bundle',
'../platform/features/timeline/bundle',
'../platform/forms/bundle',
'../platform/framework/bundle',
'../platform/framework/src/load/Bundle',
'../platform/identity/bundle',

View File

@ -29,13 +29,6 @@ define([
) {
return function plugin() {
return function install(openmct) {
openmct.types.addType('folder', {
name: "Folder",
key: "folder",
description: "Create folders to organize other objects or links to objects without the ability to edit it's properties.",
cssClass: "icon-folder",
creatable: true
});
openmct.objectViews.addProvider(new FolderGridView(openmct));
openmct.objectViews.addProvider(new FolderListView(openmct));
};

View File

@ -3,10 +3,6 @@ import myItemsInterceptor from "./myItemsInterceptor";
export default function plugin() {
return function install(openmct) {
openmct.objects.addRoot({
namespace: '',
key: 'mine'
});
myItemsInterceptor(openmct);
missingObjectInterceptor(openmct);
};

View File

@ -1,41 +0,0 @@
export default class LocalStorageObjectProvider {
constructor({spaceKey = 'mct'}) {
this.localStorage = window.localStorage;
this.space = this.initializeSpace(spaceKey);
}
get(identifier) {
if (this.getSpaceAsObject()[identifier.key] !== undefined) {
const persistedModel = this.getSpaceAsObject()[identifier.key];
const domainObject = {
identifier,
...persistedModel
};
return Promise.resolve(domainObject);
} else {
return Promise.resolve(undefined);
}
}
getSpaceAsObject() {
return JSON.parse(this.space);
}
create(model) {
return this.setModel(model);
}
update(model) {
return this.setModel(model);
}
setModel(model) {
this.space[model.identifier.key] = JSON.stringify(model);
this.persist();
return Promise.resolve(true);
}
initializeSpace(spaceKey) {
if (this.localStorage[spaceKey] === undefined) {
this.localStorage[spaceKey] = JSON.stringify({});
}
return this.localStorage[spaceKey];
}
}

View File

@ -1,29 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import LocalStorageObjectProvider from './LocalStorageObjectProvider';
export default function (namespace = '', storageSpace = 'mct') {
return function (openmct) {
openmct.objects.addProvider(namespace, new LocalStorageObjectProvider(storageSpace));
};
}

View File

@ -430,7 +430,7 @@ export default {
}
// check for no entries first
if (entries[section.id]) {
if (entries[section.id] && entries[section.id][page.id]) {
const pageEntries = entries[section.id][page.id];
pageEntries.forEach(entry => {

View File

@ -22,7 +22,7 @@
<template>
<div class="c-notebook__search-results">
<div class="c-notebook__search-results__header">Search Results</div>
<div class="c-notebook__search-results__header">Search Results ({{ results.length }})</div>
<div class="c-notebook__entries">
<NotebookEntry v-for="(result, index) in results"
:key="index"

View File

@ -85,33 +85,33 @@ define([
}
],
"views": [
// {
// "name": "Plot",
// "key": "plot-single",
// "cssClass": "icon-telemetry",
// "template": PlotTemplate,
// "needs": [
// "telemetry"
// ],
// "delegation": false,
// "priority": "mandatory"
// },
// {
// "name": "Overlay Plot",
// "key": "overlayPlot",
// "cssClass": "icon-plot-overlay",
// "type": "telemetry.plot.overlay",
// "template": PlotTemplate,
// "editable": true
// },
// {
// "name": "Stacked Plot",
// "key": "stackedPlot",
// "cssClass": "icon-plot-stacked",
// "type": "telemetry.plot.stacked",
// "template": StackedPlotTemplate,
// "editable": true
// }
{
"name": "Plot",
"key": "plot-single",
"cssClass": "icon-telemetry",
"template": PlotTemplate,
"needs": [
"telemetry"
],
"delegation": false,
"priority": "mandatory"
},
{
"name": "Overlay Plot",
"key": "overlayPlot",
"cssClass": "icon-plot-overlay",
"type": "telemetry.plot.overlay",
"template": PlotTemplate,
"editable": true
},
{
"name": "Stacked Plot",
"key": "stackedPlot",
"cssClass": "icon-plot-stacked",
"type": "telemetry.plot.stacked",
"template": StackedPlotTemplate,
"editable": true
}
],
"directives": [
{

View File

@ -426,6 +426,12 @@ export default {
synchronized(value) {
if (typeof value !== 'undefined') {
this._synchronized = value;
const isUnsynced = !value && this.openmct.time.clock();
const domainObject = this.openmct.legacyObject(this.domainObject);
if (domainObject.getCapability('status')) {
domainObject.getCapability('status')
.set('timeconductor-unsynced', isUnsynced);
}
}
return this._synchronized;

View File

@ -100,7 +100,7 @@ export default {
mounted() {
eventHelpers.extend(this);
//this.exportImageService = this.openmct.$injector.get('exportImageService');
this.exportImageService = this.openmct.$injector.get('exportImageService');
},
beforeDestroy() {
this.destroy();

View File

@ -40,7 +40,7 @@ export default function PlotViewProvider(openmct) {
}
function isCompactView(objectPath) {
return true;
return objectPath.find(object => object.type === 'time-strip');
}
return {

View File

@ -71,7 +71,8 @@ export default class XAxisModel extends Model {
defaults(options) {
const bounds = options.openmct.time.bounds();
const timeSystem = options.openmct.time.timeSystem();
const format = options.openmct.telemetry.getFormatter(timeSystem.timeFormat);
const format = options.openmct.$injector.get('formatService')
.getFormat(timeSystem.timeFormat);
return {
name: timeSystem.name,

View File

@ -65,9 +65,7 @@ define([
'./interceptors/plugin',
'./performanceIndicator/plugin',
'./CouchDBSearchFolder/plugin',
'./localStorage/plugin',
'./timeline/plugin',
'./devices/plugin'
'./timeline/plugin'
], function (
_,
UTCTimeSystem,
@ -113,11 +111,10 @@ define([
ObjectInterceptors,
PerformanceIndicator,
CouchDBSearchFolder,
LocalStorage,
Timeline,
Devices
Timeline
) {
const bundleMap = {
LocalStorage: 'platform/persistence/local',
MyItems: 'platform/features/my-items',
Elasticsearch: 'platform/persistence/elastic'
};
@ -130,14 +127,12 @@ define([
};
});
plugins.LocalStorage = LocalStorage.default;
plugins.UTCTimeSystem = UTCTimeSystem;
plugins.LocalTimeSystem = LocalTimeSystem;
plugins.ImportExport = ImportExport;
plugins.StaticRootPlugin = StaticRootPlugin;
plugins.Devices = Devices.default;
/**
* A tabular view showing the latest values of multiple telemetry points at

View File

@ -1,62 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'moment'
], function (
moment
) {
const DATE_FORMAT = "HH:mm:ss";
const DATE_FORMATS = [
DATE_FORMAT
];
/**
* Formatter for duration. Uses moment to produce a date from a given
* value, but output is formatted to display only time. Can be used for
* specifying a time duration. For specifying duration, it's best to
* specify a date of January 1, 1970, as the ms offset will equal the
* duration represented by the time.
*
* @implements {Format}
* @constructor
* @memberof platform/commonUI/formats
*/
function DurationFormat() {
this.key = "duration";
}
DurationFormat.prototype.format = function (value) {
return moment.utc(value).format(DATE_FORMAT);
};
DurationFormat.prototype.parse = function (text) {
return moment.duration(text).asMilliseconds();
};
DurationFormat.prototype.validate = function (text) {
return moment.utc(text, DATE_FORMATS, true).isValid();
};
return DurationFormat;
});

View File

@ -1,83 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2016, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'moment'
], function (
moment
) {
const DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS";
const DATE_FORMATS = [
DATE_FORMAT,
DATE_FORMAT + "Z",
"YYYY-MM-DD HH:mm:ss",
"YYYY-MM-DD HH:mm",
"YYYY-MM-DD"
];
/**
* @typedef Scale
* @property {number} min the minimum scale value, in ms
* @property {number} max the maximum scale value, in ms
*/
/**
* Formatter for UTC timestamps. Interprets numeric values as
* milliseconds since the start of 1970.
*
* @implements {Format}
* @constructor
* @memberof platform/commonUI/formats
*/
function UTCTimeFormat() {
this.key = "utc";
}
/**
* @param {number} value The value to format.
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
* in the array.
*/
UTCTimeFormat.prototype.format = function (value) {
if (value !== undefined) {
return moment.utc(value).format(DATE_FORMAT) + "Z";
} else {
return value;
}
};
UTCTimeFormat.prototype.parse = function (text) {
if (typeof text === 'number') {
return text;
}
return moment.utc(text, DATE_FORMATS).valueOf();
};
UTCTimeFormat.prototype.validate = function (text) {
return moment.utc(text, DATE_FORMATS, true).isValid();
};
return UTCTimeFormat;
});

View File

@ -22,14 +22,10 @@
define([
"./UTCTimeSystem",
"./LocalClock",
"./UTCTimeFormat",
"./DurationFormat"
"./LocalClock"
], function (
UTCTimeSystem,
LocalClock,
UTCTimeFormat,
DurationFormat
LocalClock
) {
/**
* Install a time system that supports UTC times. It also installs a local
@ -40,8 +36,6 @@ define([
const timeSystem = new UTCTimeSystem();
openmct.time.addTimeSystem(timeSystem);
openmct.time.addClock(new LocalClock(100));
openmct.telemetry.addFormat(new UTCTimeFormat());
openmct.telemetry.addFormat(new DurationFormat());
};
};
});

View File

@ -13,7 +13,7 @@
</div>
<span v-if="!singleSelectNonObject"
class="c-inspector__selected c-object-label__name"
>{{ domainObject.name }}</span>
>{{ item.name }}</span>
<div v-if="singleSelectNonObject"
class="c-inspector__selected c-inspector__selected--non-domain-object c-object-label"
>
@ -36,7 +36,7 @@ export default {
inject: ['openmct'],
data() {
return {
domainObject: undefined,
domainObject: {},
keyString: undefined,
multiSelect: false,
itemsSelected: 0,
@ -44,22 +44,21 @@ export default {
};
},
computed: {
item() {
return this.domainObject || {};
},
type() {
if (this.domainObject !== undefined) {
return this.openmct.types.get(this.domainObject.type);
} else {
return undefined;
}
return this.openmct.types.get(this.item.type);
},
typeCssClass() {
if (this.type === undefined || this.type.definition.cssClass === undefined) {
if (this.type.definition.cssClass === undefined) {
return 'icon-object';
}
return this.type.definition.cssClass;
},
singleSelectNonObject() {
return !this.domainObject && !this.multiSelect;
return !this.item.identifier && !this.multiSelect;
},
statusClass() {
return this.status ? `is-status--${this.status}` : '';

View File

@ -12,7 +12,7 @@
</template>
<script>
import CreateAction from '../../../platform/commonUI/edit/src/creation/CreateAction';
import CreateAction from '@/api/forms/actions/CreateAction';
import objectUtils from 'objectUtils';
export default {
@ -74,6 +74,12 @@ export default {
// 4. perform action.
return this.openmct.objects.get(this.openmct.router.path[0].identifier)
.then((currentObject) => {
console.log('type', key);
const createAction = new CreateAction(this.openmct, key, currentObject);
createAction.invoke();
let legacyContextualParent = this.convertToLegacy(currentObject);
let legacyType = this.openmct.$injector.get('typeService').getType(key);
let context = {
@ -87,7 +93,6 @@ export default {
this.openmct
);
return action.perform();
});
},
convertToLegacy(domainObject) {

View File

@ -108,6 +108,7 @@
import Inspector from '../inspector/Inspector.vue';
import MctTree from './mct-tree.vue';
import ObjectView from '../components/ObjectView.vue';
import MctTemplate from '../legacy/mct-template.vue';
import CreateButton from './CreateButton.vue';
import multipane from './multipane.vue';
import pane from './pane.vue';
@ -122,6 +123,7 @@ export default {
Inspector,
MctTree,
ObjectView,
'mct-template': MctTemplate,
CreateButton,
multipane,
pane,

View File

@ -308,6 +308,9 @@ export default {
},
methods: {
async initialize() {
// required to index tree objects that do not have search providers
this.openmct.$injector.get('searchService');
window.addEventListener('resize', this.handleWindowResize);
await this.calculateHeights();

View File

@ -66,6 +66,9 @@ export default {
watch: {
highlight() {
this.highlightText();
},
text() {
this.highlightText();
}
},
mounted() {