Compare commits

...

13 Commits

Author SHA1 Message Date
24e7ea143a Added more details on the process around pull requests 2020-05-11 17:12:25 -07:00
4a87a5d847 Show object styles in preview modal (#3018)
* Adds conditional styles to Preview window
2020-05-11 14:25:39 -07:00
421c09ec2c Allow users to lazy load Tabs (#2958)
* lazy load tabs

* remove listener on destroy

* fix lint error

* Store current tab position on domainObject

* remove lodash dependency and use keystring
2020-05-08 10:36:13 -07:00
0679b246b8 [Notebook]: Remove default section/page from localstorage on notebook delete (#2900)
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-05-07 16:13:32 -07:00
83f9c6c528 improve plot gestures - and clean up (#3013) 2020-05-06 10:33:59 -07:00
a5f3ba6259 Use evalAsync instead of digest() (#3001)
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-05-05 12:23:41 -07:00
a70facf0c8 Merge pull request #3000 from nasa/upgrade-moment
Upgrade moment to 2.25.3
2020-05-05 11:01:39 -07:00
447fe94325 Merge branch 'upgrade-moment' of https://github.com/nasa/openmct into upgrade-moment 2020-05-05 10:36:43 -07:00
8e2b666766 Upgraded moment version to 2.25.3 2020-05-05 10:36:33 -07:00
dcbfbdbb89 Merge branch 'master' into upgrade-moment 2020-05-05 10:12:50 -07:00
4c76bf34ab Highlight currently winning Condition in Condition Set Edit and Read-only views (#2936)
* Preview condition styles on selecting that condition or one of it's styles

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-05-05 09:55:42 -07:00
81b7a9d3e0 Merge branch 'master' into upgrade-moment 2020-05-01 16:47:26 -07:00
dc573c479c Upgrade moment to 2.24.0 2020-05-01 16:25:49 -07:00
15 changed files with 202 additions and 57 deletions

View File

@ -103,7 +103,7 @@ the name chosen could not be mistaken for a topic or master branch.
### Merging ### Merging
When development is complete on an issue, the first step toward merging it When development is complete on an issue, the first step toward merging it
back into the master branch is to file a Pull Request. The contributions back into the master branch is to file a Pull Request (PR). The contributions
should meet code, test, and commit message standards as described below, should meet code, test, and commit message standards as described below,
and the pull request should include a completed author checklist, also and the pull request should include a completed author checklist, also
as described below. Pull requests may be assigned to specific team as described below. Pull requests may be assigned to specific team
@ -114,6 +114,12 @@ request. When the reviewer is satisfied, they should add a comment to
the pull request containing the reviewer checklist (from below) and complete the pull request containing the reviewer checklist (from below) and complete
the merge back to the master branch. the merge back to the master branch.
Additionally:
* Every pull request must link to the issue that it addresses. Eg. “Addresses #1234” or “Closes #1234”. This is the responsibility of the pull requests __author__. If no issue exists, create one.
* Every __author__ must include testing instructions. These instructions should identify the areas of code affected, and some minimal test steps. If addressing a bug, reproduction steps should be included, if they were not included in the original issue. If reproduction steps were included on the original issue, and are sufficient, refer to them.
* A pull request that closes an issue should say so in the description. Including the text “Closes #1234” will cause the linked issue to be automatically closed when the pull request is merged. This is the responsibility of the pull requests __author__.
* When a pull request is merged, and the corresponding issue closed, the __reviewer__ must add the tag “unverified” to the original issue. This will indicate that although the issue is closed, it has not been tested yet.
## Standards ## Standards
Contributions to Open MCT are expected to meet the following standards. Contributions to Open MCT are expected to meet the following standards.

View File

@ -53,9 +53,9 @@
"marked": "^0.3.5", "marked": "^0.3.5",
"mini-css-extract-plugin": "^0.4.1", "mini-css-extract-plugin": "^0.4.1",
"minimist": "^1.1.1", "minimist": "^1.1.1",
"moment": "^2.11.1", "moment": "2.25.3",
"moment-duration-format": "^2.2.2", "moment-duration-format": "^2.2.2",
"moment-timezone": "^0.5.21", "moment-timezone": "0.5.28",
"node-bourbon": "^4.2.3", "node-bourbon": "^4.2.3",
"node-sass": "^4.9.2", "node-sass": "^4.9.2",
"painterro": "^0.2.65", "painterro": "^0.2.65",

View File

@ -157,7 +157,6 @@ export default class StyleRuleManager extends EventEmitter {
delete this.stopProvidingTelemetry; delete this.stopProvidingTelemetry;
this.conditionSetIdentifier = undefined; this.conditionSetIdentifier = undefined;
this.isEditing = undefined; this.isEditing = undefined;
this.callback = undefined;
} }
} }

View File

@ -30,6 +30,7 @@
> >
<div class="c-condition-h__drop-target"></div> <div class="c-condition-h__drop-target"></div>
<div v-if="isEditing" <div v-if="isEditing"
:class="{'is-current': condition.id === currentConditionId}"
class="c-condition c-condition--edit" class="c-condition c-condition--edit"
> >
<!-- Edit view --> <!-- Edit view -->
@ -167,6 +168,7 @@
</div> </div>
<div v-else <div v-else
class="c-condition c-condition--browse" class="c-condition c-condition--browse"
:class="{'is-current': condition.id === currentConditionId}"
> >
<!-- Browse view --> <!-- Browse view -->
<div class="c-condition__header"> <div class="c-condition__header">
@ -199,6 +201,10 @@ export default {
ConditionDescription ConditionDescription
}, },
props: { props: {
currentConditionId: {
type: String,
default: ''
},
condition: { condition: {
type: Object, type: Object,
required: true required: true

View File

@ -58,6 +58,7 @@
<Condition v-for="(condition, index) in conditionCollection" <Condition v-for="(condition, index) in conditionCollection"
:key="condition.id" :key="condition.id"
:condition="condition" :condition="condition"
:current-condition-id="currentConditionId"
:condition-index="index" :condition-index="index"
:telemetry="telemetryObjs" :telemetry="telemetryObjs"
:is-editing="isEditing" :is-editing="isEditing"
@ -107,7 +108,8 @@ export default {
moveIndex: undefined, moveIndex: undefined,
isDragging: false, isDragging: false,
defaultOutput: undefined, defaultOutput: undefined,
dragCounter: 0 dragCounter: 0,
currentConditionId: ''
}; };
}, },
watch: { watch: {
@ -145,6 +147,7 @@ export default {
}, },
methods: { methods: {
handleConditionSetResultUpdated(data) { handleConditionSetResultUpdated(data) {
this.currentConditionId = data.conditionId;
this.$emit('conditionSetResultUpdated', data) this.$emit('conditionSetResultUpdated', data)
}, },
observeForChanges() { observeForChanges() {

View File

@ -190,6 +190,7 @@
} }
.c-condition { .c-condition {
border: 1px solid transparent;
flex-direction: column; flex-direction: column;
min-width: 400px; min-width: 400px;
@ -234,6 +235,12 @@
&__summary { &__summary {
flex: 1 1 auto; flex: 1 1 auto;
} }
&.is-current {
$c: $colorBodyFg;
border-color: rgba($c, 0.2);
background: rgba($c, 0.2);
}
} }
/***************************** CONDITION DEFINITION, EDITING */ /***************************** CONDITION DEFINITION, EDITING */

View File

@ -65,7 +65,7 @@
&.is-current { &.is-current {
$c: $colorBodyFg; $c: $colorBodyFg;
border-color: rgba($c, 0.5); border-color: rgba($c, 0.2);
background: rgba($c, 0.2); background: rgba($c, 0.2);
} }

View File

@ -29,7 +29,7 @@
<script> <script>
import Snapshot from '../snapshot'; import Snapshot from '../snapshot';
import { clearDefaultNotebook, getDefaultNotebook } from '../utils/notebook-storage'; import { getDefaultNotebook } from '../utils/notebook-storage';
import { NOTEBOOK_DEFAULT, NOTEBOOK_SNAPSHOT } from '../notebook-constants'; import { NOTEBOOK_DEFAULT, NOTEBOOK_SNAPSHOT } from '../notebook-constants';
export default { export default {
@ -72,27 +72,21 @@ export default {
methods: { methods: {
async setNotebookTypes() { async setNotebookTypes() {
const notebookTypes = []; const notebookTypes = [];
let defaultPath = '';
const defaultNotebook = getDefaultNotebook(); const defaultNotebook = getDefaultNotebook();
if (defaultNotebook) { if (defaultNotebook) {
const domainObject = await this.openmct.objects.get(defaultNotebook.notebookMeta.identifier) const domainObject = defaultNotebook.domainObject;
.then(d => d);
if (!domainObject.location) { if (domainObject.location) {
clearDefaultNotebook(); const defaultPath = `${domainObject.name} - ${defaultNotebook.section.name} - ${defaultNotebook.page.name}`;
} else {
defaultPath = `${domainObject.name} - ${defaultNotebook.section.name} - ${defaultNotebook.page.name}`;
}
}
if (defaultPath.length !== 0) {
notebookTypes.push({ notebookTypes.push({
cssClass: 'icon-notebook', cssClass: 'icon-notebook',
name: `Save to Notebook ${defaultPath}`, name: `Save to Notebook ${defaultPath}`,
type: NOTEBOOK_DEFAULT type: NOTEBOOK_DEFAULT
}); });
} }
}
notebookTypes.push({ notebookTypes.push({
cssClass: 'icon-notebook', cssClass: 'icon-notebook',

View File

@ -239,6 +239,7 @@ export default {
const section = this.getSelectedSection(); const section = this.getSelectedSection();
return { return {
domainObject: this.internalDomainObject,
notebookMeta, notebookMeta,
section, section,
page page
@ -440,7 +441,7 @@ export default {
async updateDefaultNotebook(notebookStorage) { async updateDefaultNotebook(notebookStorage) {
const defaultNotebookObject = await this.getDefaultNotebookObject(); const defaultNotebookObject = await this.getDefaultNotebookObject();
this.removeDefaultClass(defaultNotebookObject); this.removeDefaultClass(defaultNotebookObject);
setDefaultNotebook(notebookStorage); setDefaultNotebook(this.openmct, notebookStorage);
this.addDefaultClass(); this.addDefaultClass();
this.defaultSectionId = notebookStorage.section.id; this.defaultSectionId = notebookStorage.section.id;
this.defaultPageId = notebookStorage.page.id; this.defaultPageId = notebookStorage.page.id;

View File

@ -1,6 +1,46 @@
const NOTEBOOK_LOCAL_STORAGE = 'notebook-storage'; const NOTEBOOK_LOCAL_STORAGE = 'notebook-storage';
let currentNotebookObject = null;
let unlisten = null;
function defaultNotebookObjectChanged(newDomainObject) {
if (newDomainObject.location !== null) {
currentNotebookObject = newDomainObject;
const notebookStorage = getDefaultNotebook();
notebookStorage.domainObject = newDomainObject;
saveDefaultNotebook(notebookStorage);
return;
}
if (unlisten) {
unlisten();
unlisten = null;
}
clearDefaultNotebook();
}
function observeDefaultNotebookObject(openmct, notebookStorage) {
const domainObject = notebookStorage.domainObject;
if (currentNotebookObject
&& currentNotebookObject.identifier.key === domainObject.identifier.key) {
return;
}
if (unlisten) {
unlisten();
unlisten = null;
}
unlisten = openmct.objects.observe(notebookStorage.domainObject, '*', defaultNotebookObjectChanged);
}
function saveDefaultNotebook(notebookStorage) {
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage));
}
export function clearDefaultNotebook() { export function clearDefaultNotebook() {
currentNotebookObject = null;
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, null); window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, null);
} }
@ -10,20 +50,21 @@ export function getDefaultNotebook() {
return JSON.parse(notebookStorage); return JSON.parse(notebookStorage);
} }
export function setDefaultNotebook(notebookStorage) { export function setDefaultNotebook(openmct, notebookStorage) {
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage)); observeDefaultNotebookObject(openmct, notebookStorage);
saveDefaultNotebook(notebookStorage);
} }
export function setDefaultNotebookSection(section) { export function setDefaultNotebookSection(section) {
const notebookStorage = getDefaultNotebook(); const notebookStorage = getDefaultNotebook();
notebookStorage.section = section; notebookStorage.section = section;
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage)); saveDefaultNotebook(notebookStorage);
} }
export function setDefaultNotebookPage(page) { export function setDefaultNotebookPage(page) {
const notebookStorage = getDefaultNotebook(); const notebookStorage = getDefaultNotebook();
notebookStorage.page = page; notebookStorage.page = page;
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage)); saveDefaultNotebook(notebookStorage);
} }

View File

@ -67,10 +67,10 @@ define([
} }
this.$canvas = this.$element.find('canvas'); this.$canvas = this.$element.find('canvas');
this.listenTo(this.$canvas, 'click', this.onMouseClick, this);
this.listenTo(this.$canvas, 'mousemove', this.trackMousePosition, this); this.listenTo(this.$canvas, 'mousemove', this.trackMousePosition, this);
this.listenTo(this.$canvas, 'mouseleave', this.untrackMousePosition, this); this.listenTo(this.$canvas, 'mouseleave', this.untrackMousePosition, this);
this.listenTo(this.$canvas, 'mousedown', this.onMouseDown, this); this.listenTo(this.$canvas, 'mousedown', this.onMouseDown, this);
this.listenTo(this.$canvas, 'wheel', this.wheelZoom, this);
this.watchForMarquee(); this.watchForMarquee();
}; };
@ -78,7 +78,6 @@ define([
MCTPlotController.prototype.initialize = function () { MCTPlotController.prototype.initialize = function () {
this.$canvas = this.$element.find('canvas'); this.$canvas = this.$element.find('canvas');
this.listenTo(this.$canvas, 'click', this.onMouseClick, this);
this.listenTo(this.$canvas, 'mousemove', this.trackMousePosition, this); this.listenTo(this.$canvas, 'mousemove', this.trackMousePosition, this);
this.listenTo(this.$canvas, 'mouseleave', this.untrackMousePosition, this); this.listenTo(this.$canvas, 'mouseleave', this.untrackMousePosition, this);
this.listenTo(this.$canvas, 'mousedown', this.onMouseDown, this); this.listenTo(this.$canvas, 'mousedown', this.onMouseDown, this);
@ -210,23 +209,6 @@ define([
this.highlightValues(point); this.highlightValues(point);
}; };
MCTPlotController.prototype.onMouseClick = function ($event) {
const isClick = this.isMouseClick();
if (this.pan) {
this.endPan($event);
}
if (this.marquee) {
this.endMarquee($event);
}
this.$scope.$apply();
if (!this.$scope.highlights.length || !isClick) {
return;
}
this.$scope.lockHighlightPoint = !this.$scope.lockHighlightPoint;
};
MCTPlotController.prototype.highlightValues = function (point) { MCTPlotController.prototype.highlightValues = function (point) {
this.highlightPoint = point; this.highlightPoint = point;
this.$scope.$emit('plot:highlight:update', point); this.$scope.$emit('plot:highlight:update', point);
@ -274,11 +256,23 @@ define([
MCTPlotController.prototype.onMouseUp = function ($event) { MCTPlotController.prototype.onMouseUp = function ($event) {
this.stopListening(this.$window, 'mouseup', this.onMouseUp, this); this.stopListening(this.$window, 'mouseup', this.onMouseUp, this);
this.stopListening(this.$window, 'mousemove', this.trackMousePosition, this); this.stopListening(this.$window, 'mousemove', this.trackMousePosition, this);
if (this.isMouseClick()) {
this.$scope.lockHighlightPoint = !this.$scope.lockHighlightPoint;
}
if (this.allowPan) {
return this.endPan($event);
}
if (this.allowMarquee) {
return this.endMarquee($event);
}
}; };
MCTPlotController.prototype.isMouseClick = function () { MCTPlotController.prototype.isMouseClick = function () {
if (!this.marquee) { if (!this.marquee) {
return; return false;
} }
const { start, end } = this.marquee; const { start, end } = this.marquee;

View File

@ -227,8 +227,9 @@ define([
}; };
PlotController.prototype.stopLoading = function () { PlotController.prototype.stopLoading = function () {
this.$scope.$evalAsync(() => {
this.$scope.pending -= 1; this.$scope.pending -= 1;
this.$scope.$digest(); });
}; };
/** /**

View File

@ -27,7 +27,7 @@
{'is-current': isCurrent(tab)}, {'is-current': isCurrent(tab)},
tab.type.definition.cssClass tab.type.definition.cssClass
]" ]"
@click="showTab(tab)" @click="showTab(tab, index)"
> >
<span class="c-button__label">{{ tab.domainObject.name }}</span> <span class="c-button__label">{{ tab.domainObject.name }}</span>
</button> </button>
@ -48,6 +48,7 @@
</div> </div>
</div> </div>
<object-view <object-view
v-if="internalDomainObject.keep_alive ? currentTab : isCurrent(tab)"
class="c-tabs-view__object" class="c-tabs-view__object"
:object="tab.domainObject" :object="tab.domainObject"
/> />
@ -57,7 +58,6 @@
<script> <script>
import ObjectView from '../../../ui/components/ObjectView.vue'; import ObjectView from '../../../ui/components/ObjectView.vue';
import _ from 'lodash';
var unknownObjectType = { var unknownObjectType = {
definition: { definition: {
@ -73,6 +73,7 @@ export default {
}, },
data: function () { data: function () {
return { return {
internalDomainObject: this.domainObject,
currentTab: {}, currentTab: {},
tabsList: [], tabsList: [],
setCurrentTab: true, setCurrentTab: true,
@ -85,8 +86,16 @@ export default {
this.composition.on('add', this.addItem); this.composition.on('add', this.addItem);
this.composition.on('remove', this.removeItem); this.composition.on('remove', this.removeItem);
this.composition.on('reorder', this.onReorder); this.composition.on('reorder', this.onReorder);
this.composition.load(); this.composition.load().then(() => {
let currentTabIndex = this.domainObject.currentTabIndex;
if (currentTabIndex !== undefined && this.tabsList.length > currentTabIndex) {
this.currentTab = this.tabsList[currentTabIndex];
} }
});
}
this.unsubscribe = this.openmct.objects.observe(this.internalDomainObject, '*', this.updateInternalDomainObject);
document.addEventListener('dragstart', this.dragstart); document.addEventListener('dragstart', this.dragstart);
document.addEventListener('dragend', this.dragend); document.addEventListener('dragend', this.dragend);
@ -96,18 +105,25 @@ export default {
this.composition.off('remove', this.removeItem); this.composition.off('remove', this.removeItem);
this.composition.off('reorder', this.onReorder); this.composition.off('reorder', this.onReorder);
this.unsubscribe();
document.removeEventListener('dragstart', this.dragstart); document.removeEventListener('dragstart', this.dragstart);
document.removeEventListener('dragend', this.dragend); document.removeEventListener('dragend', this.dragend);
}, },
methods:{ methods:{
showTab(tab) { showTab(tab, index) {
if (index !== undefined) {
this.storeCurrentTabIndex(index);
}
this.currentTab = tab; this.currentTab = tab;
}, },
addItem(domainObject) { addItem(domainObject) {
let type = this.openmct.types.get(domainObject.type) || unknownObjectType, let type = this.openmct.types.get(domainObject.type) || unknownObjectType,
tabItem = { tabItem = {
domainObject, domainObject,
type: type type: type,
key: this.openmct.objects.makeKeyString(domainObject.identifier)
}; };
this.tabsList.push(tabItem); this.tabsList.push(tabItem);
@ -126,7 +142,7 @@ export default {
this.tabsList.splice(pos, 1); this.tabsList.splice(pos, 1);
if (this.isCurrent(tabToBeRemoved)) { if (this.isCurrent(tabToBeRemoved)) {
this.showTab(this.tabsList[this.tabsList.length - 1]); this.showTab(this.tabsList[this.tabsList.length - 1], this.tabsList.length - 1);
} }
}, },
onReorder(reorderPlan) { onReorder(reorderPlan) {
@ -138,6 +154,7 @@ export default {
}, },
onDrop(e) { onDrop(e) {
this.setCurrentTab = true; this.setCurrentTab = true;
this.storeCurrentTabIndex(this.tabsList.length);
}, },
dragstart(e) { dragstart(e) {
if (e.dataTransfer.types.includes('openmct/domain-object-path')) { if (e.dataTransfer.types.includes('openmct/domain-object-path')) {
@ -155,7 +172,13 @@ export default {
this.allowDrop = false; this.allowDrop = false;
}, },
isCurrent(tab) { isCurrent(tab) {
return _.isEqual(this.currentTab, tab) return this.currentTab.key === tab.key;
},
updateInternalDomainObject(domainObject) {
this.internalDomainObject = domainObject;
},
storeCurrentTabIndex(index) {
this.openmct.objects.mutate(this.internalDomainObject, 'currentTabIndex', index);
} }
} }
} }

View File

@ -36,7 +36,27 @@ define([
cssClass: 'icon-tabs-view', cssClass: 'icon-tabs-view',
initialize(domainObject) { initialize(domainObject) {
domainObject.composition = []; domainObject.composition = [];
domainObject.keep_alive = true;
},
form: [
{
"key": "keep_alive",
"name": "Keep Tabs Alive",
"control": "select",
"options": [
{
'name': 'True',
'value': true
},
{
'name': 'False',
'value': false
} }
],
"required": true,
"cssClass": "l-input"
}
]
}); });
}; };
}; };

View File

@ -35,6 +35,8 @@
<script> <script>
import PreviewHeader from './preview-header.vue'; import PreviewHeader from './preview-header.vue';
import {STYLE_CONSTANTS} from "@/plugins/condition/utils/constants";
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
export default { export default {
components: { components: {
@ -69,6 +71,14 @@ export default {
}, },
destroyed() { destroyed() {
this.view.destroy(); this.view.destroy();
if (this.stopListeningStyles) {
this.stopListeningStyles();
}
if (this.styleRuleManager) {
this.styleRuleManager.destroy();
delete this.styleRuleManager;
}
}, },
methods: { methods: {
clear() { clear() {
@ -90,6 +100,46 @@ export default {
this.view = this.currentView.view(this.domainObject, this.objectPath); this.view = this.currentView.view(this.domainObject, this.objectPath);
this.view.show(this.viewContainer, false); this.view.show(this.viewContainer, false);
this.initObjectStyles();
},
initObjectStyles() {
if (!this.styleRuleManager) {
this.styleRuleManager = new StyleRuleManager((this.domainObject.configuration && this.domainObject.configuration.objectStyles), this.openmct, this.updateStyle.bind(this));
} else {
this.styleRuleManager.updateObjectStyleConfig(this.domainObject.configuration && this.domainObject.configuration.objectStyles);
}
if (this.stopListeningStyles) {
this.stopListeningStyles();
}
this.stopListeningStyles = this.openmct.objects.observe(this.domainObject, 'configuration.objectStyles', (newObjectStyle) => {
//Updating styles in the inspector view will trigger this so that the changes are reflected immediately
this.styleRuleManager.updateObjectStyleConfig(newObjectStyle);
});
},
updateStyle(styleObj) {
if (!styleObj) {
return;
}
let keys = Object.keys(styleObj);
keys.forEach(key => {
let firstChild = this.$refs.objectView.querySelector(':first-child');
if (firstChild) {
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('__no_value') > -1)) {
if (firstChild.style[key]) {
firstChild.style[key] = '';
}
} else {
if (!styleObj.isStyleInvisible && firstChild.classList.contains(STYLE_CONSTANTS.isStyleInvisible)) {
firstChild.classList.remove(STYLE_CONSTANTS.isStyleInvisible);
} else if (styleObj.isStyleInvisible && !firstChild.classList.contains(styleObj.isStyleInvisible)) {
firstChild.classList.add(styleObj.isStyleInvisible);
}
firstChild.style[key] = styleObj[key];
}
}
});
} }
} }
} }