Compare commits
40 Commits
add-events
...
tc-size-li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29977f8eb2 | ||
|
|
f404c4022b | ||
|
|
bf3cad3f6e | ||
|
|
8780cc33d0 | ||
|
|
dc62e56279 | ||
|
|
1c794bdece | ||
|
|
052ec19892 | ||
|
|
5f70ab7dd3 | ||
|
|
7f73e1e765 | ||
|
|
ea7cf080c3 | ||
|
|
9b0762f201 | ||
|
|
31aa291672 | ||
|
|
65e8d8b23c | ||
|
|
fdb35094f4 | ||
|
|
3b99a12d7f | ||
|
|
25ee2d8099 | ||
|
|
c14cc25977 | ||
|
|
50997270e9 | ||
|
|
67e3094c6c | ||
|
|
526e31d10c | ||
|
|
3b316ed491 | ||
|
|
282ead581a | ||
|
|
c4f18a4797 | ||
|
|
c273e83093 | ||
|
|
e4b9242864 | ||
|
|
ceddadcac6 | ||
|
|
6e2437b09e | ||
|
|
5a44931537 | ||
|
|
f165d9c064 | ||
|
|
613973d936 | ||
|
|
830f321f90 | ||
|
|
a14cd62878 | ||
|
|
8314d03af5 | ||
|
|
187da3c462 | ||
|
|
e4f134ca59 | ||
|
|
76829ad252 | ||
|
|
a8da0d5917 | ||
|
|
488beb5b3f | ||
|
|
2f63718385 | ||
|
|
433f1bf28e |
@@ -1,5 +1,6 @@
|
|||||||
import AutoCompleteField from './components/controls/AutoCompleteField.vue';
|
import AutoCompleteField from './components/controls/AutoCompleteField.vue';
|
||||||
import ClockDisplayFormatField from './components/controls/ClockDisplayFormatField.vue';
|
import ClockDisplayFormatField from './components/controls/ClockDisplayFormatField.vue';
|
||||||
|
import CheckBoxField from './components/controls/CheckBoxField.vue';
|
||||||
import Datetime from './components/controls/Datetime.vue';
|
import Datetime from './components/controls/Datetime.vue';
|
||||||
import FileInput from './components/controls/FileInput.vue';
|
import FileInput from './components/controls/FileInput.vue';
|
||||||
import Locator from './components/controls/Locator.vue';
|
import Locator from './components/controls/Locator.vue';
|
||||||
@@ -12,6 +13,7 @@ import Vue from 'vue';
|
|||||||
|
|
||||||
export const DEFAULT_CONTROLS_MAP = {
|
export const DEFAULT_CONTROLS_MAP = {
|
||||||
'autocomplete': AutoCompleteField,
|
'autocomplete': AutoCompleteField,
|
||||||
|
'checkbox': CheckBoxField,
|
||||||
'composite': ClockDisplayFormatField,
|
'composite': ClockDisplayFormatField,
|
||||||
'datetime': Datetime,
|
'datetime': Datetime,
|
||||||
'file-input': FileInput,
|
'file-input': FileInput,
|
||||||
|
|||||||
@@ -172,7 +172,11 @@ export default class FormsAPI {
|
|||||||
|
|
||||||
function onFormSave(save) {
|
function onFormSave(save) {
|
||||||
return () => {
|
return () => {
|
||||||
|
if (element) {
|
||||||
|
formElement.remove();
|
||||||
|
} else {
|
||||||
overlay.dismiss();
|
overlay.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
if (save) {
|
if (save) {
|
||||||
save(changes);
|
save(changes);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -24,28 +24,36 @@
|
|||||||
<div class="c-form">
|
<div class="c-form">
|
||||||
<div class="c-overlay__top-bar c-form__top-bar">
|
<div class="c-overlay__top-bar c-form__top-bar">
|
||||||
<div class="c-overlay__dialog-title">{{ model.title }}</div>
|
<div class="c-overlay__dialog-title">{{ model.title }}</div>
|
||||||
<div class="c-overlay__dialog-hint hint">All fields marked <span class="req icon-asterisk"></span> are required.</div>
|
<div
|
||||||
|
v-if="hasRequiredFields"
|
||||||
|
class="c-overlay__dialog-hint hint"
|
||||||
|
>All fields marked <span class="req icon-asterisk"></span> are required.</div>
|
||||||
</div>
|
</div>
|
||||||
<form name="mctForm"
|
<form
|
||||||
|
name="mctForm"
|
||||||
class="c-form__contents"
|
class="c-form__contents"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
@submit.prevent
|
@submit.prevent
|
||||||
>
|
>
|
||||||
<div v-for="section in formSections"
|
<div
|
||||||
|
v-for="section in formSections"
|
||||||
:key="section.id"
|
:key="section.id"
|
||||||
class="c-form__section"
|
class="c-form__section"
|
||||||
:class="section.cssClass"
|
:class="section.cssClass"
|
||||||
>
|
>
|
||||||
<h2 v-if="section.name"
|
<h2
|
||||||
|
v-if="section.name"
|
||||||
class="c-form__section-header"
|
class="c-form__section-header"
|
||||||
>
|
>
|
||||||
{{ section.name }}
|
{{ section.name }}
|
||||||
</h2>
|
</h2>
|
||||||
<div v-for="(row, index) in section.rows"
|
<div
|
||||||
|
v-for="(row, index) in section.rows"
|
||||||
:key="row.id"
|
:key="row.id"
|
||||||
class="u-contents"
|
class="u-contents"
|
||||||
>
|
>
|
||||||
<FormRow :css-class="section.cssClass"
|
<FormRow
|
||||||
|
:css-class="section.cssClass"
|
||||||
:first="index < 1"
|
:first="index < 1"
|
||||||
:row="row"
|
:row="row"
|
||||||
@onChange="onChange"
|
@onChange="onChange"
|
||||||
@@ -55,18 +63,21 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="mct-form__controls c-overlay__button-bar c-form__bottom-bar">
|
<div class="mct-form__controls c-overlay__button-bar c-form__bottom-bar">
|
||||||
<button tabindex="0"
|
<button
|
||||||
|
tabindex="0"
|
||||||
:disabled="isInvalid"
|
:disabled="isInvalid"
|
||||||
class="c-button c-button--major"
|
class="c-button c-button--major"
|
||||||
@click="onSave"
|
@click="onSave"
|
||||||
>
|
>
|
||||||
OK
|
{{ submitLabel }}
|
||||||
</button>
|
</button>
|
||||||
<button tabindex="0"
|
<button
|
||||||
|
v-if="!hideCancel"
|
||||||
|
tabindex="0"
|
||||||
class="c-button"
|
class="c-button"
|
||||||
@click="onDismiss"
|
@click="onDismiss"
|
||||||
>
|
>
|
||||||
Cancel
|
{{ cancelLabel }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,11 +111,42 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
hasRequiredFields() {
|
||||||
|
return this.model.sections.some(section =>
|
||||||
|
section.rows.some(row => row.required));
|
||||||
|
},
|
||||||
isInvalid() {
|
isInvalid() {
|
||||||
return Object.entries(this.invalidProperties)
|
return Object.entries(this.invalidProperties)
|
||||||
.some(([key, value]) => {
|
.some(([key, value]) => {
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
submitLabel() {
|
||||||
|
if (
|
||||||
|
this.model.buttons
|
||||||
|
&& this.model.buttons.submit
|
||||||
|
&& this.model.buttons.submit.label
|
||||||
|
) {
|
||||||
|
return this.model.buttons.submit.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'OK';
|
||||||
|
},
|
||||||
|
cancelLabel() {
|
||||||
|
if (
|
||||||
|
this.model.buttons
|
||||||
|
&& this.model.buttons.cancel
|
||||||
|
&& this.model.buttons.cancel.label
|
||||||
|
) {
|
||||||
|
return this.model.buttons.submit.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Cancel';
|
||||||
|
},
|
||||||
|
hideCancel() {
|
||||||
|
return this.model.buttons
|
||||||
|
&& this.model.buttons.cancel
|
||||||
|
&& this.model.buttons.cancel.hide === true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -75,10 +75,12 @@ export default {
|
|||||||
rowClass() {
|
rowClass() {
|
||||||
let cssClass = this.cssClass;
|
let cssClass = this.cssClass;
|
||||||
|
|
||||||
if (this.row.required) {
|
if (!this.row.required) {
|
||||||
cssClass = `${cssClass} req`;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cssClass = `${cssClass} req`;
|
||||||
|
|
||||||
if (this.visited && this.valid !== undefined) {
|
if (this.visited && this.valid !== undefined) {
|
||||||
if (this.valid === true) {
|
if (this.valid === true) {
|
||||||
cssClass = `${cssClass} valid`;
|
cssClass = `${cssClass} valid`;
|
||||||
|
|||||||
62
src/api/forms/components/controls/CheckBoxField.vue
Normal file
62
src/api/forms/components/controls/CheckBoxField.vue
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2022, 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
|
||||||
|
type="checkbox"
|
||||||
|
:checked="isChecked"
|
||||||
|
@input="toggleCheckBox"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isChecked: this.model.value
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleCheckBox() {
|
||||||
|
this.isChecked = !this.isChecked;
|
||||||
|
const data = {
|
||||||
|
model: this.model,
|
||||||
|
value: this.isChecked
|
||||||
|
};
|
||||||
|
this.$emit('onChange', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -43,6 +43,7 @@ class InMemorySearchProvider {
|
|||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
|
|
||||||
this.indexedIds = {};
|
this.indexedIds = {};
|
||||||
|
this.indexedCompositions = {};
|
||||||
this.idsToIndex = [];
|
this.idsToIndex = [];
|
||||||
this.pendingIndex = {};
|
this.pendingIndex = {};
|
||||||
this.pendingRequests = 0;
|
this.pendingRequests = 0;
|
||||||
@@ -58,7 +59,6 @@ class InMemorySearchProvider {
|
|||||||
this.onWorkerMessageError = this.onWorkerMessageError.bind(this);
|
this.onWorkerMessageError = this.onWorkerMessageError.bind(this);
|
||||||
this.onerror = this.onWorkerError.bind(this);
|
this.onerror = this.onWorkerError.bind(this);
|
||||||
this.startIndexing = this.startIndexing.bind(this);
|
this.startIndexing = this.startIndexing.bind(this);
|
||||||
this.onMutationOfIndexedObject = this.onMutationOfIndexedObject.bind(this);
|
|
||||||
|
|
||||||
this.openmct.on('start', this.startIndexing);
|
this.openmct.on('start', this.startIndexing);
|
||||||
this.openmct.on('destroy', () => {
|
this.openmct.on('destroy', () => {
|
||||||
@@ -68,6 +68,9 @@ class InMemorySearchProvider {
|
|||||||
this.worker.port.onmessageerror = null;
|
this.worker.port.onmessageerror = null;
|
||||||
this.worker.port.close();
|
this.worker.port.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.destroyObservers(this.indexedIds);
|
||||||
|
this.destroyObservers(this.indexedCompositions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +140,7 @@ class InMemorySearchProvider {
|
|||||||
};
|
};
|
||||||
modelResults.hits = await Promise.all(event.data.results.map(async (hit) => {
|
modelResults.hits = await Promise.all(event.data.results.map(async (hit) => {
|
||||||
const identifier = this.openmct.objects.parseKeyString(hit.keyString);
|
const identifier = this.openmct.objects.parseKeyString(hit.keyString);
|
||||||
const domainObject = await this.openmct.objects.get(identifier.key);
|
const domainObject = await this.openmct.objects.get(identifier);
|
||||||
|
|
||||||
return domainObject;
|
return domainObject;
|
||||||
}));
|
}));
|
||||||
@@ -213,29 +216,52 @@ class InMemorySearchProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMutationOfIndexedObject(domainObject) {
|
onNameMutation(domainObject, name) {
|
||||||
const provider = this;
|
const provider = this;
|
||||||
provider.index(domainObject.identifier, domainObject);
|
|
||||||
|
domainObject.name = name;
|
||||||
|
provider.index(domainObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCompositionMutation(domainObject, composition) {
|
||||||
|
const provider = this;
|
||||||
|
const indexedComposition = domainObject.composition;
|
||||||
|
const identifiersToIndex = composition
|
||||||
|
.filter(identifier => !indexedComposition
|
||||||
|
.some(indexedIdentifier => this.openmct.objects
|
||||||
|
.areIdsEqual([identifier, indexedIdentifier])));
|
||||||
|
|
||||||
|
identifiersToIndex.forEach(identifier => {
|
||||||
|
this.openmct.objects.get(identifier).then(objectToIndex => provider.index(objectToIndex));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass an id and model to the worker to be indexed. If the model has
|
* Pass a domainObject to the worker to be indexed.
|
||||||
* composition, schedule those ids for later indexing.
|
* If the object has composition, schedule those ids for later indexing.
|
||||||
|
* Watch for object changes and re-index object and children if so
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param id a model id
|
* @param domainObject a domainObject
|
||||||
* @param model a model
|
|
||||||
*/
|
*/
|
||||||
async index(id, domainObject) {
|
async index(domainObject) {
|
||||||
const provider = this;
|
const provider = this;
|
||||||
const keyString = this.openmct.objects.makeKeyString(id);
|
const keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
|
|
||||||
if (!this.indexedIds[keyString]) {
|
if (!this.indexedIds[keyString]) {
|
||||||
this.openmct.objects.observe(domainObject, `*`, this.onMutationOfIndexedObject);
|
this.indexedIds[keyString] = this.openmct.objects.observe(
|
||||||
|
domainObject,
|
||||||
|
'name',
|
||||||
|
this.onNameMutation.bind(this, domainObject)
|
||||||
|
);
|
||||||
|
this.indexedCompositions[keyString] = this.openmct.objects.observe(
|
||||||
|
domainObject,
|
||||||
|
'composition',
|
||||||
|
this.onCompositionMutation.bind(this, domainObject)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.indexedIds[keyString] = true;
|
if ((keyString !== 'ROOT')) {
|
||||||
|
|
||||||
if ((id.key !== 'ROOT')) {
|
|
||||||
if (this.worker) {
|
if (this.worker) {
|
||||||
this.worker.port.postMessage({
|
this.worker.port.postMessage({
|
||||||
request: 'index',
|
request: 'index',
|
||||||
@@ -247,15 +273,12 @@ class InMemorySearchProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const composition = this.openmct.composition.registry.find(foundComposition => {
|
const composition = this.openmct.composition.get(domainObject);
|
||||||
return foundComposition.appliesTo(domainObject);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (composition) {
|
if (composition !== undefined) {
|
||||||
const childIdentifiers = await composition.load(domainObject);
|
const children = await composition.load();
|
||||||
childIdentifiers.forEach(function (childIdentifier) {
|
|
||||||
provider.scheduleForIndexing(childIdentifier);
|
children.forEach(child => provider.scheduleForIndexing(child.identifier));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,12 +294,12 @@ class InMemorySearchProvider {
|
|||||||
const provider = this;
|
const provider = this;
|
||||||
|
|
||||||
this.pendingRequests += 1;
|
this.pendingRequests += 1;
|
||||||
const identifier = await this.openmct.objects.parseKeyString(keyString);
|
const domainObject = await this.openmct.objects.get(keyString);
|
||||||
const domainObject = await this.openmct.objects.get(identifier.key);
|
|
||||||
delete provider.pendingIndex[keyString];
|
delete provider.pendingIndex[keyString];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (domainObject) {
|
if (domainObject) {
|
||||||
await provider.index(identifier, domainObject);
|
await provider.index(domainObject);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to index domain object ' + keyString, error);
|
console.warn('Failed to index domain object ' + keyString, error);
|
||||||
@@ -347,6 +370,16 @@ class InMemorySearchProvider {
|
|||||||
};
|
};
|
||||||
this.onWorkerMessage(eventToReturn);
|
this.onWorkerMessage(eventToReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyObservers(observers) {
|
||||||
|
Object.entries(observers).forEach(([keyString, unobserve]) => {
|
||||||
|
if (typeof unobserve === 'function') {
|
||||||
|
unobserve();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete observers[keyString];
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default InMemorySearchProvider;
|
export default InMemorySearchProvider;
|
||||||
|
|||||||
@@ -33,8 +33,10 @@
|
|||||||
|
|
||||||
port.onmessage = function (event) {
|
port.onmessage = function (event) {
|
||||||
if (event.data.request === 'index') {
|
if (event.data.request === 'index') {
|
||||||
|
console.log('onmessage index: ', event.data);
|
||||||
indexItem(event.data.keyString, event.data.model);
|
indexItem(event.data.keyString, event.data.model);
|
||||||
} else if (event.data.request === 'search') {
|
} else if (event.data.request === 'search') {
|
||||||
|
console.log('onmessage search: ', event.data);
|
||||||
port.postMessage(search(event.data));
|
port.postMessage(search(event.data));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -77,6 +79,8 @@
|
|||||||
queryId: data.queryId
|
queryId: data.queryId
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('indexed on search: ', indexedItems);
|
||||||
|
|
||||||
results = Object.values(indexedItems).filter((indexedItem) => {
|
results = Object.values(indexedItems).filter((indexedItem) => {
|
||||||
return indexedItem.name.toLowerCase().includes(input);
|
return indexedItem.name.toLowerCase().includes(input);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ define([
|
|||||||
*/
|
*/
|
||||||
function parseKeyString(keyString) {
|
function parseKeyString(keyString) {
|
||||||
if (isIdentifier(keyString)) {
|
if (isIdentifier(keyString)) {
|
||||||
|
// hack to workaround a bug mashing keyString into identifier.key
|
||||||
|
if (!keyString.namespace && keyString.key.includes(':')) {
|
||||||
|
return parseKeyString(keyString.key);
|
||||||
|
}
|
||||||
|
|
||||||
return keyString;
|
return keyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import EventEmitter from 'EventEmitter';
|
|||||||
|
|
||||||
const ERRORS = {
|
const ERRORS = {
|
||||||
TIMESYSTEM_KEY: 'All telemetry metadata must have a telemetry value with a key that matches the key of the active time system.',
|
TIMESYSTEM_KEY: 'All telemetry metadata must have a telemetry value with a key that matches the key of the active time system.',
|
||||||
|
TIMESYSTEM_KEY_NOTIFICATION: 'Telemetry metadata does not match the active time system.',
|
||||||
LOADED: 'Telemetry Collection has already been loaded.'
|
LOADED: 'Telemetry Collection has already been loaded.'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,6 +222,11 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (added.length) {
|
if (added.length) {
|
||||||
|
// check if there is a size option, if so force it's adherence
|
||||||
|
if (this.options.size !== undefined && this.options.size > 0) {
|
||||||
|
added = added.slice(0, this.options.size);
|
||||||
|
}
|
||||||
|
|
||||||
this.emit('add', added);
|
this.emit('add', added);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,6 +272,10 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
this.lastBounds = bounds;
|
this.lastBounds = bounds;
|
||||||
|
|
||||||
if (isTick) {
|
if (isTick) {
|
||||||
|
if (this.timeKey === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// need to check futureBuffer and need to check
|
// need to check futureBuffer and need to check
|
||||||
// if anything has fallen out of bounds
|
// if anything has fallen out of bounds
|
||||||
let startIndex = 0;
|
let startIndex = 0;
|
||||||
@@ -305,7 +315,6 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
if (added.length > 0) {
|
if (added.length > 0) {
|
||||||
this.emit('add', added);
|
this.emit('add', added);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// user bounds change, reset
|
// user bounds change, reset
|
||||||
this._reset();
|
this._reset();
|
||||||
@@ -325,12 +334,14 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
let domains = this.metadata.valuesForHints(['domain']);
|
let domains = this.metadata.valuesForHints(['domain']);
|
||||||
let domain = domains.find((d) => d.key === timeSystem.key);
|
let domain = domains.find((d) => d.key === timeSystem.key);
|
||||||
|
|
||||||
if (domain === undefined) {
|
if (domain !== undefined) {
|
||||||
this._error(ERRORS.TIMESYSTEM_KEY);
|
// timeKey is used to create a dummy datum used for sorting
|
||||||
|
this.timeKey = domain.source;
|
||||||
|
} else {
|
||||||
|
this._warn(ERRORS.TIMESYSTEM_KEY);
|
||||||
|
this.openmct.notifications.alert(ERRORS.TIMESYSTEM_KEY_NOTIFICATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// timeKey is used to create a dummy datum used for sorting
|
|
||||||
this.timeKey = domain.source; // this defaults to key if no source is set
|
|
||||||
let metadataValue = this.metadata.value(timeSystem.key) || { format: timeSystem.key };
|
let metadataValue = this.metadata.value(timeSystem.key) || { format: timeSystem.key };
|
||||||
let valueFormatter = this.openmct.telemetry.getValueFormatter(metadataValue);
|
let valueFormatter = this.openmct.telemetry.getValueFormatter(metadataValue);
|
||||||
|
|
||||||
@@ -400,4 +411,8 @@ export class TelemetryCollection extends EventEmitter {
|
|||||||
_error(message) {
|
_error(message) {
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_warn(message) {
|
||||||
|
console.warn(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ export default class ConditionSetViewProvider {
|
|||||||
return isConditionSet && this.openmct.router.isNavigatedObject(objectPath);
|
return isConditionSet && this.openmct.router.isNavigatedObject(objectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
canEdit(domainObject) {
|
canEdit(domainObject, objectPath) {
|
||||||
return domainObject.type === 'conditionSet';
|
const isConditionSet = domainObject.type === 'conditionSet';
|
||||||
|
|
||||||
|
return isConditionSet && this.openmct.router.isNavigatedObject(objectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
view(domainObject, objectPath) {
|
view(domainObject, objectPath) {
|
||||||
|
|||||||
@@ -66,10 +66,11 @@ export default class CreateAction extends PropertiesAction {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const parentDomainObject = parentDomainObjectPath[0];
|
const parentDomainObject = parentDomainObjectPath[0];
|
||||||
|
const namespace = parentDomainObject.identifier.namespace || parentDomainObject.key || '';
|
||||||
|
|
||||||
this.domainObject.modified = Date.now();
|
this.domainObject.modified = Date.now();
|
||||||
this.domainObject.location = this.openmct.objects.makeKeyString(parentDomainObject.identifier);
|
this.domainObject.location = this.openmct.objects.makeKeyString(parentDomainObject.identifier);
|
||||||
this.domainObject.identifier.namespace = parentDomainObject.identifier.namespace;
|
this.domainObject.identifier.namespace = namespace;
|
||||||
|
|
||||||
// Show saving progress dialog
|
// Show saving progress dialog
|
||||||
let dialog = this.openmct.overlays.progressDialog({
|
let dialog = this.openmct.overlays.progressDialog({
|
||||||
@@ -99,6 +100,7 @@ export default class CreateAction extends PropertiesAction {
|
|||||||
*/
|
*/
|
||||||
async _navigateAndEdit(domainObject, parentDomainObjectpath) {
|
async _navigateAndEdit(domainObject, parentDomainObjectpath) {
|
||||||
let objectPath;
|
let objectPath;
|
||||||
|
let self = this;
|
||||||
if (parentDomainObjectpath) {
|
if (parentDomainObjectpath) {
|
||||||
objectPath = parentDomainObjectpath && [domainObject].concat(parentDomainObjectpath);
|
objectPath = parentDomainObjectpath && [domainObject].concat(parentDomainObjectpath);
|
||||||
} else {
|
} else {
|
||||||
@@ -106,19 +108,24 @@ export default class CreateAction extends PropertiesAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = '#/browse/' + objectPath
|
const url = '#/browse/' + objectPath
|
||||||
.map(object => object && this.openmct.objects.makeKeyString(object.identifier.key))
|
.map(object => object && this.openmct.objects.makeKeyString(object.identifier))
|
||||||
.reverse()
|
.reverse()
|
||||||
.join('/');
|
.join('/');
|
||||||
|
|
||||||
this.openmct.router.navigate(url);
|
function editObject() {
|
||||||
|
const objectView = self.openmct.objectViews.get(domainObject, objectPath)[0];
|
||||||
const objectView = this.openmct.objectViews.get(domainObject, objectPath)[0];
|
|
||||||
const canEdit = objectView && objectView.canEdit && objectView.canEdit(domainObject, objectPath);
|
const canEdit = objectView && objectView.canEdit && objectView.canEdit(domainObject, objectPath);
|
||||||
|
|
||||||
if (canEdit) {
|
if (canEdit) {
|
||||||
this.openmct.editor.edit();
|
self.openmct.editor.edit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.openmct.router.once('afterNavigation', editObject);
|
||||||
|
|
||||||
|
this.openmct.router.navigate(url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -65,13 +65,8 @@ export default {
|
|||||||
keyString: undefined
|
keyString: undefined
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
imageHistorySize() {
|
|
||||||
return this.imageHistory.length;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
watch: {
|
||||||
imageHistorySize(newSize, oldSize) {
|
imageHistory(newHistory, oldHistory) {
|
||||||
this.updatePlotImagery();
|
this.updatePlotImagery();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -240,9 +240,6 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
imageHistorySize() {
|
|
||||||
return this.imageHistory.length;
|
|
||||||
},
|
|
||||||
compassRoseSizingClasses() {
|
compassRoseSizingClasses() {
|
||||||
let compassRoseSizingClasses = '';
|
let compassRoseSizingClasses = '';
|
||||||
if (this.sizedImageDimensions.width < 300) {
|
if (this.sizedImageDimensions.width < 300) {
|
||||||
@@ -409,7 +406,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
imageHistorySize(newSize, oldSize) {
|
imageHistory: {
|
||||||
|
handler(newHistory, oldHistory) {
|
||||||
|
const newSize = newHistory.length;
|
||||||
let imageIndex;
|
let imageIndex;
|
||||||
if (this.focusedImageTimestamp !== undefined) {
|
if (this.focusedImageTimestamp !== undefined) {
|
||||||
const foundImageIndex = this.imageHistory.findIndex(image => {
|
const foundImageIndex = this.imageHistory.findIndex(image => {
|
||||||
@@ -423,6 +422,8 @@ export default {
|
|||||||
this.setFocusedImage(imageIndex, false);
|
this.setFocusedImage(imageIndex, false);
|
||||||
this.scrollToRight();
|
this.scrollToRight();
|
||||||
},
|
},
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
focusedImageIndex() {
|
focusedImageIndex() {
|
||||||
this.trackDuration();
|
this.trackDuration();
|
||||||
this.resetAgeCSS();
|
this.resetAgeCSS();
|
||||||
@@ -510,12 +511,6 @@ export default {
|
|||||||
this.timeContext.off("clock", this.trackDuration);
|
this.timeContext.off("clock", this.trackDuration);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
boundsChange(bounds, isTick) {
|
|
||||||
if (!isTick) {
|
|
||||||
this.previousFocusedImage = this.focusedImage ? JSON.parse(JSON.stringify(this.focusedImage)) : undefined;
|
|
||||||
this.requestHistory();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
expand() {
|
expand() {
|
||||||
const actionCollection = this.openmct.actions.getActionsCollection(this.objectPath, this.currentView);
|
const actionCollection = this.openmct.actions.getActionsCollection(this.objectPath, this.currentView);
|
||||||
const visibleActions = actionCollection.getVisibleActions();
|
const visibleActions = actionCollection.getVisibleActions();
|
||||||
@@ -690,22 +685,32 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thumbnailClick) {
|
||||||
|
//We use the props till the user changes what they want to see
|
||||||
|
this.focusedImageTimestamp = undefined;
|
||||||
|
//set the previousFocusedImage when a user chooses an image
|
||||||
|
this.previousFocusedImage = this.imageHistory[focusedIndex] ? JSON.parse(JSON.stringify(this.imageHistory[focusedIndex])) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.previousFocusedImage) {
|
if (this.previousFocusedImage) {
|
||||||
// determine if the previous image exists in the new bounds of imageHistory
|
// determine if the previous image exists in the new bounds of imageHistory
|
||||||
|
if (!thumbnailClick) {
|
||||||
const matchIndex = this.matchIndexOfPreviousImage(
|
const matchIndex = this.matchIndexOfPreviousImage(
|
||||||
this.previousFocusedImage,
|
this.previousFocusedImage,
|
||||||
this.imageHistory
|
this.imageHistory
|
||||||
);
|
);
|
||||||
focusedIndex = matchIndex > -1 ? matchIndex : this.imageHistory.length - 1;
|
focusedIndex = matchIndex > -1 ? matchIndex : this.imageHistory.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(this.isPaused || thumbnailClick)
|
||||||
|
|| focusedIndex === this.imageHistory.length - 1) {
|
||||||
delete this.previousFocusedImage;
|
delete this.previousFocusedImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thumbnailClick) {
|
|
||||||
//We use the props till the user changes what they want to see
|
|
||||||
this.focusedImageTimestamp = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.focusedImageIndex = focusedIndex;
|
||||||
|
|
||||||
|
//TODO: do we even need this anymore?
|
||||||
if (this.isPaused && !thumbnailClick && this.focusedImageTimestamp === undefined) {
|
if (this.isPaused && !thumbnailClick && this.focusedImageTimestamp === undefined) {
|
||||||
this.nextImageIndex = focusedIndex;
|
this.nextImageIndex = focusedIndex;
|
||||||
//this could happen if bounds changes
|
//this could happen if bounds changes
|
||||||
@@ -716,8 +721,6 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.focusedImageIndex = focusedIndex;
|
|
||||||
|
|
||||||
if (thumbnailClick && !this.isPaused) {
|
if (thumbnailClick && !this.isPaused) {
|
||||||
this.paused(true);
|
this.paused(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,9 +120,15 @@ export default {
|
|||||||
return this.timeFormatter.parse(datum);
|
return this.timeFormatter.parse(datum);
|
||||||
},
|
},
|
||||||
boundsChange(bounds, isTick) {
|
boundsChange(bounds, isTick) {
|
||||||
if (!isTick) {
|
if (isTick) {
|
||||||
this.requestHistory();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
|
||||||
|
delete this.imageContainerWidth;
|
||||||
|
delete this.imageContainerHeight;
|
||||||
|
|
||||||
|
return this.requestHistory();
|
||||||
},
|
},
|
||||||
async requestHistory() {
|
async requestHistory() {
|
||||||
let bounds = this.timeContext.bounds();
|
let bounds = this.timeContext.bounds();
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ export default class LinkAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(currentParent) {
|
validate(currentParent) {
|
||||||
return (object, data) => {
|
return (data) => {
|
||||||
const parentCandidate = data.value;
|
const parentCandidate = data.value[0];
|
||||||
const currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier);
|
const currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier);
|
||||||
const parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier);
|
const parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier);
|
||||||
const objectKeystring = this.openmct.objects.makeKeyString(object.identifier);
|
const objectKeystring = this.openmct.objects.makeKeyString(this.object.identifier);
|
||||||
|
|
||||||
if (!parentCandidateKeystring || !currentParentKeystring) {
|
if (!parentCandidateKeystring || !currentParentKeystring) {
|
||||||
return false;
|
return false;
|
||||||
@@ -114,7 +114,7 @@ export default class LinkAction {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parentCandidate && this.openmct.composition.checkPolicy(parentCandidate, object);
|
return parentCandidate && this.openmct.composition.checkPolicy(parentCandidate, this.object);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ import { clearDefaultNotebook, getDefaultNotebook, setDefaultNotebook, setDefaul
|
|||||||
import { addNotebookEntry, createNewEmbed, getEntryPosById, getNotebookEntries, mutateObject } from '../utils/notebook-entries';
|
import { addNotebookEntry, createNewEmbed, getEntryPosById, getNotebookEntries, mutateObject } from '../utils/notebook-entries';
|
||||||
import { saveNotebookImageDomainObject, updateNamespaceOfDomainObject } from '../utils/notebook-image';
|
import { saveNotebookImageDomainObject, updateNamespaceOfDomainObject } from '../utils/notebook-image';
|
||||||
import { NOTEBOOK_VIEW_TYPE } from '../notebook-constants';
|
import { NOTEBOOK_VIEW_TYPE } from '../notebook-constants';
|
||||||
import objectUtils from 'objectUtils';
|
|
||||||
|
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import objectLink from '../../../ui/mixins/object-link';
|
import objectLink from '../../../ui/mixins/object-link';
|
||||||
@@ -455,11 +454,6 @@ export default {
|
|||||||
? getDefaultNotebook().defaultSectionId
|
? getDefaultNotebook().defaultSectionId
|
||||||
: undefined;
|
: undefined;
|
||||||
},
|
},
|
||||||
getDefaultNotebookObject() {
|
|
||||||
const defaultNotebook = getDefaultNotebook();
|
|
||||||
|
|
||||||
return defaultNotebook && this.openmct.objects.get(defaultNotebook.identifier);
|
|
||||||
},
|
|
||||||
getLinktoNotebook() {
|
getLinktoNotebook() {
|
||||||
const objectPath = this.openmct.router.path;
|
const objectPath = this.openmct.router.path;
|
||||||
const link = objectLink.computed.objectLink.call({
|
const link = objectLink.computed.objectLink.call({
|
||||||
@@ -619,12 +613,12 @@ export default {
|
|||||||
|
|
||||||
this.sectionsChanged({ sections });
|
this.sectionsChanged({ sections });
|
||||||
},
|
},
|
||||||
removeDefaultClass(domainObject) {
|
removeDefaultClass(defaultNotebookIdentifier) {
|
||||||
if (!domainObject) {
|
if (!defaultNotebookIdentifier) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.openmct.status.delete(domainObject.identifier);
|
this.openmct.status.delete(defaultNotebookIdentifier);
|
||||||
},
|
},
|
||||||
resetSearch() {
|
resetSearch() {
|
||||||
this.search = '';
|
this.search = '';
|
||||||
@@ -633,15 +627,16 @@ export default {
|
|||||||
toggleNav() {
|
toggleNav() {
|
||||||
this.showNav = !this.showNav;
|
this.showNav = !this.showNav;
|
||||||
},
|
},
|
||||||
async updateDefaultNotebook(notebookStorage) {
|
updateDefaultNotebook(notebookStorage) {
|
||||||
const defaultNotebookObject = await this.getDefaultNotebookObject();
|
const defaultNotebook = getDefaultNotebook();
|
||||||
const isSameNotebook = defaultNotebookObject
|
const defaultNotebookIdentifier = defaultNotebook && defaultNotebook.identifier;
|
||||||
&& objectUtils.makeKeyString(defaultNotebookObject.identifier) === objectUtils.makeKeyString(notebookStorage.identifier);
|
const isSameNotebook = defaultNotebookIdentifier
|
||||||
|
&& this.openmct.objects.areIdsEqual(defaultNotebookIdentifier, notebookStorage.identifier);
|
||||||
if (!isSameNotebook) {
|
if (!isSameNotebook) {
|
||||||
this.removeDefaultClass(defaultNotebookObject);
|
this.removeDefaultClass(defaultNotebookIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defaultNotebookObject || !isSameNotebook) {
|
if (!defaultNotebookIdentifier || !isSameNotebook) {
|
||||||
setDefaultNotebook(this.openmct, notebookStorage, this.domainObject);
|
setDefaultNotebook(this.openmct, notebookStorage, this.domainObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,8 @@ export default class Snapshot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.location.href = window.location.origin + url;
|
const path = window.location.href.split('#');
|
||||||
|
window.location.href = path[0] + url;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,11 +105,6 @@ export function addNotebookEntry(openmct, domainObject, notebookStorage, embed =
|
|||||||
const date = Date.now();
|
const date = Date.now();
|
||||||
const configuration = domainObject.configuration;
|
const configuration = domainObject.configuration;
|
||||||
const entries = configuration.entries || {};
|
const entries = configuration.entries || {};
|
||||||
|
|
||||||
if (!entries) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const embeds = embed
|
const embeds = embed
|
||||||
? [embed]
|
? [embed]
|
||||||
: [];
|
: [];
|
||||||
@@ -125,7 +120,8 @@ export function addNotebookEntry(openmct, domainObject, notebookStorage, embed =
|
|||||||
const newEntries = addEntryIntoPage(notebookStorage, entries, entry);
|
const newEntries = addEntryIntoPage(notebookStorage, entries, entry);
|
||||||
|
|
||||||
addDefaultClass(domainObject, openmct);
|
addDefaultClass(domainObject, openmct);
|
||||||
domainObject.configuration.entries = newEntries;
|
|
||||||
|
mutateObject(openmct, domainObject, 'configuration.entries', newEntries);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,8 @@ export default {
|
|||||||
loaded: false,
|
loaded: false,
|
||||||
isTimeOutOfSync: false,
|
isTimeOutOfSync: false,
|
||||||
showLimitLineLabels: undefined,
|
showLimitLineLabels: undefined,
|
||||||
isFrozenOnMouseDown: false
|
isFrozenOnMouseDown: false,
|
||||||
|
hasSameRangeValue: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -321,6 +322,7 @@ export default {
|
|||||||
this.setDisplayRange(series, xKey);
|
this.setDisplayRange(series, xKey);
|
||||||
}, this);
|
}, this);
|
||||||
this.listenTo(series, 'change:yKey', () => {
|
this.listenTo(series, 'change:yKey', () => {
|
||||||
|
this.checkSameRangeValue();
|
||||||
this.loadSeriesData(series);
|
this.loadSeriesData(series);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
@@ -328,10 +330,18 @@ export default {
|
|||||||
this.loadSeriesData(series);
|
this.loadSeriesData(series);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.checkSameRangeValue();
|
||||||
this.loadSeriesData(series);
|
this.loadSeriesData(series);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkSameRangeValue() {
|
||||||
|
this.hasSameRangeValue = this.seriesModels.every((model) => {
|
||||||
|
return model.get('yKey') === this.seriesModels[0].get('yKey');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
removeSeries(plotSeries) {
|
removeSeries(plotSeries) {
|
||||||
|
this.checkSameRangeValue();
|
||||||
this.stopListening(plotSeries);
|
this.stopListening(plotSeries);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -447,7 +457,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setDisplayRange(series, xKey) {
|
setDisplayRange(series, xKey) {
|
||||||
if (this.config.series.length !== 1) {
|
if (this.config.series.model.length !== 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,10 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div v-if="singleSeries"
|
<div
|
||||||
|
v-if="canShowYAxisLabel"
|
||||||
class="gl-plot-label gl-plot-y-label"
|
class="gl-plot-label gl-plot-y-label"
|
||||||
:class="{'icon-gear': (yKeyOptions.length > 1)}"
|
:class="{'icon-gear': (yKeyOptions.length > 1 && singleSeries)}"
|
||||||
>{{ yAxisLabel }}
|
>{{ yAxisLabel }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -71,6 +72,12 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
hasSameRangeValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
seriesModel: {
|
seriesModel: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() {
|
default() {
|
||||||
@@ -90,6 +97,11 @@ export default {
|
|||||||
loaded: false
|
loaded: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
canShowYAxisLabel() {
|
||||||
|
return this.singleSeries === true || this.hasSameRangeValue === true;
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.yAxis = this.getYAxisFromConfig();
|
this.yAxis = this.getYAxisFromConfig();
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ export default {
|
|||||||
// Have to throw away the old canvas elements and replace with new
|
// Have to throw away the old canvas elements and replace with new
|
||||||
// canvas elements in order to get new drawing contexts.
|
// canvas elements in order to get new drawing contexts.
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.innerHTML = this.TEMPLATE;
|
div.innerHTML = this.canvasTemplate + this.canvasTemplate;
|
||||||
const mainCanvas = div.querySelectorAll("canvas")[1];
|
const mainCanvas = div.querySelectorAll("canvas")[1];
|
||||||
const overlayCanvas = div.querySelectorAll("canvas")[0];
|
const overlayCanvas = div.querySelectorAll("canvas")[0];
|
||||||
this.canvas.parentNode.replaceChild(mainCanvas, this.canvas);
|
this.canvas.parentNode.replaceChild(mainCanvas, this.canvas);
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ export default class PlotSeries extends Model {
|
|||||||
this.evaluate = function (datum) {
|
this.evaluate = function (datum) {
|
||||||
return this.limitEvaluator.evaluate(datum, valueMetadata);
|
return this.limitEvaluator.evaluate(datum, valueMetadata);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
this.set('unit', valueMetadata.unit);
|
||||||
const format = this.formats[newKey];
|
const format = this.formats[newKey];
|
||||||
this.getYVal = format.parse.bind(format);
|
this.getYVal = format.parse.bind(format);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,9 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SummaryWidgetsCompositionPolicy.prototype.allow = function (parent, child) {
|
SummaryWidgetsCompositionPolicy.prototype.allow = function (parent, child) {
|
||||||
const parentType = parent.getCapability('type');
|
const parentType = parent.type;
|
||||||
const newStyleChild = child.useCapability('adapter');
|
|
||||||
|
|
||||||
if (parentType.instanceOf('summary-widget') && !this.openmct.telemetry.isTelemetryObject(newStyleChild)) {
|
if (parentType === 'summary-widget' && !this.openmct.telemetry.isTelemetryObject(child)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ export default class TelemetryTableView {
|
|||||||
this.objectPath = objectPath;
|
this.objectPath = objectPath;
|
||||||
this.component = undefined;
|
this.component = undefined;
|
||||||
|
|
||||||
this.table = new TelemetryTable(domainObject, openmct);
|
Object.defineProperty(this, 'table', {
|
||||||
|
value: new TelemetryTable(domainObject, openmct),
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewContext() {
|
getViewContext() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -29,10 +29,6 @@ define(
|
|||||||
_,
|
_,
|
||||||
EventEmitter
|
EventEmitter
|
||||||
) {
|
) {
|
||||||
const LESS_THAN = -1;
|
|
||||||
const EQUAL = 0;
|
|
||||||
const GREATER_THAN = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
@@ -80,10 +76,7 @@ define(
|
|||||||
this.rows = [];
|
this.rows = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let row of rowsToAdd) {
|
this.sortAndMergeRows(rowsToAdd);
|
||||||
let index = this.sortedIndex(this.rows, row);
|
|
||||||
this.rows.splice(index, 0, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we emit filter no matter what to trigger
|
// we emit filter no matter what to trigger
|
||||||
// an update of visible rows
|
// an update of visible rows
|
||||||
@@ -92,58 +85,85 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sortedLastIndex(rows, testRow) {
|
sortAndMergeRows(rows) {
|
||||||
return this.sortedIndex(rows, testRow, _.sortedLastIndex);
|
const sortedRowsToAdd = this.sortCollection(rows);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the correct insertion point for the given row.
|
|
||||||
* Leverages lodash's `sortedIndex` function which implements a binary search.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
sortedIndex(rows, testRow, lodashFunction = _.sortedIndexBy) {
|
|
||||||
if (this.rows.length === 0) {
|
if (this.rows.length === 0) {
|
||||||
return 0;
|
this.rows = sortedRowsToAdd;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const testRowValue = this.getValueForSortColumn(testRow);
|
const firstIncomingRow = sortedRowsToAdd[0];
|
||||||
const firstValue = this.getValueForSortColumn(this.rows[0]);
|
const lastIncomingRow = sortedRowsToAdd[sortedRowsToAdd.length - 1];
|
||||||
const lastValue = this.getValueForSortColumn(this.rows[this.rows.length - 1]);
|
const firstExistingRow = this.rows[0];
|
||||||
|
const lastExistingRow = this.rows[this.rows.length - 1];
|
||||||
|
|
||||||
|
if (this.firstRowInSortOrder(lastIncomingRow, firstExistingRow)
|
||||||
|
=== lastIncomingRow
|
||||||
|
) {
|
||||||
|
this.rows = [...sortedRowsToAdd, ...this.rows];
|
||||||
|
} else if (this.firstRowInSortOrder(lastExistingRow, firstIncomingRow)
|
||||||
|
=== lastExistingRow
|
||||||
|
) {
|
||||||
|
this.rows = [...this.rows, ...sortedRowsToAdd];
|
||||||
|
} else {
|
||||||
|
this.mergeSortedRows(sortedRowsToAdd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortCollection(rows) {
|
||||||
|
const sortedRows = _.orderBy(
|
||||||
|
rows,
|
||||||
|
row => row.getParsedValue(this.sortOptions.key), this.sortOptions.direction
|
||||||
|
);
|
||||||
|
|
||||||
|
return sortedRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeSortedRows(rows) {
|
||||||
|
const mergedRows = [];
|
||||||
|
let i = 0;
|
||||||
|
let j = 0;
|
||||||
|
|
||||||
|
while (i < this.rows.length && j < rows.length) {
|
||||||
|
const iRow = this.rows[i];
|
||||||
|
const jRow = rows[j];
|
||||||
|
|
||||||
|
if (this.firstRowInSortOrder(iRow, jRow) === iRow) {
|
||||||
|
mergedRows.push(iRow);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
mergedRows.push(jRow);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tail of existing rows is all that is left to merge
|
||||||
|
if (i < this.rows.length) {
|
||||||
|
for (i; i < this.rows.length; i++) {
|
||||||
|
mergedRows.push(this.rows[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tail of incoming rows is all that is left to merge
|
||||||
|
if (j < rows.length) {
|
||||||
|
for (j; j < rows.length; j++) {
|
||||||
|
mergedRows.push(rows[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rows = mergedRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstRowInSortOrder(row1, row2) {
|
||||||
|
const val1 = this.getValueForSortColumn(row1);
|
||||||
|
const val2 = this.getValueForSortColumn(row2);
|
||||||
|
|
||||||
if (this.sortOptions.direction === 'asc') {
|
if (this.sortOptions.direction === 'asc') {
|
||||||
if (testRowValue > lastValue) {
|
return val1 <= val2 ? row1 : row2;
|
||||||
return this.rows.length;
|
|
||||||
} else if (testRowValue === lastValue) {
|
|
||||||
// Maintain stable sort
|
|
||||||
return this.rows.length;
|
|
||||||
} else if (testRowValue <= firstValue) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
} else {
|
||||||
return lodashFunction(rows, testRow, (thisRow) => {
|
return val1 >= val2 ? row1 : row2;
|
||||||
return this.getValueForSortColumn(thisRow);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (testRowValue >= firstValue) {
|
|
||||||
return 0;
|
|
||||||
} else if (testRowValue < lastValue) {
|
|
||||||
return this.rows.length;
|
|
||||||
} else if (testRowValue === lastValue) {
|
|
||||||
// Maintain stable sort
|
|
||||||
return this.rows.length;
|
|
||||||
} else {
|
|
||||||
// Use a custom comparison function to support descending sort.
|
|
||||||
return lodashFunction(rows, testRow, (thisRow) => {
|
|
||||||
const thisRowValue = this.getValueForSortColumn(thisRow);
|
|
||||||
if (testRowValue === thisRowValue) {
|
|
||||||
return EQUAL;
|
|
||||||
} else if (testRowValue < thisRowValue) {
|
|
||||||
return LESS_THAN;
|
|
||||||
} else {
|
|
||||||
return GREATER_THAN;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
export const COLOR_PALETTE = [
|
export const COLOR_PALETTE = [
|
||||||
[0x00, 0x37, 0xFF],
|
[0x43, 0xB0, 0xFF],
|
||||||
[0xF0, 0x60, 0x00],
|
[0xF0, 0x60, 0x00],
|
||||||
[0x00, 0x70, 0x40],
|
[0x00, 0x70, 0x40],
|
||||||
[0xFB, 0x49, 0x49],
|
[0xFB, 0x49, 0x49],
|
||||||
@@ -30,25 +30,25 @@ export const COLOR_PALETTE = [
|
|||||||
[0xFF, 0xA6, 0x3D],
|
[0xFF, 0xA6, 0x3D],
|
||||||
[0x05, 0xA3, 0x00],
|
[0x05, 0xA3, 0x00],
|
||||||
[0xF0, 0x00, 0x6C],
|
[0xF0, 0x00, 0x6C],
|
||||||
[0x77, 0x17, 0x7A],
|
[0xAC, 0x54, 0xAE],
|
||||||
[0x23, 0xA9, 0xDB],
|
[0x23, 0xA9, 0xDB],
|
||||||
[0xFA, 0xF0, 0x6F],
|
[0xC7, 0xBE, 0x52],
|
||||||
[0x4E, 0xF0, 0x48],
|
[0x5A, 0xBD, 0x56],
|
||||||
[0xAD, 0x50, 0x72],
|
[0xAD, 0x50, 0x72],
|
||||||
[0x94, 0x25, 0xEA],
|
[0x94, 0x25, 0xEA],
|
||||||
[0x21, 0x87, 0x82],
|
[0x21, 0x87, 0x82],
|
||||||
[0x8F, 0x6E, 0x47],
|
[0x8F, 0x6E, 0x47],
|
||||||
[0xf0, 0x59, 0xcb],
|
[0xf0, 0x59, 0xcb],
|
||||||
[0x34, 0xB6, 0x7D],
|
[0x34, 0xB6, 0x7D],
|
||||||
[0x6A, 0x36, 0xFF],
|
[0x7F, 0x52, 0xFF],
|
||||||
[0x56, 0xF0, 0xE8],
|
[0x46, 0xC7, 0xC0],
|
||||||
[0xA1, 0x8C, 0x1C],
|
[0xA1, 0x8C, 0x1C],
|
||||||
[0xCB, 0xE1, 0x44],
|
[0x95, 0xB1, 0x26],
|
||||||
[0xFF, 0x84, 0x9E],
|
[0xFF, 0x84, 0x9E],
|
||||||
[0xB7, 0x79, 0xE7],
|
[0xB7, 0x79, 0xE7],
|
||||||
[0x8C, 0xC9, 0xFD],
|
[0x8C, 0xC9, 0xFD],
|
||||||
[0xDB, 0xAA, 0x6E],
|
[0xDB, 0xAA, 0x6E],
|
||||||
[0xB8, 0xDF, 0x97],
|
[0x93, 0xB5, 0x77],
|
||||||
[0xFF, 0xBC, 0xDA],
|
[0xFF, 0xBC, 0xDA],
|
||||||
[0xD3, 0xB6, 0xDE]
|
[0xD3, 0xB6, 0xDE]
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -141,12 +141,16 @@ export default {
|
|||||||
this.openmct.objectViews.off('clearData', this.clearData);
|
this.openmct.objectViews.off('clearData', this.clearData);
|
||||||
},
|
},
|
||||||
getStyleReceiver() {
|
getStyleReceiver() {
|
||||||
let styleReceiver = this.$refs.objectViewWrapper.querySelector('.js-style-receiver')
|
let styleReceiver;
|
||||||
|
|
||||||
|
if (this.$refs.objectViewWrapper !== undefined) {
|
||||||
|
styleReceiver = this.$refs.objectViewWrapper.querySelector('.js-style-receiver')
|
||||||
|| this.$refs.objectViewWrapper.querySelector(':first-child');
|
|| this.$refs.objectViewWrapper.querySelector(':first-child');
|
||||||
|
|
||||||
if (styleReceiver === null) {
|
if (styleReceiver === null) {
|
||||||
styleReceiver = undefined;
|
styleReceiver = undefined;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return styleReceiver;
|
return styleReceiver;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -186,6 +186,10 @@ export default {
|
|||||||
return {
|
return {
|
||||||
name: field.name,
|
name: field.name,
|
||||||
value: field.path.reduce((object, key) => {
|
value: field.path.reduce((object, key) => {
|
||||||
|
if (object === undefined) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
return object[key];
|
return object[key];
|
||||||
}, this.domainObject)
|
}, this.domainObject)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -445,6 +445,10 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sorting composition items
|
// sorting composition items
|
||||||
|
if (!a.name || !b.name) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (a.name.toLowerCase()
|
if (a.name.toLowerCase()
|
||||||
> b.name.toLowerCase()) {
|
> b.name.toLowerCase()) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import objectPathToUrl from '/src/tools/url';
|
import objectPathToUrl from '../../tools/url';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
|||||||
Reference in New Issue
Block a user