mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 20:57:53 +00:00
Feature/eslint plugin vue (#2548)
* Use eslint-plugin-vue to lint vue files
This commit is contained in:
parent
14ce5e159b
commit
14a0f84c1b
44
.eslintrc.js
44
.eslintrc.js
@ -5,9 +5,16 @@ module.exports = {
|
||||
"jasmine": true,
|
||||
"amd": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parser": "babel-eslint",
|
||||
"globals": {
|
||||
"_": "readonly"
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/recommended"
|
||||
],
|
||||
"parser": "vue-eslint-parser",
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint",
|
||||
"allowImportExportEverywhere": true,
|
||||
"ecmaVersion": 2015,
|
||||
"ecmaFeatures": {
|
||||
@ -58,7 +65,38 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
"dot-notation": "error",
|
||||
"indent": ["error", 4]
|
||||
"indent": ["error", 4],
|
||||
"vue/html-indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"attribute": 1,
|
||||
"baseIndent": 0,
|
||||
"closeBracket": 0,
|
||||
"alignAttributesVertically": true,
|
||||
"ignores": []
|
||||
}
|
||||
],
|
||||
"vue/html-self-closing": ["error",
|
||||
{
|
||||
"html": {
|
||||
"void": "never",
|
||||
"normal": "never",
|
||||
"component": "always"
|
||||
},
|
||||
"svg": "always",
|
||||
"math": "always"
|
||||
}
|
||||
],
|
||||
"vue/max-attributes-per-line": ["error", {
|
||||
"singleline": 1,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": true
|
||||
}
|
||||
}],
|
||||
"vue/multiline-html-element-content-newline": "off",
|
||||
"vue/singleline-html-element-content-newline": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
"d3-time": "1.0.x",
|
||||
"d3-time-format": "2.1.x",
|
||||
"eslint": "5.2.0",
|
||||
"eslint-plugin-vue": "^6.0.0",
|
||||
"eventemitter3": "^1.2.0",
|
||||
"exports-loader": "^0.7.0",
|
||||
"express": "^4.13.1",
|
||||
@ -74,8 +75,8 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
"lint": "eslint platform example src openmct.js",
|
||||
"lint:fix": "eslint platform example src openmct.js --fix",
|
||||
"lint": "eslint platform example src/**/*.{js,vue} openmct.js",
|
||||
"lint:fix": "eslint platform example src/**/*.{js,vue} openmct.js --fix",
|
||||
"build:prod": "NODE_ENV=production webpack",
|
||||
"build:dev": "webpack",
|
||||
"build:watch": "webpack --watch",
|
||||
|
@ -1,20 +1,24 @@
|
||||
<template>
|
||||
<div class="c-menu">
|
||||
<div class="c-menu">
|
||||
<ul>
|
||||
<li v-for="action in actions"
|
||||
<li
|
||||
v-for="action in actions"
|
||||
:key="action.name"
|
||||
:class="action.cssClass"
|
||||
:title="action.description"
|
||||
@click="action.invoke(objectPath)">
|
||||
@click="action.invoke(objectPath)"
|
||||
>
|
||||
{{ action.name }}
|
||||
</li>
|
||||
<li v-if="actions.length === 0">No actions defined.</li>
|
||||
<li v-if="actions.length === 0">
|
||||
No actions defined.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
export default {
|
||||
inject: ['actions', 'objectPath']
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,28 +1,36 @@
|
||||
<template>
|
||||
<div class="c-message">
|
||||
<div class="c-message">
|
||||
<!--Uses flex-row -->
|
||||
<div class="c-message__icon"
|
||||
:class="['u-icon-bg-color-' + iconClass]"></div>
|
||||
<div
|
||||
class="c-message__icon"
|
||||
:class="['u-icon-bg-color-' + iconClass]"
|
||||
></div>
|
||||
<div class="c-message__text">
|
||||
<!-- Uses flex-column -->
|
||||
<div class="c-message__title"
|
||||
v-if="title">
|
||||
{{title}}
|
||||
<div
|
||||
v-if="title"
|
||||
class="c-message__title"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
|
||||
<div class="c-message__hint"
|
||||
v-if="hint">
|
||||
{{hint}}
|
||||
<span v-if="timestamp">[{{timestamp}}]</span>
|
||||
<div
|
||||
v-if="hint"
|
||||
class="c-message__hint"
|
||||
>
|
||||
{{ hint }}
|
||||
<span v-if="timestamp">[{{ timestamp }}]</span>
|
||||
</div>
|
||||
|
||||
<div class="c-message__action-text"
|
||||
v-if="message">
|
||||
{{message}}
|
||||
<div
|
||||
v-if="message"
|
||||
class="c-message__action-text"
|
||||
>
|
||||
{{ message }}
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -1,28 +1,57 @@
|
||||
<template>
|
||||
<div class="c-overlay">
|
||||
<div class="c-overlay__blocker"
|
||||
@click="destroy">
|
||||
</div>
|
||||
<div class="c-overlay">
|
||||
<div
|
||||
class="c-overlay__blocker"
|
||||
@click="destroy"
|
||||
></div>
|
||||
<div class="c-overlay__outer">
|
||||
<button class="c-click-icon c-overlay__close-button icon-x-in-circle"
|
||||
<button
|
||||
v-if="dismissable"
|
||||
@click="destroy">
|
||||
</button>
|
||||
<div class="c-overlay__contents" ref="element" tabindex="0"></div>
|
||||
<div class="c-overlay__button-bar" v-if="buttons">
|
||||
<button class="c-button"
|
||||
tabindex="0"
|
||||
ref="buttons"
|
||||
class="c-click-icon c-overlay__close-button icon-x-in-circle"
|
||||
@click="destroy"
|
||||
></button>
|
||||
<div
|
||||
ref="element"
|
||||
class="c-overlay__contents"
|
||||
></div>
|
||||
<div
|
||||
v-if="buttons"
|
||||
class="c-overlay__button-bar"
|
||||
>
|
||||
<button
|
||||
v-for="(button, index) in buttons"
|
||||
:key="index"
|
||||
@focus="focusIndex=index"
|
||||
class="c-button"
|
||||
:class="{'c-button--major': button.emphasis}"
|
||||
@click="buttonClickHandler(button.callback)"
|
||||
>
|
||||
{{ button.label }}
|
||||
</button>
|
||||
<div
|
||||
ref="element"
|
||||
class="c-overlay__contents"
|
||||
tabindex="0"
|
||||
></div>
|
||||
<div
|
||||
v-if="buttons"
|
||||
class="c-overlay__button-bar"
|
||||
>
|
||||
<button
|
||||
v-for="(button, index) in buttons"
|
||||
ref="buttons"
|
||||
:key="index"
|
||||
class="c-button"
|
||||
tabindex="0"
|
||||
:class="{'c-button--major': focusIndex===index}"
|
||||
@click="buttonClickHandler(button.callback)">
|
||||
{{button.label}}
|
||||
@focus="focusIndex=index"
|
||||
@click="buttonClickHandler(button.callback)"
|
||||
>
|
||||
{{ button.label }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -174,7 +203,7 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
focusIndex: -1
|
||||
@ -200,7 +229,7 @@
|
||||
this.$emit('destroy');
|
||||
},
|
||||
getElementForFocus: function () {
|
||||
const defaultElement = this.$refs.element;;
|
||||
const defaultElement = this.$refs.element;
|
||||
if (!this.$refs.buttons) {
|
||||
return defaultElement;
|
||||
}
|
||||
@ -219,5 +248,5 @@
|
||||
return focusButton[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<dialog-component>
|
||||
<progress-component :model="model"></progress-component>
|
||||
</dialog-component>
|
||||
<dialog-component>
|
||||
<progress-component :model="model" />
|
||||
</dialog-component>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -14,9 +14,14 @@ import DialogComponent from './DialogComponent.vue';
|
||||
export default {
|
||||
components: {
|
||||
DialogComponent: DialogComponent,
|
||||
ProgressComponent: ProgressComponent,
|
||||
ProgressComponent: ProgressComponent
|
||||
},
|
||||
inject:['iconClass', 'title', 'hint', 'timestamp', 'message'],
|
||||
props:['model']
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -44,6 +44,7 @@ define([
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
LadTableSet: LadTableSet.default
|
||||
},
|
||||
@ -52,7 +53,6 @@ define([
|
||||
domainObject,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
template: '<lad-table-set></lad-table-set>'
|
||||
});
|
||||
},
|
||||
|
@ -44,6 +44,7 @@ define([
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
LadTableComponent: LadTableComponent.default
|
||||
},
|
||||
@ -52,7 +53,6 @@ define([
|
||||
domainObject,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
template: '<lad-table-component></lad-table-component>'
|
||||
});
|
||||
},
|
||||
|
@ -22,13 +22,13 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<tr @contextmenu.prevent="showContextMenu">
|
||||
<td>{{name}}</td>
|
||||
<td>{{timestamp}}</td>
|
||||
<tr @contextmenu.prevent="showContextMenu">
|
||||
<td>{{ name }}</td>
|
||||
<td>{{ timestamp }}</td>
|
||||
<td :class="valueClass">
|
||||
{{value}}
|
||||
{{ value }}
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -44,7 +44,12 @@ const CONTEXT_MENU_ACTIONS = [
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: ['domainObject'],
|
||||
props: {
|
||||
domainObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let currentObjectPath = this.objectPath.slice();
|
||||
currentObjectPath.unshift(this.domainObject);
|
||||
@ -57,48 +62,16 @@ export default {
|
||||
currentObjectPath
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateValues(datum) {
|
||||
this.timestamp = this.formats[this.timestampKey].format(datum);
|
||||
this.value = this.formats[this.valueKey].format(datum);
|
||||
|
||||
var limit = this.limitEvaluator.evaluate(datum, this.valueMetadata);
|
||||
|
||||
if (limit) {
|
||||
this.valueClass = limit.cssClass;
|
||||
} else {
|
||||
this.valueClass = '';
|
||||
}
|
||||
},
|
||||
updateName(name){
|
||||
this.name = name;
|
||||
},
|
||||
updateTimeSystem(timeSystem) {
|
||||
this.value = '---';
|
||||
this.timestamp = '---';
|
||||
this.valueClass = '';
|
||||
this.timestampKey = timeSystem.key;
|
||||
|
||||
this.openmct
|
||||
.telemetry
|
||||
.request(this.domainObject, {strategy: 'latest'})
|
||||
.then((array) => this.updateValues(array[array.length - 1]));
|
||||
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
|
||||
this.limitEvaluator = openmct
|
||||
this.limitEvaluator = this.openmct
|
||||
.telemetry
|
||||
.limitEvaluator(this.domainObject);
|
||||
|
||||
this.stopWatchingMutation = openmct
|
||||
this.stopWatchingMutation = this.openmct
|
||||
.objects
|
||||
.observe(
|
||||
this.domainObject,
|
||||
@ -129,6 +102,38 @@ export default {
|
||||
this.stopWatchingMutation();
|
||||
this.unsubscribe();
|
||||
this.openmct.off('timeSystem', this.updateTimeSystem);
|
||||
},
|
||||
methods: {
|
||||
updateValues(datum) {
|
||||
this.timestamp = this.formats[this.timestampKey].format(datum);
|
||||
this.value = this.formats[this.valueKey].format(datum);
|
||||
|
||||
var limit = this.limitEvaluator.evaluate(datum, this.valueMetadata);
|
||||
|
||||
if (limit) {
|
||||
this.valueClass = limit.cssClass;
|
||||
} else {
|
||||
this.valueClass = '';
|
||||
}
|
||||
},
|
||||
updateName(name) {
|
||||
this.name = name;
|
||||
},
|
||||
updateTimeSystem(timeSystem) {
|
||||
this.value = '---';
|
||||
this.timestamp = '---';
|
||||
this.valueClass = '';
|
||||
this.timestampKey = timeSystem.key;
|
||||
|
||||
this.openmct
|
||||
.telemetry
|
||||
.request(this.domainObject, {strategy: 'latest'})
|
||||
.then((array) => this.updateValues(array[array.length - 1]));
|
||||
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -33,14 +33,13 @@
|
||||
<lad-row
|
||||
v-for="item in items"
|
||||
:key="item.key"
|
||||
:domainObject="item.domainObject">
|
||||
</lad-row>
|
||||
:domain-object="item.domainObject"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import lodash from 'lodash';
|
||||
import LadRow from './LADRow.vue';
|
||||
|
||||
export default {
|
||||
@ -53,6 +52,18 @@ export default {
|
||||
items: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.reorder);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.reorder);
|
||||
},
|
||||
methods: {
|
||||
addItem(domainObject) {
|
||||
let item = {};
|
||||
@ -72,18 +83,6 @@ export default {
|
||||
this.$set(this.items, reorderEvent.newIndex, oldItems[reorderEvent.oldIndex]);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.reorder);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.reorder);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<table class="c-table c-lad-table">
|
||||
<table class="c-table c-lad-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
@ -31,19 +31,24 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<template
|
||||
v-for="primary in primaryTelemetryObjects">
|
||||
<tr class="c-table__group-header"
|
||||
:key="primary.key">
|
||||
<td colspan="10">{{primary.domainObject.name}}</td>
|
||||
v-for="primary in primaryTelemetryObjects"
|
||||
>
|
||||
<tr
|
||||
:key="primary.key"
|
||||
class="c-table__group-header"
|
||||
>
|
||||
<td colspan="10">
|
||||
{{ primary.domainObject.name }}
|
||||
</td>
|
||||
</tr>
|
||||
<lad-row
|
||||
v-for="secondary in secondaryTelemetryObjects[primary.key]"
|
||||
:key="secondary.key"
|
||||
:domainObject="secondary.domainObject">
|
||||
</lad-row>
|
||||
:domain-object="secondary.domainObject"
|
||||
/>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -51,10 +56,9 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import lodash from 'lodash';
|
||||
import LadRow from './LADRow.vue';
|
||||
import LadRow from './LADRow.vue';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject'],
|
||||
components: {
|
||||
LadRow
|
||||
@ -66,6 +70,22 @@
|
||||
compositions: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addPrimary);
|
||||
this.composition.on('remove', this.removePrimary);
|
||||
this.composition.on('reorder', this.reorderPrimary);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addPrimary);
|
||||
this.composition.off('remove', this.removePrimary);
|
||||
this.composition.off('reorder', this.reorderPrimary);
|
||||
this.compositions.forEach(c => {
|
||||
c.composition.off('add', c.addCallback);
|
||||
c.composition.off('remove', c.removeCallback);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
addPrimary(domainObject) {
|
||||
let primary = {};
|
||||
@ -75,7 +95,7 @@
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, []);
|
||||
this.primaryTelemetryObjects.push(primary);
|
||||
|
||||
let composition = openmct.composition.get(primary.domainObject),
|
||||
let composition = this.openmct.composition.get(primary.domainObject),
|
||||
addCallback = this.addSecondary(primary),
|
||||
removeCallback = this.removeSecondary(primary);
|
||||
|
||||
@ -121,23 +141,6 @@
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, array);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addPrimary);
|
||||
this.composition.on('remove', this.removePrimary);
|
||||
this.composition.on('reorder', this.reorderPrimary);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addPrimary);
|
||||
this.composition.off('remove', this.removePrimary);
|
||||
this.composition.off('reorder', this.reorderPrimary);
|
||||
this.compositions.forEach(c => {
|
||||
c.composition.off('add', c.addCallback);
|
||||
c.composition.off('remove', c.removeCallback);
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="c-indicator c-indicator--clickable icon-clear-data s-status-caution">
|
||||
<div class="c-indicator c-indicator--clickable icon-clear-data s-status-caution">
|
||||
<span class="label c-indicator__label">
|
||||
<button @click="globalClearEmit">Clear Data</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -55,11 +55,11 @@ define([
|
||||
openmct,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
components: {
|
||||
AlphanumericFormatView: AlphanumericFormatView.default
|
||||
},
|
||||
template: '<alphanumeric-format-view></alphanumeric-format-view>',
|
||||
el: element
|
||||
template: '<alphanumeric-format-view></alphanumeric-format-view>'
|
||||
});
|
||||
},
|
||||
destroy: function () {
|
||||
|
@ -21,37 +21,54 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-properties" v-if="isEditing">
|
||||
<div class="c-properties__header">Alphanumeric Format</div>
|
||||
<div
|
||||
v-if="isEditing"
|
||||
class="c-properties"
|
||||
>
|
||||
<div class="c-properties__header">
|
||||
Alphanumeric Format
|
||||
</div>
|
||||
<ul class="c-properties__section">
|
||||
<li class="c-properties__row">
|
||||
<div class="c-properties__label" title="Printf formatting for the selected telemetry">
|
||||
<div
|
||||
class="c-properties__label"
|
||||
title="Printf formatting for the selected telemetry"
|
||||
>
|
||||
<label for="telemetryPrintfFormat">Format</label>
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
<input id="telemetryPrintfFormat"
|
||||
<input
|
||||
id="telemetryPrintfFormat"
|
||||
type="text"
|
||||
@change="formatTelemetry"
|
||||
:value="telemetryFormat"
|
||||
:placeholder="nonMixedFormat ? '' : 'Mixed'"
|
||||
@change="formatTelemetry"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
let selectionPath = this.openmct.selection.get()[0];
|
||||
return {
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
telemetryFormat: undefined,
|
||||
nonMixedFormat: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', this.toggleEdit);
|
||||
this.openmct.selection.on('change', this.handleSelection);
|
||||
this.handleSelection(this.openmct.selection.get());
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.editor.off('isEditing', this.toggleEdit);
|
||||
this.openmct.selection.off('change', this.handleSelection);
|
||||
},
|
||||
methods: {
|
||||
toggleEdit(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
@ -75,16 +92,7 @@
|
||||
|
||||
this.telemetryFormat = this.nonMixedFormat ? format : '';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', this.toggleEdit);
|
||||
this.openmct.selection.on('change', this.handleSelection);
|
||||
this.handleSelection(this.openmct.selection.get());
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.editor.off('isEditing', this.toggleEdit);
|
||||
this.openmct.selection.off('change', this.handleSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
@ -21,15 +21,18 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-box-view"
|
||||
:style="style">
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
class="c-box-view"
|
||||
:style="style"
|
||||
></div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -44,10 +47,10 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
export default {
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#717171',
|
||||
@ -63,9 +66,20 @@
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
index: Number,
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean
|
||||
},
|
||||
computed: {
|
||||
@ -98,6 +112,5 @@
|
||||
this.removeSelectable();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
}
|
||||
</script>
|
||||
|
@ -21,42 +21,49 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout"
|
||||
<div
|
||||
class="l-layout"
|
||||
:class="{
|
||||
'is-multi-selected': selectedLayoutItems.length > 1
|
||||
}"
|
||||
@dragover="handleDragOver"
|
||||
@click.capture="bypassSelection"
|
||||
@drop="handleDrop"
|
||||
:class="{
|
||||
'is-multi-selected': selectedLayoutItems.length > 1
|
||||
}">
|
||||
>
|
||||
<!-- Background grid -->
|
||||
<div class="l-layout__grid-holder c-grid">
|
||||
<div class="c-grid__x l-grid l-grid-x"
|
||||
<div
|
||||
v-if="gridSize[0] >= 3"
|
||||
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
|
||||
</div>
|
||||
<div class="c-grid__y l-grid l-grid-y"
|
||||
class="c-grid__x l-grid l-grid-x"
|
||||
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]"
|
||||
></div>
|
||||
<div
|
||||
v-if="gridSize[1] >= 3"
|
||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
|
||||
class="c-grid__y l-grid l-grid-y"
|
||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"
|
||||
></div>
|
||||
</div>
|
||||
<component v-for="(item, index) in layoutItems"
|
||||
<component
|
||||
:is="item.type"
|
||||
:item="item"
|
||||
v-for="(item, index) in layoutItems"
|
||||
:key="item.id"
|
||||
:gridSize="gridSize"
|
||||
:initSelect="initSelectIndex === index"
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:init-select="initSelectIndex === index"
|
||||
:index="index"
|
||||
:multiSelect="selectedLayoutItems.length > 1"
|
||||
:multi-select="selectedLayoutItems.length > 1"
|
||||
@move="move"
|
||||
@endMove="endMove"
|
||||
@endLineResize='endLineResize'
|
||||
@formatChanged='updateTelemetryFormat'>
|
||||
</component>
|
||||
<edit-marquee v-if='showMarquee'
|
||||
:gridSize="gridSize"
|
||||
:selectedLayoutItems="selectedLayoutItems"
|
||||
@endResize="endResize">
|
||||
</edit-marquee>
|
||||
</div>
|
||||
@endLineResize="endLineResize"
|
||||
@formatChanged="updateTelemetryFormat"
|
||||
/>
|
||||
<edit-marquee
|
||||
v-if="showMarquee"
|
||||
:grid-size="gridSize"
|
||||
:selected-layout-items="selectedLayoutItems"
|
||||
@endResize="endResize"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -135,36 +142,36 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import uuid from 'uuid';
|
||||
import uuid from 'uuid';
|
||||
|
||||
import SubobjectView from './SubobjectView.vue'
|
||||
import TelemetryView from './TelemetryView.vue'
|
||||
import BoxView from './BoxView.vue'
|
||||
import TextView from './TextView.vue'
|
||||
import LineView from './LineView.vue'
|
||||
import ImageView from './ImageView.vue'
|
||||
import EditMarquee from './EditMarquee.vue'
|
||||
import SubobjectView from './SubobjectView.vue'
|
||||
import TelemetryView from './TelemetryView.vue'
|
||||
import BoxView from './BoxView.vue'
|
||||
import TextView from './TextView.vue'
|
||||
import LineView from './LineView.vue'
|
||||
import ImageView from './ImageView.vue'
|
||||
import EditMarquee from './EditMarquee.vue'
|
||||
|
||||
const ITEM_TYPE_VIEW_MAP = {
|
||||
const ITEM_TYPE_VIEW_MAP = {
|
||||
'subobject-view': SubobjectView,
|
||||
'telemetry-view': TelemetryView,
|
||||
'box-view': BoxView,
|
||||
'line-view': LineView,
|
||||
'text-view': TextView,
|
||||
'image-view': ImageView
|
||||
};
|
||||
const ORDERS = {
|
||||
};
|
||||
const ORDERS = {
|
||||
top: Number.POSITIVE_INFINITY,
|
||||
up: 1,
|
||||
down: -1,
|
||||
bottom: Number.NEGATIVE_INFINITY
|
||||
};
|
||||
const DRAG_OBJECT_TRANSFER_PREFIX = 'openmct/domain-object/';
|
||||
};
|
||||
const DRAG_OBJECT_TRANSFER_PREFIX = 'openmct/domain-object/';
|
||||
|
||||
let components = ITEM_TYPE_VIEW_MAP;
|
||||
components['edit-marquee'] = EditMarquee;
|
||||
let components = ITEM_TYPE_VIEW_MAP;
|
||||
components['edit-marquee'] = EditMarquee;
|
||||
|
||||
function getItemDefinition(itemType, ...options) {
|
||||
function getItemDefinition(itemType, ...options) {
|
||||
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
|
||||
|
||||
if (!itemView) {
|
||||
@ -172,9 +179,16 @@
|
||||
}
|
||||
|
||||
return itemView.makeDefinition(...options);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
export default {
|
||||
components: components,
|
||||
props: {
|
||||
domainObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
|
||||
return {
|
||||
@ -203,8 +217,23 @@
|
||||
}
|
||||
},
|
||||
inject: ['openmct', 'options', 'objectPath'],
|
||||
props: ['domainObject'],
|
||||
components: components,
|
||||
mounted() {
|
||||
this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', function (obj) {
|
||||
this.internalDomainObject = JSON.parse(JSON.stringify(obj));
|
||||
}.bind(this));
|
||||
this.openmct.selection.on('change', this.setSelection);
|
||||
this.initializeItems();
|
||||
this.composition = this.openmct.composition.get(this.internalDomainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
this.composition.off('add', this.addChild);
|
||||
this.composition.off('remove', this.removeChild);
|
||||
this.unlisten();
|
||||
},
|
||||
methods: {
|
||||
addElement(itemType, element) {
|
||||
this.addItem(itemType + '-view', element);
|
||||
@ -281,11 +310,10 @@
|
||||
});
|
||||
}
|
||||
|
||||
let layoutItems = this.layoutItems.map(item => {
|
||||
this.layoutItems.forEach(item => {
|
||||
if (this.initialPositions[item.id]) {
|
||||
this.updateItemPosition(item, gridDelta);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
},
|
||||
updateItemPosition(item, gridDelta) {
|
||||
@ -380,7 +408,7 @@
|
||||
|
||||
// If the layout already contains the given object, then shortcut the default dragover behavior and
|
||||
// potentially allow drop. Display layouts allow drag drop of duplicate telemetry objects.
|
||||
if (this.containsObject(draggedKeyString)){
|
||||
if (this.containsObject(draggedKeyString)) {
|
||||
$event.preventDefault();
|
||||
}
|
||||
},
|
||||
@ -492,7 +520,6 @@
|
||||
orderItem(position, selectedItems) {
|
||||
let delta = ORDERS[position];
|
||||
let indices = [];
|
||||
let newIndex = -1;
|
||||
let items = [];
|
||||
|
||||
Object.assign(items, this.layoutItems);
|
||||
@ -564,23 +591,6 @@
|
||||
item.format = format;
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', function (obj) {
|
||||
this.internalDomainObject = JSON.parse(JSON.stringify(obj));
|
||||
}.bind(this));
|
||||
this.openmct.selection.on('change', this.setSelection);
|
||||
this.initializeItems();
|
||||
this.composition = this.openmct.composition.get(this.internalDomainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
this.composition.off('add', this.addChild);
|
||||
this.composition.off('remove', this.removeChild);
|
||||
this.unlisten();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,17 +21,28 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<!-- Resize handles -->
|
||||
<div class="c-frame-edit" :style="style">
|
||||
<div class="c-frame-edit__handle c-frame-edit__handle--nw"
|
||||
@mousedown="startResize([1,1], [-1,-1], $event)"></div>
|
||||
<div class="c-frame-edit__handle c-frame-edit__handle--ne"
|
||||
@mousedown="startResize([0,1], [1,-1], $event)"></div>
|
||||
<div class="c-frame-edit__handle c-frame-edit__handle--sw"
|
||||
@mousedown="startResize([1,0], [-1,1], $event)"></div>
|
||||
<div class="c-frame-edit__handle c-frame-edit__handle--se"
|
||||
@mousedown="startResize([0,0], [1,1], $event)"></div>
|
||||
</div>
|
||||
<!-- Resize handles -->
|
||||
<div
|
||||
class="c-frame-edit"
|
||||
:style="marqueeStyle"
|
||||
>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--nw"
|
||||
@mousedown="startResize([1,1], [-1,-1], $event)"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--ne"
|
||||
@mousedown="startResize([0,1], [1,-1], $event)"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--sw"
|
||||
@mousedown="startResize([1,0], [-1,1], $event)"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--se"
|
||||
@mousedown="startResize([0,0], [1,1], $event)"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -95,13 +106,21 @@
|
||||
|
||||
|
||||
<script>
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
selectedLayoutItems: Array,
|
||||
gridSize: Array
|
||||
selectedLayoutItems: {
|
||||
type: Array,
|
||||
default: undefined
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -109,7 +128,7 @@
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
marqueePosition() {
|
||||
let x = Number.POSITIVE_INFINITY;
|
||||
let y = Number.POSITIVE_INFINITY;
|
||||
let width = Number.NEGATIVE_INFINITY;
|
||||
@ -145,24 +164,23 @@
|
||||
height = height - y;
|
||||
}
|
||||
|
||||
this.marqueePosition = {
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height
|
||||
}
|
||||
return this.getMarqueeStyle(x, y, width, height);
|
||||
},
|
||||
marqueeStyle() {
|
||||
return {
|
||||
left: (this.gridSize[0] * this.marqueePosition.x) + 'px',
|
||||
top: (this.gridSize[1] * this.marqueePosition.y) + 'px',
|
||||
width: (this.gridSize[0] * this.marqueePosition.width) + 'px',
|
||||
height: (this.gridSize[1] * this.marqueePosition.height) + 'px'
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMarqueeStyle(x, y, width, height) {
|
||||
return {
|
||||
left: (this.gridSize[0] * x) + 'px',
|
||||
top: (this.gridSize[1] * y) + 'px',
|
||||
width: (this.gridSize[0] * width) + 'px',
|
||||
height: (this.gridSize[1] * height) + 'px'
|
||||
};
|
||||
},
|
||||
updatePosition(event) {
|
||||
let currentPosition = [event.pageX, event.pageY];
|
||||
this.initialPosition = this.initialPosition || currentPosition;
|
||||
@ -229,5 +247,5 @@
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,15 +21,18 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-image-view"
|
||||
:style="style">
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
class="c-image-view"
|
||||
:style="style"
|
||||
></div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -46,10 +49,10 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
export default {
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
stroke: 'transparent',
|
||||
@ -61,15 +64,26 @@
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
index: Number,
|
||||
initSelect: Boolean
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
@ -100,5 +114,5 @@
|
||||
this.removeSelectable();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
|
@ -21,19 +21,21 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout__frame c-frame"
|
||||
<div
|
||||
class="l-layout__frame c-frame"
|
||||
:class="{
|
||||
'no-frame': !item.hasFrame,
|
||||
'u-inspectable': inspectable
|
||||
}"
|
||||
:style="style">
|
||||
|
||||
:style="style"
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
<div class="c-frame-edit__move"
|
||||
@mousedown="startMove([1,1], [0,0], $event)">
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c-frame-edit__move"
|
||||
@mousedown="startMove([1,1], [0,0], $event)"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -173,13 +175,21 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
@ -241,5 +251,5 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,45 +21,60 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout__frame c-frame no-frame"
|
||||
:style="style">
|
||||
<svg width="100%" height="100%">
|
||||
<line v-bind="linePosition"
|
||||
<div
|
||||
class="l-layout__frame c-frame no-frame"
|
||||
:style="style"
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
>
|
||||
<line
|
||||
v-bind="linePosition"
|
||||
:stroke="item.stroke"
|
||||
stroke-width="2">
|
||||
</line>
|
||||
stroke-width="2"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<div class="c-frame-edit__move"
|
||||
@mousedown="startDrag($event)"></div>
|
||||
<div class="c-frame-edit" v-if="showFrameEdit">
|
||||
<div class="c-frame-edit__handle"
|
||||
<div
|
||||
class="c-frame-edit__move"
|
||||
@mousedown="startDrag($event)"
|
||||
></div>
|
||||
<div
|
||||
v-if="showFrameEdit"
|
||||
class="c-frame-edit"
|
||||
>
|
||||
<div
|
||||
class="c-frame-edit__handle"
|
||||
:class="startHandleClass"
|
||||
@mousedown="startDrag($event, 'start')"></div>
|
||||
<div class="c-frame-edit__handle"
|
||||
@mousedown="startDrag($event, 'start')"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle"
|
||||
:class="endHandleClass"
|
||||
@mousedown="startDrag($event, 'end')"></div>
|
||||
</div>
|
||||
@mousedown="startDrag($event, 'end')"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
|
||||
const START_HANDLE_QUADRANTS = {
|
||||
const START_HANDLE_QUADRANTS = {
|
||||
1: 'c-frame-edit__handle--sw',
|
||||
2: 'c-frame-edit__handle--se',
|
||||
3: 'c-frame-edit__handle--ne',
|
||||
4: 'c-frame-edit__handle--nw'
|
||||
};
|
||||
};
|
||||
|
||||
const END_HANDLE_QUADRANTS = {
|
||||
const END_HANDLE_QUADRANTS = {
|
||||
1: 'c-frame-edit__handle--ne',
|
||||
2: 'c-frame-edit__handle--nw',
|
||||
3: 'c-frame-edit__handle--sw',
|
||||
4: 'c-frame-edit__handle--se'
|
||||
};
|
||||
};
|
||||
|
||||
export default {
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
x: 5,
|
||||
@ -71,10 +86,21 @@
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
initSelect: Boolean,
|
||||
index: Number,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
multiSelect: Boolean
|
||||
},
|
||||
data() {
|
||||
@ -106,7 +132,7 @@
|
||||
left: `${left}px`,
|
||||
top: `${top}px`,
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
height: `${height}px`
|
||||
};
|
||||
},
|
||||
startHandleClass() {
|
||||
@ -129,39 +155,46 @@
|
||||
return 3;
|
||||
},
|
||||
linePosition() {
|
||||
if (this.vectorQuadrant === 1) {
|
||||
return {
|
||||
return this.vectorQuadrant % 2 !== 0
|
||||
// odd vectorQuadrant slopes up
|
||||
? {
|
||||
x1: '0%',
|
||||
y1: '100%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
};
|
||||
}
|
||||
if (this.vectorQuadrant === 4) {
|
||||
return {
|
||||
// even vectorQuadrant slopes down
|
||||
: {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
};
|
||||
}
|
||||
if (this.vectorQuadrant === 2) {
|
||||
return {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.setSelection);
|
||||
this.context = {
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
if (this.vectorQuadrant === 3) {
|
||||
return {
|
||||
x1: '100%',
|
||||
y1: '0%',
|
||||
x2: '0%',
|
||||
y2: '100%'
|
||||
};
|
||||
}
|
||||
}
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
},
|
||||
methods: {
|
||||
startDrag(event, position) {
|
||||
@ -235,30 +268,6 @@
|
||||
return Math.round(v / this.gridSize[i]);
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.setSelection);
|
||||
this.context = {
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
|
@ -20,44 +20,47 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:title="domainObject && domainObject.name"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<object-frame v-if="domainObject"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<object-frame
|
||||
v-if="domainObject"
|
||||
ref="objectFrame"
|
||||
:domain-object="domainObject"
|
||||
:object-path="currentObjectPath"
|
||||
:has-frame="item.hasFrame"
|
||||
:show-edit-view="false"
|
||||
ref="objectFrame">
|
||||
</object-frame>
|
||||
</layout-frame>
|
||||
/>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ObjectFrame from '../../../ui/components/ObjectFrame.vue'
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
import ObjectFrame from '../../../ui/components/ObjectFrame.vue'
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
const MINIMUM_FRAME_SIZE = [320, 180],
|
||||
const MINIMUM_FRAME_SIZE = [320, 180],
|
||||
DEFAULT_DIMENSIONS = [10, 10],
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
DEFAULT_HIDDEN_FRAME_TYPES = ['hyperlink', 'summary-widget'];
|
||||
|
||||
function getDefaultDimensions(gridSize) {
|
||||
function getDefaultDimensions(gridSize) {
|
||||
return MINIMUM_FRAME_SIZE.map((min, index) => {
|
||||
return Math.max(
|
||||
Math.ceil(min / gridSize[index]),
|
||||
DEFAULT_DIMENSIONS[index]
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function hasFrameByDefault(type) {
|
||||
function hasFrameByDefault(type) {
|
||||
return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let defaultDimensions = getDefaultDimensions(gridSize);
|
||||
position = position || DEFAULT_POSITION;
|
||||
@ -72,11 +75,26 @@
|
||||
};
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
components: {
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
initSelect: Boolean,
|
||||
index: Number
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -84,10 +102,6 @@
|
||||
currentObjectPath: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
@ -97,6 +111,15 @@
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
@ -111,15 +134,6 @@
|
||||
this.$el, this.context, this.initSelect);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -20,29 +20,41 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
<template>
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-telemetry-view"
|
||||
:style="styleObject"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
v-if="domainObject"
|
||||
@contextmenu.prevent="showContextMenu">
|
||||
<div v-if="showLabel"
|
||||
class="c-telemetry-view__label">
|
||||
<div class="c-telemetry-view__label-text">{{ domainObject.name }}</div>
|
||||
class="c-telemetry-view"
|
||||
:style="styleObject"
|
||||
@contextmenu.prevent="showContextMenu"
|
||||
>
|
||||
<div
|
||||
v-if="showLabel"
|
||||
class="c-telemetry-view__label"
|
||||
>
|
||||
<div class="c-telemetry-view__label-text">
|
||||
{{ domainObject.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showValue"
|
||||
<div
|
||||
v-if="showValue"
|
||||
:title="fieldName"
|
||||
class="c-telemetry-view__value"
|
||||
:class="[telemetryClass]">
|
||||
<div class="c-telemetry-view__value-text">{{ telemetryValue }}</div>
|
||||
:class="[telemetryClass]"
|
||||
>
|
||||
<div class="c-telemetry-view__value-text">
|
||||
{{ telemetryValue }}
|
||||
</div>
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -78,15 +90,15 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
import printj from 'printj'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
import printj from 'printj'
|
||||
|
||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
|
||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
CONTEXT_MENU_ACTIONS = ['viewHistoricalData'];
|
||||
|
||||
export default {
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||
position = position || DEFAULT_POSITION;
|
||||
@ -106,15 +118,34 @@
|
||||
};
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
initSelect: Boolean,
|
||||
index: Number
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
initSelect: Boolean,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
datum: undefined,
|
||||
formats: undefined,
|
||||
domainObject: undefined,
|
||||
currentObjectPath: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showLabel() {
|
||||
let displayMode = this.item.displayMode;
|
||||
@ -161,14 +192,6 @@
|
||||
return alarm && alarm.cssClass;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
datum: undefined,
|
||||
formats: undefined,
|
||||
domainObject: undefined,
|
||||
currentObjectPath: undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
@ -181,6 +204,20 @@
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
this.openmct.time.on("bounds", this.refreshData);
|
||||
},
|
||||
destroyed() {
|
||||
this.removeSubscription();
|
||||
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
this.openmct.time.off("bounds", this.refreshData);
|
||||
},
|
||||
methods: {
|
||||
requestHistoricalData() {
|
||||
let bounds = this.openmct.time.bounds();
|
||||
@ -246,21 +283,7 @@
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
this.openmct.time.on("bounds", this.refreshData);
|
||||
},
|
||||
destroyed() {
|
||||
this.removeSubscription();
|
||||
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
}
|
||||
|
||||
this.openmct.time.off("bounds", this.refreshData);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
@ -20,17 +20,21 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
<template>
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-text-view"
|
||||
:style="style">
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
class="c-text-view"
|
||||
:style="style"
|
||||
>
|
||||
{{ item.text }}
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -46,10 +50,10 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
export default {
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
fill: 'transparent',
|
||||
@ -64,15 +68,26 @@
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
index: Number,
|
||||
initSelect: Boolean
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
@ -105,6 +120,5 @@
|
||||
this.removeSelectable();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
}
|
||||
</script>
|
||||
|
@ -42,22 +42,22 @@ export default function DisplayLayoutPlugin(options) {
|
||||
return {
|
||||
show(container) {
|
||||
component = new Vue({
|
||||
el: container,
|
||||
components: {
|
||||
Layout
|
||||
},
|
||||
template: '<layout ref="displayLayout" :domain-object="domainObject"></layout>',
|
||||
provide: {
|
||||
openmct,
|
||||
objectUtils,
|
||||
options,
|
||||
objectPath
|
||||
},
|
||||
el: container,
|
||||
data() {
|
||||
return {
|
||||
domainObject: domainObject
|
||||
};
|
||||
}
|
||||
},
|
||||
template: '<layout ref="displayLayout" :domain-object="domainObject"></layout>'
|
||||
});
|
||||
},
|
||||
getSelectionContext() {
|
||||
|
@ -48,11 +48,11 @@ define([
|
||||
provide: {
|
||||
openmct
|
||||
},
|
||||
el: element,
|
||||
components: {
|
||||
FiltersView: FiltersView.default
|
||||
},
|
||||
template: '<filters-view></filters-view>',
|
||||
el: element
|
||||
template: '<filters-view></filters-view>'
|
||||
});
|
||||
},
|
||||
destroy: function () {
|
||||
|
@ -1,35 +1,45 @@
|
||||
<template>
|
||||
<div class="c-properties__section c-filter-settings">
|
||||
<li class="c-properties__row c-filter-settings__setting"
|
||||
<div class="c-properties__section c-filter-settings">
|
||||
<li
|
||||
v-for="(filter, index) in filterField.filters"
|
||||
:key="index">
|
||||
<div class="c-properties__label label"
|
||||
:disabled="useGlobal">
|
||||
:key="index"
|
||||
class="c-properties__row c-filter-settings__setting"
|
||||
>
|
||||
<div
|
||||
class="c-properties__label label"
|
||||
:disabled="useGlobal"
|
||||
>
|
||||
{{ filterField.name }} =
|
||||
</div>
|
||||
<div class="c-properties__value value">
|
||||
<!-- EDITING -->
|
||||
<!-- String input, editing -->
|
||||
<template v-if="!filter.possibleValues && isEditing">
|
||||
<input class="c-input--flex"
|
||||
type="text"
|
||||
<input
|
||||
:id="`${filter}filterControl`"
|
||||
class="c-input--flex"
|
||||
type="text"
|
||||
:disabled="useGlobal"
|
||||
:value="persistedValue(filter)"
|
||||
@change="updateFilterValue($event, filter)">
|
||||
@change="updateFilterValue($event, filter)"
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- Checkbox list, editing -->
|
||||
<template v-if="filter.possibleValues && isEditing">
|
||||
<div class="c-checkbox-list__row"
|
||||
<div
|
||||
v-for="option in filter.possibleValues"
|
||||
:key="option.value">
|
||||
<input class="c-checkbox-list__input"
|
||||
type="checkbox"
|
||||
:key="option.value"
|
||||
class="c-checkbox-list__row"
|
||||
>
|
||||
<input
|
||||
:id="`${option.value}filterControl`"
|
||||
class="c-checkbox-list__input"
|
||||
type="checkbox"
|
||||
:disabled="useGlobal"
|
||||
:checked="isChecked(filter.comparator, option.value)"
|
||||
@change="updateFilterValue($event, filter.comparator, option.value)"
|
||||
:checked="isChecked(filter.comparator, option.value)">
|
||||
>
|
||||
<span class="c-checkbox-list__value">
|
||||
{{ option.label }}
|
||||
</span>
|
||||
@ -50,7 +60,7 @@
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -59,7 +69,10 @@ export default {
|
||||
'openmct'
|
||||
],
|
||||
props: {
|
||||
filterField: Object,
|
||||
filterField: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
useGlobal: Boolean,
|
||||
persistedFilters: {
|
||||
type: Object,
|
||||
@ -73,6 +86,12 @@ export default {
|
||||
isEditing: this.openmct.editor.isEditing()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', this.toggleIsEditing);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.openmct.editor.off('isEditing', this.toggleIsEditing);
|
||||
},
|
||||
methods: {
|
||||
toggleIsEditing(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
@ -107,12 +126,6 @@ export default {
|
||||
return accum;
|
||||
}, []).join(', ');
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', this.toggleIsEditing);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.openmct.editor.off('isEditing', this.toggleIsEditing);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,50 +1,62 @@
|
||||
<template>
|
||||
<li class="c-tree__item-h">
|
||||
<div class="c-tree__item menus-to-left"
|
||||
@click="toggleExpanded">
|
||||
<div class="c-filter-tree-item__filter-indicator"
|
||||
:class="{'icon-filter': hasActiveFilters }"></div>
|
||||
<span class="c-disclosure-triangle is-enabled flex-elem"
|
||||
:class="{'c-disclosure-triangle--expanded': expanded}"></span>
|
||||
<li class="c-tree__item-h">
|
||||
<div
|
||||
class="c-tree__item menus-to-left"
|
||||
@click="toggleExpanded"
|
||||
>
|
||||
<div
|
||||
class="c-filter-tree-item__filter-indicator"
|
||||
:class="{'icon-filter': hasActiveFilters }"
|
||||
></div>
|
||||
<span
|
||||
class="c-disclosure-triangle is-enabled flex-elem"
|
||||
:class="{'c-disclosure-triangle--expanded': expanded}"
|
||||
></span>
|
||||
<div class="c-tree__item__label c-object-label">
|
||||
<div class="c-object-label">
|
||||
<div class="c-object-label__type-icon"
|
||||
:class="objectCssClass">
|
||||
<div
|
||||
class="c-object-label__type-icon"
|
||||
:class="objectCssClass"
|
||||
></div>
|
||||
<div class="c-object-label__name flex-elem grows">
|
||||
{{ filterObject.name }}
|
||||
</div>
|
||||
<div class="c-object-label__name flex-elem grows">{{ filterObject.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="expanded">
|
||||
<ul class="c-properties">
|
||||
<div class="c-properties__label span-all"
|
||||
v-if="!isEditing && persistedFilters.useGlobal">
|
||||
<div
|
||||
v-if="!isEditing && persistedFilters.useGlobal"
|
||||
class="c-properties__label span-all"
|
||||
>
|
||||
Uses global filter
|
||||
</div>
|
||||
|
||||
<div class="c-properties__label span-all"
|
||||
v-if="isEditing">
|
||||
<div
|
||||
v-if="isEditing"
|
||||
class="c-properties__label span-all"
|
||||
>
|
||||
<toggle-switch
|
||||
:id="keyString"
|
||||
:checked="persistedFilters.useGlobal"
|
||||
@change="useGlobalFilter"
|
||||
:checked="persistedFilters.useGlobal">
|
||||
</toggle-switch>
|
||||
/>
|
||||
Use global filter
|
||||
</div>
|
||||
<filter-field
|
||||
v-if="(!persistedFilters.useGlobal && !isEditing) || isEditing"
|
||||
v-for="metadatum in filterObject.metadataWithFilters"
|
||||
v-for="metadatum in activeFilters"
|
||||
:key="metadatum.key"
|
||||
:filterField="metadatum"
|
||||
:useGlobal="persistedFilters.useGlobal"
|
||||
:persistedFilters="updatedFilters[metadatum.key]"
|
||||
:filter-field="metadatum"
|
||||
:use-global="persistedFilters.useGlobal"
|
||||
:persisted-filters="updatedFilters[metadatum.key]"
|
||||
@filterSelected="updateFiltersWithSelectedValue"
|
||||
@filterTextValueChanged="updateFiltersWithTextValue">
|
||||
</filter-field>
|
||||
@filterTextValueChanged="updateFiltersWithTextValue"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -58,7 +70,10 @@ export default {
|
||||
ToggleSwitch
|
||||
},
|
||||
props: {
|
||||
filterObject: Object,
|
||||
filterObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
persistedFilters: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
@ -74,6 +89,23 @@ export default {
|
||||
isEditing: this.openmct.editor.isEditing()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// do not show filter fields if using global filter
|
||||
// if editing however, show all filter fields
|
||||
activeFilters() {
|
||||
if (!this.isEditing && this.persistedFilters.useGlobal) {
|
||||
return []
|
||||
}
|
||||
|
||||
return this.filterObject.metadataWithFilters
|
||||
},
|
||||
hasActiveFilters() {
|
||||
// Should be true when the user has entered any filter values.
|
||||
return Object.values(this.persistedFilters).some(comparator => {
|
||||
return (typeof(comparator) === 'object' && !_.isEmpty(comparator));
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
persistedFilters: {
|
||||
handler: function checkFilters(newpersistedFilters) {
|
||||
@ -82,13 +114,14 @@ export default {
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasActiveFilters() {
|
||||
// Should be true when the user has entered any filter values.
|
||||
return Object.values(this.persistedFilters).some(comparator => {
|
||||
return (typeof(comparator) === 'object' && !_.isEmpty(comparator));
|
||||
});
|
||||
}
|
||||
mounted() {
|
||||
let type = this.openmct.types.get(this.filterObject.domainObject.type) || {};
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.filterObject.domainObject.identifier);
|
||||
this.objectCssClass = type.definition.cssClass;
|
||||
this.openmct.editor.on('isEditing', this.toggleIsEditing);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.openmct.editor.off('isEditing', this.toggleIsEditing);
|
||||
},
|
||||
methods: {
|
||||
toggleExpanded() {
|
||||
@ -128,16 +161,7 @@ export default {
|
||||
},
|
||||
toggleIsEditing(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
let type = this.openmct.types.get(this.filterObject.domainObject.type) || {};
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.filterObject.domainObject.identifier);
|
||||
this.objectCssClass = type.definition.cssClass;
|
||||
this.openmct.editor.on('isEditing', this.toggleIsEditing);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.openmct.editor.off('isEditing', this.toggleIsEditing);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,22 +1,28 @@
|
||||
<template>
|
||||
<ul class="c-tree c-filter-tree" v-if="Object.keys(children).length">
|
||||
<ul
|
||||
v-if="Object.keys(children).length"
|
||||
class="c-tree c-filter-tree"
|
||||
>
|
||||
<h2>Data Filters</h2>
|
||||
<div class="c-filter-indication"
|
||||
v-if="hasActiveFilters">{{ label }}
|
||||
<div
|
||||
v-if="hasActiveFilters"
|
||||
class="c-filter-indication"
|
||||
>
|
||||
{{ label }}
|
||||
</div>
|
||||
<global-filters
|
||||
:globalFilters="globalFilters"
|
||||
:globalMetadata="globalMetadata"
|
||||
@persistGlobalFilters="persistGlobalFilters">
|
||||
</global-filters>
|
||||
:global-filters="globalFilters"
|
||||
:global-metadata="globalMetadata"
|
||||
@persistGlobalFilters="persistGlobalFilters"
|
||||
/>
|
||||
<filter-object
|
||||
v-for="(child, key) in children"
|
||||
:key="key"
|
||||
:filterObject="child"
|
||||
:persistedFilters="persistedFilters[key]"
|
||||
@updateFilters="persistFilters">
|
||||
</filter-object>
|
||||
</ul>
|
||||
:filter-object="child"
|
||||
:persisted-filters="persistedFilters[key]"
|
||||
@updateFilters="persistFilters"
|
||||
/>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -40,14 +46,14 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import FilterObject from './FilterObject.vue';
|
||||
import GlobalFilters from './GlobalFilters.vue'
|
||||
import FilterObject from './FilterObject.vue';
|
||||
import GlobalFilters from './GlobalFilters.vue'
|
||||
|
||||
const FILTER_VIEW_TITLE = 'Filters applied';
|
||||
const FILTER_VIEW_TITLE_MIXED = 'Mixed filters applied';
|
||||
const USE_GLOBAL = 'useGlobal';
|
||||
const FILTER_VIEW_TITLE = 'Filters applied';
|
||||
const FILTER_VIEW_TITLE_MIXED = 'Mixed filters applied';
|
||||
const USE_GLOBAL = 'useGlobal';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
components: {
|
||||
FilterObject,
|
||||
GlobalFilters
|
||||
@ -91,8 +97,25 @@
|
||||
return FILTER_VIEW_TITLE;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.providedObject);
|
||||
this.composition.on('add', this.addChildren);
|
||||
this.composition.on('remove', this.removeChildren);
|
||||
this.composition.load();
|
||||
this.unobserve = this.openmct.objects.observe(this.providedObject, 'configuration.filters', this.updatePersistedFilters);
|
||||
this.unobserveGlobalFilters = this.openmct.objects.observe(this.providedObject, 'configuration.globalFilters', this.updateGlobalFilters);
|
||||
this.unobserveAllMutation = this.openmct.objects.observe(this.providedObject, '*', (mutatedObject) => this.providedObject = mutatedObject);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.composition.off('add', this.addChildren);
|
||||
this.composition.off('remove', this.removeChildren);
|
||||
this.unobserve();
|
||||
this.unobserveGlobalFilters();
|
||||
this.unobserveAllMutation();
|
||||
},
|
||||
methods: {
|
||||
addChildren(domainObject) {
|
||||
let keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
@ -228,22 +251,6 @@
|
||||
mutateConfigurationGlobalFilters() {
|
||||
this.openmct.objects.mutate(this.providedObject, 'configuration.globalFilters', this.globalFilters);
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.composition = this.openmct.composition.get(this.providedObject);
|
||||
this.composition.on('add', this.addChildren);
|
||||
this.composition.on('remove', this.removeChildren);
|
||||
this.composition.load();
|
||||
this.unobserve = this.openmct.objects.observe(this.providedObject, 'configuration.filters', this.updatePersistedFilters);
|
||||
this.unobserveGlobalFilters = this.openmct.objects.observe(this.providedObject, 'configuration.globalFilters', this.updateGlobalFilters);
|
||||
this.unobserveAllMutation = this.openmct.objects.observe(this.providedObject, '*', (mutatedObject) => this.providedObject = mutatedObject);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.composition.off('add', this.addChildren);
|
||||
this.composition.off('remove', this.removeChildren);
|
||||
this.unobserve();
|
||||
this.unobserveGlobalFilters();
|
||||
this.unobserveAllMutation();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,29 +1,40 @@
|
||||
<template>
|
||||
<li class="c-tree__item-h">
|
||||
<div class="c-tree__item menus-to-left"
|
||||
@click="toggleExpanded">
|
||||
<div class="c-filter-tree-item__filter-indicator"
|
||||
:class="{'icon-filter': hasActiveGlobalFilters }"></div>
|
||||
<span class="c-disclosure-triangle is-enabled flex-elem"
|
||||
:class="{'c-disclosure-triangle--expanded': expanded}"></span>
|
||||
<li class="c-tree__item-h">
|
||||
<div
|
||||
class="c-tree__item menus-to-left"
|
||||
@click="toggleExpanded"
|
||||
>
|
||||
<div
|
||||
class="c-filter-tree-item__filter-indicator"
|
||||
:class="{'icon-filter': hasActiveGlobalFilters }"
|
||||
></div>
|
||||
<span
|
||||
class="c-disclosure-triangle is-enabled flex-elem"
|
||||
:class="{'c-disclosure-triangle--expanded': expanded}"
|
||||
></span>
|
||||
<div class="c-tree__item__label c-object-label">
|
||||
<div class="c-object-label">
|
||||
<div class="c-object-label__type-icon icon-gear"></div>
|
||||
<div class="c-object-label__name flex-elem grows">Global Filtering</div>
|
||||
<div class="c-object-label__name flex-elem grows">
|
||||
Global Filtering
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="c-properties" v-if="expanded">
|
||||
</div>
|
||||
<ul
|
||||
v-if="expanded"
|
||||
class="c-properties"
|
||||
>
|
||||
<filter-field
|
||||
v-for="metadatum in globalMetadata"
|
||||
:key="metadatum.key"
|
||||
:filterField="metadatum"
|
||||
:persistedFilters="updatedFilters[metadatum.key]"
|
||||
:filter-field="metadatum"
|
||||
:persisted-filters="updatedFilters[metadatum.key]"
|
||||
@filterSelected="updateFiltersWithSelectedValue"
|
||||
@filterTextValueChanged="updateFiltersWithTextValue">
|
||||
</filter-field>
|
||||
@filterTextValueChanged="updateFiltersWithTextValue"
|
||||
/>
|
||||
</ul>
|
||||
</li>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -59,15 +70,18 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import FilterField from './FilterField.vue';
|
||||
import FilterField from './FilterField.vue';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
FilterField
|
||||
},
|
||||
props: {
|
||||
globalMetadata: Object,
|
||||
globalMetadata: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
globalFilters: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
@ -131,5 +145,5 @@
|
||||
this.$emit('persistGlobalFilters', key, this.updatedFilters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,13 +21,17 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-fl-container"
|
||||
<div
|
||||
class="c-fl-container"
|
||||
:style="[{'flex-basis': sizeString}]"
|
||||
:class="{'is-empty': !frames.length}">
|
||||
<div class="c-fl-container__header"
|
||||
:class="{'is-empty': !frames.length}"
|
||||
>
|
||||
<div
|
||||
v-show="isEditing"
|
||||
class="c-fl-container__header"
|
||||
draggable="true"
|
||||
@dragstart="startContainerDrag">
|
||||
@dragstart="startContainerDrag"
|
||||
>
|
||||
<span class="c-fl-container__size-indicator">{{ sizeString }}</span>
|
||||
</div>
|
||||
|
||||
@ -35,48 +39,47 @@
|
||||
class="c-fl-frame__drop-hint"
|
||||
:index="-1"
|
||||
:allow-drop="allowDrop"
|
||||
@object-drop-to="moveOrCreateNewFrame">
|
||||
</drop-hint>
|
||||
@object-drop-to="moveOrCreateNewFrame"
|
||||
/>
|
||||
|
||||
<div class="c-fl-container__frames-holder">
|
||||
<template
|
||||
v-for="(frame, i) in frames">
|
||||
|
||||
v-for="(frame, i) in frames"
|
||||
>
|
||||
<frame-component
|
||||
class="c-fl-container__frame"
|
||||
:key="frame.id"
|
||||
class="c-fl-container__frame"
|
||||
:frame="frame"
|
||||
:index="i"
|
||||
:containerIndex="index"
|
||||
:isEditing="isEditing">
|
||||
</frame-component>
|
||||
:container-index="index"
|
||||
:is-editing="isEditing"
|
||||
/>
|
||||
|
||||
<drop-hint
|
||||
class="c-fl-frame__drop-hint"
|
||||
:key="i"
|
||||
class="c-fl-frame__drop-hint"
|
||||
:index="i"
|
||||
:allowDrop="allowDrop"
|
||||
@object-drop-to="moveOrCreateNewFrame">
|
||||
</drop-hint>
|
||||
:allow-drop="allowDrop"
|
||||
@object-drop-to="moveOrCreateNewFrame"
|
||||
/>
|
||||
|
||||
<resize-handle
|
||||
v-if="(i !== frames.length - 1)"
|
||||
:key="i"
|
||||
:index="i"
|
||||
:orientation="rowsLayout ? 'horizontal' : 'vertical'"
|
||||
:is-editing="isEditing"
|
||||
@init-move="startFrameResizing"
|
||||
@move="frameResizing"
|
||||
@end-move="endFrameResizing"
|
||||
:isEditing="isEditing">
|
||||
</resize-handle>
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FrameComponent from './frame.vue';
|
||||
import Frame from '../utils/frame';
|
||||
import ResizeHandle from './resizeHandle.vue';
|
||||
import DropHint from './dropHint.vue';
|
||||
|
||||
@ -84,12 +87,26 @@ const MIN_FRAME_SIZE = 5;
|
||||
|
||||
export default {
|
||||
inject:['openmct'],
|
||||
props: ['container', 'index', 'rowsLayout', 'isEditing'],
|
||||
components: {
|
||||
FrameComponent,
|
||||
ResizeHandle,
|
||||
DropHint
|
||||
},
|
||||
props: {
|
||||
container: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
rowsLayout: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
frames() {
|
||||
return this.container.frames;
|
||||
@ -98,6 +115,19 @@ export default {
|
||||
return `${Math.round(this.container.size)}%`
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let context = {
|
||||
item: this.$parent.domainObject,
|
||||
addContainer: this.addContainer,
|
||||
type: 'container',
|
||||
containerId: this.container.id
|
||||
}
|
||||
|
||||
this.unsubscribeSelection = this.openmct.selection.selectable(this.$el, context, false);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.unsubscribeSelection();
|
||||
},
|
||||
methods: {
|
||||
allowDrop(event, index) {
|
||||
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
@ -131,7 +161,7 @@ export default {
|
||||
insertIndex
|
||||
);
|
||||
return;
|
||||
};
|
||||
}
|
||||
// move frame.
|
||||
let frameId = event.dataTransfer.getData('frameid');
|
||||
let containerIndex = Number(event.dataTransfer.getData('containerIndex'));
|
||||
@ -182,19 +212,6 @@ export default {
|
||||
startContainerDrag(event) {
|
||||
event.dataTransfer.setData('containerid', this.container.id);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let context = {
|
||||
item: this.$parent.domainObject,
|
||||
addContainer: this.addContainer,
|
||||
type: 'container',
|
||||
containerId: this.container.id
|
||||
}
|
||||
|
||||
this.unsubscribeSelection = this.openmct.selection.selectable(this.$el, context, false);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.unsubscribeSelection();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,15 +21,16 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div v-show="isValidTarget">
|
||||
<div class="c-drop-hint c-drop-hint--always-show"
|
||||
<div v-show="isValidTarget">
|
||||
<div
|
||||
class="c-drop-hint c-drop-hint--always-show"
|
||||
:class="{'is-mouse-over': isMouseOver}"
|
||||
@dragover.prevent
|
||||
@dragenter="dragenter"
|
||||
@dragleave="dragleave"
|
||||
@drop="dropHandler">
|
||||
</div>
|
||||
</div>
|
||||
@drop="dropHandler"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -39,7 +40,10 @@
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
index: Number,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
allowDrop: {
|
||||
type: Function,
|
||||
required: true
|
||||
@ -51,6 +55,16 @@ export default {
|
||||
isValidTarget: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('dragstart', this.dragstart);
|
||||
document.addEventListener('dragend', this.dragend);
|
||||
document.addEventListener('drop', this.dragend);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
document.removeEventListener('drop', this.dragend);
|
||||
},
|
||||
methods: {
|
||||
dragenter() {
|
||||
this.isMouseOver = true;
|
||||
@ -68,16 +82,6 @@ export default {
|
||||
dragend() {
|
||||
this.isValidTarget = false;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('dragstart', this.dragstart);
|
||||
document.addEventListener('dragend', this.dragend);
|
||||
document.addEventListener('drop', this.dragend);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
document.removeEventListener('drop', this.dragend);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,67 +21,69 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-fl">
|
||||
<div class="c-fl">
|
||||
<div
|
||||
id="js-fl-drag-ghost"
|
||||
class="c-fl__drag-ghost">
|
||||
</div>
|
||||
class="c-fl__drag-ghost"
|
||||
></div>
|
||||
|
||||
<div class="c-fl__empty"
|
||||
v-if="areAllContainersEmpty()">
|
||||
<div
|
||||
v-if="areAllContainersEmpty()"
|
||||
class="c-fl__empty"
|
||||
>
|
||||
<span class="c-fl__empty-message">This Flexible Layout is currently empty</span>
|
||||
</div>
|
||||
|
||||
<div class="c-fl__container-holder"
|
||||
<div
|
||||
class="c-fl__container-holder"
|
||||
:class="{
|
||||
'c-fl--rows': rowsLayout === true
|
||||
}">
|
||||
|
||||
}"
|
||||
>
|
||||
<template v-for="(container, index) in containers">
|
||||
|
||||
<drop-hint
|
||||
class="c-fl-frame__drop-hint"
|
||||
v-if="index === 0 && containers.length > 1"
|
||||
:key="index"
|
||||
class="c-fl-frame__drop-hint"
|
||||
:index="-1"
|
||||
:allow-drop="allowContainerDrop"
|
||||
@object-drop-to="moveContainer">
|
||||
</drop-hint>
|
||||
@object-drop-to="moveContainer"
|
||||
/>
|
||||
|
||||
<container-component
|
||||
class="c-fl__container"
|
||||
:key="container.id"
|
||||
class="c-fl__container"
|
||||
:index="index"
|
||||
:container="container"
|
||||
:rowsLayout="rowsLayout"
|
||||
:isEditing="isEditing"
|
||||
:rows-layout="rowsLayout"
|
||||
:is-editing="isEditing"
|
||||
@move-frame="moveFrame"
|
||||
@new-frame="setFrameLocation"
|
||||
@persist="persist">
|
||||
</container-component>
|
||||
@persist="persist"
|
||||
/>
|
||||
|
||||
<resize-handle
|
||||
v-if="index !== (containers.length - 1)"
|
||||
:key="index"
|
||||
:index="index"
|
||||
:orientation="rowsLayout ? 'vertical' : 'horizontal'"
|
||||
:isEditing="isEditing"
|
||||
:is-editing="isEditing"
|
||||
@init-move="startContainerResizing"
|
||||
@move="containerResizing"
|
||||
@end-move="endContainerResizing">
|
||||
</resize-handle>
|
||||
@end-move="endContainerResizing"
|
||||
/>
|
||||
|
||||
<drop-hint
|
||||
class="c-fl-frame__drop-hint"
|
||||
v-if="containers.length > 1"
|
||||
:key="index"
|
||||
class="c-fl-frame__drop-hint"
|
||||
:index="index"
|
||||
:allowDrop="allowContainerDrop"
|
||||
@object-drop-to="moveContainer">
|
||||
</drop-hint>
|
||||
:allow-drop="allowContainerDrop"
|
||||
@object-drop-to="moveContainer"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -465,15 +467,15 @@ export default {
|
||||
ResizeHandle,
|
||||
DropHint
|
||||
},
|
||||
props: {
|
||||
isEditing: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: this.layoutObject,
|
||||
newFrameLocation: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
isEditing: Boolean
|
||||
},
|
||||
computed: {
|
||||
layoutDirectionStr() {
|
||||
if (this.rowsLayout) {
|
||||
@ -489,9 +491,24 @@ export default {
|
||||
return this.domainObject.configuration.rowsLayout;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('remove', this.removeChildObject);
|
||||
this.composition.on('add', this.addFrame);
|
||||
|
||||
this.RemoveAction = new RemoveAction(this.openmct);
|
||||
|
||||
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.composition.off('remove', this.removeChildObject);
|
||||
this.composition.off('add', this.addFrame);
|
||||
|
||||
this.unobserve();
|
||||
},
|
||||
methods: {
|
||||
areAllContainersEmpty() {
|
||||
return !!!this.containers.filter(container => container.frames.length).length;
|
||||
return !this.containers.filter(container => container.frames.length).length;
|
||||
},
|
||||
addContainer() {
|
||||
let container = new Container();
|
||||
@ -589,7 +606,7 @@ export default {
|
||||
return containerPos !== index && (containerPos - 1) !== index
|
||||
}
|
||||
},
|
||||
persist(index){
|
||||
persist(index) {
|
||||
if (index) {
|
||||
this.openmct.objects.mutate(this.domainObject, `configuration.containers[${index}]`, this.containers[index]);
|
||||
} else {
|
||||
@ -657,21 +674,6 @@ export default {
|
||||
|
||||
this.persist();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('remove', this.removeChildObject);
|
||||
this.composition.on('add', this.addFrame);
|
||||
|
||||
this.RemoveAction = new RemoveAction(this.openmct);
|
||||
|
||||
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.composition.off('remove', this.removeChildObject);
|
||||
this.composition.off('add', this.addFrame);
|
||||
|
||||
this.unobserve();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,56 +21,89 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-fl-frame"
|
||||
<div
|
||||
class="c-fl-frame"
|
||||
:style="{
|
||||
'flex-basis': `${frame.size}%`
|
||||
}">
|
||||
|
||||
<div class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
|
||||
}"
|
||||
>
|
||||
<div
|
||||
ref="frame"
|
||||
class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
|
||||
draggable="true"
|
||||
@dragstart="initDrag"
|
||||
ref="frame">
|
||||
|
||||
>
|
||||
<object-frame
|
||||
v-if="domainObject"
|
||||
ref="objectFrame"
|
||||
:domain-object="domainObject"
|
||||
:object-path="objectPath"
|
||||
:has-frame="hasFrame"
|
||||
:show-edit-view="false"
|
||||
ref="objectFrame">
|
||||
</object-frame>
|
||||
/>
|
||||
|
||||
<div class="c-fl-frame__size-indicator"
|
||||
<div
|
||||
v-if="isEditing"
|
||||
v-show="frame.size && frame.size < 100">
|
||||
{{frame.size}}%
|
||||
</div>
|
||||
v-show="frame.size && frame.size < 100"
|
||||
class="c-fl-frame__size-indicator"
|
||||
>
|
||||
{{ frame.size }}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ResizeHandle from './resizeHandle.vue';
|
||||
import ObjectFrame from '../../../ui/components/ObjectFrame.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: ['frame', 'index', 'containerIndex', 'isEditing'],
|
||||
components: {
|
||||
ObjectFrame
|
||||
},
|
||||
props: {
|
||||
frame: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
containerIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
objectPath: undefined
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResizeHandle,
|
||||
ObjectFrame
|
||||
},
|
||||
computed: {
|
||||
hasFrame() {
|
||||
return !this.frame.noFrame;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.frame.domainObjectIdentifier) {
|
||||
this.openmct.objects.get(this.frame.domainObjectIdentifier).then((object)=>{
|
||||
this.setDomainObject(object);
|
||||
});
|
||||
}
|
||||
|
||||
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribeSelection) {
|
||||
this.unsubscribeSelection();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setDomainObject(object) {
|
||||
this.domainObject = object;
|
||||
@ -105,20 +138,6 @@ export default {
|
||||
event.dataTransfer.setData('frameid', this.frame.id);
|
||||
event.dataTransfer.setData('containerIndex', this.containerIndex);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.frame.domainObjectIdentifier) {
|
||||
this.openmct.objects.get(this.frame.domainObjectIdentifier).then((object)=>{
|
||||
this.setDomainObject(object);
|
||||
});
|
||||
}
|
||||
|
||||
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribeSelection) {
|
||||
this.unsubscribeSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,22 +21,46 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-fl-frame__resize-handle"
|
||||
:class="[orientation]"
|
||||
<div
|
||||
v-show="isEditing && !isDragging"
|
||||
@mousedown="mousedown">
|
||||
</div>
|
||||
class="c-fl-frame__resize-handle"
|
||||
:class="[orientation]"
|
||||
@mousedown="mousedown"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['orientation', 'index', 'isEditing'],
|
||||
props: {
|
||||
orientation: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
initialPos: 0,
|
||||
isDragging: false,
|
||||
isDragging: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('dragstart', this.setDragging);
|
||||
document.addEventListener('dragend', this.unsetDragging);
|
||||
document.addEventListener('drop', this.unsetDragging);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('dragstart', this.setDragging);
|
||||
document.removeEventListener('dragend', this.unsetDragging);
|
||||
document.removeEventListener('drop', this.unsetDragging);
|
||||
},
|
||||
methods: {
|
||||
mousedown(event) {
|
||||
event.preventDefault();
|
||||
@ -75,16 +99,6 @@ export default {
|
||||
unsetDragging(event) {
|
||||
this.isDragging = false;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('dragstart', this.setDragging);
|
||||
document.addEventListener('dragend', this.unsetDragging);
|
||||
document.addEventListener('drop', this.unsetDragging);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('dragstart', this.setDragging);
|
||||
document.removeEventListener('dragend', this.unsetDragging);
|
||||
document.removeEventListener('drop', this.unsetDragging);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -44,19 +44,19 @@ define([
|
||||
return {
|
||||
show: function (element, isEditing) {
|
||||
component = new Vue({
|
||||
data() {
|
||||
return {
|
||||
isEditing: isEditing
|
||||
}
|
||||
},
|
||||
components: {
|
||||
FlexibleLayoutComponent: FlexibleLayoutComponent.default
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
layoutObject: domainObject
|
||||
},
|
||||
el: element,
|
||||
components: {
|
||||
FlexibleLayoutComponent: FlexibleLayoutComponent.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing: isEditing
|
||||
}
|
||||
},
|
||||
template: '<flexible-layout-component ref="flexibleLayout" :isEditing="isEditing"></flexible-layout-component>'
|
||||
});
|
||||
},
|
||||
|
@ -41,6 +41,7 @@ define([
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
gridViewComponent: GridViewComponent.default
|
||||
},
|
||||
@ -48,7 +49,6 @@ define([
|
||||
openmct,
|
||||
domainObject
|
||||
},
|
||||
el: element,
|
||||
template: '<grid-view-component></grid-view-component>'
|
||||
});
|
||||
},
|
||||
|
@ -43,6 +43,7 @@ define([
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
listViewComponent: ListViewComponent.default
|
||||
},
|
||||
@ -51,7 +52,6 @@ define([
|
||||
domainObject,
|
||||
Moment
|
||||
},
|
||||
el: element,
|
||||
template: '<list-view-component></list-view-component>'
|
||||
});
|
||||
},
|
||||
|
@ -1,25 +1,38 @@
|
||||
<template>
|
||||
<a class="l-grid-view__item c-grid-item"
|
||||
<a
|
||||
class="l-grid-view__item c-grid-item"
|
||||
:class="{ 'is-alias': item.isAlias === true }"
|
||||
:href="objectLink">
|
||||
<div class="c-grid-item__type-icon"
|
||||
:class="(item.type.cssClass != undefined) ? 'bg-' + item.type.cssClass : 'bg-icon-object-unknown'">
|
||||
</div>
|
||||
:href="objectLink"
|
||||
>
|
||||
<div
|
||||
class="c-grid-item__type-icon"
|
||||
:class="(item.type.cssClass != undefined) ? 'bg-' + item.type.cssClass : 'bg-icon-object-unknown'"
|
||||
></div>
|
||||
<div class="c-grid-item__details">
|
||||
<!-- Name and metadata -->
|
||||
<div class="c-grid-item__name"
|
||||
:title="item.model.name">{{item.model.name}}</div>
|
||||
<div class="c-grid-item__metadata"
|
||||
:title="item.type.name">
|
||||
<span class="c-grid-item__metadata__type">{{item.type.name}}</span>
|
||||
<div
|
||||
class="c-grid-item__name"
|
||||
:title="item.model.name"
|
||||
>{{ item.model.name }}</div>
|
||||
<div
|
||||
class="c-grid-item__metadata"
|
||||
:title="item.type.name"
|
||||
>
|
||||
<span class="c-grid-item__metadata__type">{{ item.type.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-grid-item__controls">
|
||||
<div class="icon-people" title='Shared'></div>
|
||||
<button class="c-icon-button icon-info c-info-button" title='More Info'></button>
|
||||
<div
|
||||
class="icon-people"
|
||||
title="Shared"
|
||||
></div>
|
||||
<button
|
||||
class="c-icon-button icon-info c-info-button"
|
||||
title="More Info"
|
||||
></button>
|
||||
<div class="icon-pointer-right c-pointer-icon"></div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -154,6 +167,11 @@ import objectLink from '../../../ui/mixins/object-link';
|
||||
|
||||
export default {
|
||||
mixins: [contextMenuGesture, objectLink],
|
||||
props: ['item']
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<div class="l-grid-view">
|
||||
<grid-item v-for="(item, index) in items"
|
||||
<div class="l-grid-view">
|
||||
<grid-item
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:item="item"
|
||||
:object-path="item.objectPath">
|
||||
</grid-item>
|
||||
</div>
|
||||
:object-path="item.objectPath"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -1,17 +1,31 @@
|
||||
<template>
|
||||
<tr class="c-list-item"
|
||||
<tr
|
||||
class="c-list-item"
|
||||
:class="{ 'is-alias': item.isAlias === true }"
|
||||
@click="navigate">
|
||||
@click="navigate"
|
||||
>
|
||||
<td class="c-list-item__name">
|
||||
<a :href="objectLink" ref="objectLink">
|
||||
<div class="c-list-item__type-icon" :class="item.type.cssClass"></div>
|
||||
<div class="c-list-item__name-value">{{item.model.name}}</div>
|
||||
<a
|
||||
ref="objectLink"
|
||||
:href="objectLink"
|
||||
>
|
||||
<div
|
||||
class="c-list-item__type-icon"
|
||||
:class="item.type.cssClass"
|
||||
></div>
|
||||
<div class="c-list-item__name-value">{{ item.model.name }}</div>
|
||||
</a>
|
||||
</td>
|
||||
<td class="c-list-item__type">{{ item.type.name }}</td>
|
||||
<td class="c-list-item__date-created">{{ formatTime(item.model.persisted, 'YYYY-MM-DD HH:mm:ss:SSS') }}Z</td>
|
||||
<td class="c-list-item__date-updated">{{ formatTime(item.model.modified, 'YYYY-MM-DD HH:mm:ss:SSS') }}Z</td>
|
||||
</tr>
|
||||
<td class="c-list-item__type">
|
||||
{{ item.type.name }}
|
||||
</td>
|
||||
<td class="c-list-item__date-created">
|
||||
{{ formatTime(item.model.persisted, 'YYYY-MM-DD HH:mm:ss:SSS') }}Z
|
||||
</td>
|
||||
<td class="c-list-item__date-updated">
|
||||
{{ formatTime(item.model.modified, 'YYYY-MM-DD HH:mm:ss:SSS') }}Z
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -64,7 +78,12 @@ import objectLink from '../../../ui/mixins/object-link';
|
||||
|
||||
export default {
|
||||
mixins: [contextMenuGesture, objectLink],
|
||||
props: ['item'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatTime(timestamp, format) {
|
||||
return moment(timestamp).format(format);
|
||||
|
@ -1,55 +1,64 @@
|
||||
<template>
|
||||
<div class="c-table c-table--sortable c-list-view">
|
||||
<div class="c-table c-table--sortable c-list-view">
|
||||
<table class="c-table__body">
|
||||
<thead class="c-table__header">
|
||||
<tr>
|
||||
<th class="is-sortable"
|
||||
<th
|
||||
class="is-sortable"
|
||||
:class="{
|
||||
'is-sorting': sortBy === 'model.name',
|
||||
'asc': ascending,
|
||||
'desc': !ascending
|
||||
}"
|
||||
@click="sort('model.name', true)">
|
||||
@click="sort('model.name', true)"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th class="is-sortable"
|
||||
<th
|
||||
class="is-sortable"
|
||||
:class="{
|
||||
'is-sorting': sortBy === 'type.name',
|
||||
'asc': ascending,
|
||||
'desc': !ascending
|
||||
}"
|
||||
@click="sort('type.name', true)">
|
||||
@click="sort('type.name', true)"
|
||||
>
|
||||
Type
|
||||
</th>
|
||||
<th class="is-sortable"
|
||||
<th
|
||||
class="is-sortable"
|
||||
:class="{
|
||||
'is-sorting': sortBy === 'model.persisted',
|
||||
'asc': ascending,
|
||||
'desc': !ascending
|
||||
}"
|
||||
@click="sort('model.persisted', false)">
|
||||
@click="sort('model.persisted', false)"
|
||||
>
|
||||
Created Date
|
||||
</th>
|
||||
<th class="is-sortable"
|
||||
<th
|
||||
class="is-sortable"
|
||||
:class="{
|
||||
'is-sorting': sortBy === 'model.modified',
|
||||
'asc': ascending,
|
||||
'desc': !ascending
|
||||
}"
|
||||
@click="sort('model.modified', false)">
|
||||
@click="sort('model.modified', false)"
|
||||
>
|
||||
Updated Date
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<list-item v-for="item in sortedItems"
|
||||
<list-item
|
||||
v-for="item in sortedItems"
|
||||
:key="item.objectKeyString"
|
||||
:item="item"
|
||||
:object-path="item.objectPath">
|
||||
</list-item>
|
||||
:object-path="item.objectPath"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -93,8 +102,6 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
import lodash from 'lodash';
|
||||
import compositionLoader from './composition-loader';
|
||||
import ListItem from './ListItem.vue';
|
||||
|
||||
@ -120,7 +127,7 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sortedItems () {
|
||||
sortedItems() {
|
||||
let sortedItems = _.sortBy(this.items, this.sortBy);
|
||||
if (!this.ascending) {
|
||||
sortedItems = sortedItems.reverse();
|
||||
|
@ -20,21 +20,30 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-about c-about--licenses">
|
||||
<div class="c-about c-about--licenses">
|
||||
<h1>Open MCT Third Party Licenses</h1>
|
||||
<p>This software includes components released under the following licenses:</p>
|
||||
<div v-for="(pkg, key) in packages" :key="key" class="c-license">
|
||||
<h2 class="c-license__name">{{key}}</h2>
|
||||
<div
|
||||
v-for="(pkg, key) in packages"
|
||||
:key="key"
|
||||
class="c-license"
|
||||
>
|
||||
<h2 class="c-license__name">
|
||||
{{ key }}
|
||||
</h2>
|
||||
<div class="c-license__details">
|
||||
<span class="c-license__author"><em>Author</em> {{pkg.publisher}}</span> |
|
||||
<span class="c-license__license"><em>License(s)</em> {{pkg.licenses}}</span> |
|
||||
<span class="c-license__repo"><em>Repository</em> <a :href="pkg.repository" target="_blank">{{pkg.repository}}</a></span>
|
||||
<span class="c-license__author"><em>Author</em> {{ pkg.publisher }}</span> |
|
||||
<span class="c-license__license"><em>License(s)</em> {{ pkg.licenses }}</span> |
|
||||
<span class="c-license__repo"><em>Repository</em> <a
|
||||
:href="pkg.repository"
|
||||
target="_blank"
|
||||
>{{ pkg.repository }}</a></span>
|
||||
</div>
|
||||
<div class="c-license__text">
|
||||
<p>{{pkg.licenseText}}</p>
|
||||
</div>
|
||||
<p>{{ pkg.licenseText }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="sass">
|
||||
</style>
|
||||
@ -49,4 +58,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -141,7 +141,6 @@ function (
|
||||
|
||||
var self = this,
|
||||
snapshot = new Vue({
|
||||
template: SnapshotTemplate,
|
||||
data: function () {
|
||||
return {
|
||||
embed: self.embed
|
||||
@ -151,7 +150,8 @@ function (
|
||||
formatTime: self.formatTime,
|
||||
annotateSnapshot: annotateSnapshot(self.openmct),
|
||||
findInArray: self.findInArray
|
||||
}
|
||||
},
|
||||
template: SnapshotTemplate
|
||||
});
|
||||
|
||||
var snapshotOverlay = this.openmct.overlays.overlay({
|
||||
|
@ -84,7 +84,6 @@ function (
|
||||
};
|
||||
|
||||
var NotebookVue = Vue.extend({
|
||||
template: NotebookTemplate,
|
||||
provide: {openmct: self.openmct, domainObject: self.domainObject},
|
||||
components: {
|
||||
'notebook-entry': entryComponent,
|
||||
@ -111,7 +110,8 @@ function (
|
||||
newEntry: self.newEntry,
|
||||
filterBySearch: self.filterBySearch,
|
||||
sort: self.sort
|
||||
}
|
||||
},
|
||||
template: NotebookTemplate
|
||||
});
|
||||
|
||||
this.NotebookVue = new NotebookVue();
|
||||
|
@ -1,44 +1,58 @@
|
||||
<template>
|
||||
<div class="c-tabs-view">
|
||||
<div class="c-tabs-view__tabs-holder c-tabs"
|
||||
<div class="c-tabs-view">
|
||||
<div
|
||||
class="c-tabs-view__tabs-holder c-tabs"
|
||||
:class="{
|
||||
'is-dragging': isDragging,
|
||||
'is-mouse-over': allowDrop
|
||||
}">
|
||||
<div class="c-drop-hint"
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="c-drop-hint"
|
||||
@drop="onDrop"
|
||||
@dragenter="dragenter"
|
||||
@dragleave="dragleave">
|
||||
@dragleave="dragleave"
|
||||
></div>
|
||||
<div
|
||||
v-if="!tabsList.length > 0"
|
||||
class="c-tabs-view__empty-message"
|
||||
>
|
||||
Drag objects here to add them to this view.
|
||||
</div>
|
||||
<div class="c-tabs-view__empty-message"
|
||||
v-if="!tabsList.length > 0">Drag objects here to add them to this view.</div>
|
||||
<button class="c-tabs-view__tab c-tab"
|
||||
<button
|
||||
v-for="(tab,index) in tabsList"
|
||||
:key="index"
|
||||
class="c-tabs-view__tab c-tab"
|
||||
:class="[
|
||||
{'is-current': isCurrent(tab)},
|
||||
tab.type.definition.cssClass
|
||||
]"
|
||||
@click="showTab(tab)">
|
||||
<span class="c-button__label">{{tab.domainObject.name}}</span>
|
||||
@click="showTab(tab)"
|
||||
>
|
||||
<span class="c-button__label">{{ tab.domainObject.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="c-tabs-view__object-holder"
|
||||
<div
|
||||
v-for="(tab, index) in tabsList"
|
||||
:key="index"
|
||||
:class="{'c-tabs-view__object-holder--hidden': !isCurrent(tab)}">
|
||||
<div v-if="currentTab"
|
||||
class="c-tabs-view__object-holder"
|
||||
:class="{'c-tabs-view__object-holder--hidden': !isCurrent(tab)}"
|
||||
>
|
||||
<div
|
||||
v-if="currentTab"
|
||||
class="c-tabs-view__object-name l-browse-bar__object-name--w"
|
||||
:class="currentTab.type.definition.cssClass">
|
||||
:class="currentTab.type.definition.cssClass"
|
||||
>
|
||||
<div class="l-browse-bar__object-name">
|
||||
{{currentTab.domainObject.name}}
|
||||
{{ currentTab.domainObject.name }}
|
||||
</div>
|
||||
</div>
|
||||
<object-view class="c-tabs-view__object"
|
||||
:object="tab.domainObject">
|
||||
</object-view>
|
||||
</div>
|
||||
<object-view
|
||||
class="c-tabs-view__object"
|
||||
:object="tab.domainObject"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -129,6 +143,25 @@ export default {
|
||||
allowDrop: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.composition) {
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.onReorder);
|
||||
this.composition.load();
|
||||
}
|
||||
|
||||
document.addEventListener('dragstart', this.dragstart);
|
||||
document.addEventListener('dragend', this.dragend);
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.onReorder);
|
||||
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
},
|
||||
methods:{
|
||||
showTab(tab) {
|
||||
this.currentTab = tab;
|
||||
@ -169,7 +202,7 @@ export default {
|
||||
onDrop(e) {
|
||||
this.setCurrentTab = true;
|
||||
},
|
||||
dragstart (e) {
|
||||
dragstart(e) {
|
||||
if (e.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
this.isDragging = true;
|
||||
}
|
||||
@ -187,25 +220,6 @@ export default {
|
||||
isCurrent(tab) {
|
||||
return _.isEqual(this.currentTab, tab)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.composition) {
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.onReorder);
|
||||
this.composition.load();
|
||||
}
|
||||
|
||||
document.addEventListener('dragstart', this.dragstart);
|
||||
document.addEventListener('dragend', this.dragend);
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.onReorder);
|
||||
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -44,6 +44,7 @@ define([
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
TabsComponent: TabsComponent.default
|
||||
},
|
||||
@ -52,7 +53,6 @@ define([
|
||||
domainObject,
|
||||
composition: openmct.composition.get(domainObject)
|
||||
},
|
||||
el: element,
|
||||
template: '<tabs-component></tabs-component>'
|
||||
});
|
||||
},
|
||||
|
@ -54,11 +54,11 @@ define([
|
||||
openmct,
|
||||
tableConfiguration
|
||||
},
|
||||
el: element,
|
||||
components: {
|
||||
TableConfiguration: TableConfigurationComponent.default
|
||||
},
|
||||
template: '<table-configuration></table-configuration>',
|
||||
el: element
|
||||
template: '<table-configuration></table-configuration>'
|
||||
});
|
||||
},
|
||||
destroy: function () {
|
||||
|
@ -54,20 +54,20 @@ define([
|
||||
return {
|
||||
show: function (element, editMode) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
TableComponent: TableComponent.default
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isEditing: editMode
|
||||
}
|
||||
},
|
||||
components: {
|
||||
TableComponent: TableComponent.default
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
table,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
template: '<table-component :isEditing="isEditing" :enableMarking="true"></table-component>'
|
||||
});
|
||||
},
|
||||
|
@ -1,14 +1,19 @@
|
||||
<template>
|
||||
<div v-if="filterNames.length > 0"
|
||||
:title=title
|
||||
<div
|
||||
v-if="filterNames.length > 0"
|
||||
:title="title"
|
||||
class="c-filter-indication"
|
||||
:class="{ 'c-filter-indication--mixed': hasMixedFilters }">
|
||||
:class="{ 'c-filter-indication--mixed': hasMixedFilters }"
|
||||
>
|
||||
<span class="c-filter-indication__mixed">{{ label }}</span>
|
||||
<span v-for="(name, index) in filterNames"
|
||||
class="c-filter-indication__label">
|
||||
<span
|
||||
v-for="(name, index) in filterNames"
|
||||
:key="index"
|
||||
class="c-filter-indication__label"
|
||||
>
|
||||
{{ name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -53,13 +58,13 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const FILTER_INDICATOR_LABEL = 'Filters:';
|
||||
const FILTER_INDICATOR_LABEL_MIXED = 'Mixed Filters:';
|
||||
const FILTER_INDICATOR_TITLE = 'Data filters are being applied to this view.';
|
||||
const FILTER_INDICATOR_TITLE_MIXED = 'A mix of data filter values are being applied to this view.';
|
||||
const USE_GLOBAL = 'useGlobal';
|
||||
const FILTER_INDICATOR_LABEL = 'Filters:';
|
||||
const FILTER_INDICATOR_LABEL_MIXED = 'Mixed Filters:';
|
||||
const FILTER_INDICATOR_TITLE = 'Data filters are being applied to this view.';
|
||||
const FILTER_INDICATOR_TITLE_MIXED = 'A mix of data filter values are being applied to this view.';
|
||||
const USE_GLOBAL = 'useGlobal';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct', 'table'],
|
||||
data() {
|
||||
return {
|
||||
@ -89,6 +94,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let filters = this.table.configuration.getConfiguration().filters || {};
|
||||
this.table.configuration.on('change', this.handleConfigurationChanges);
|
||||
this.updateFilters(filters);
|
||||
},
|
||||
destroyed() {
|
||||
this.table.configuration.off('change', this.handleConfigurationChanges);
|
||||
},
|
||||
methods: {
|
||||
setFilterNames() {
|
||||
let names = [];
|
||||
@ -129,7 +142,7 @@
|
||||
|
||||
return _.flatten(filterNames);
|
||||
},
|
||||
getFilterLabels(filterObject, metadatum, ) {
|
||||
getFilterLabels(filterObject, metadatum,) {
|
||||
let filterLabels = [];
|
||||
Object.values(filterObject).forEach(comparator => {
|
||||
comparator.forEach(filterValue => {
|
||||
@ -152,14 +165,6 @@
|
||||
this.filteredTelemetry = JSON.parse(JSON.stringify(filters));
|
||||
this.setFilterNames();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let filters = this.table.configuration.getConfiguration().filters || {};
|
||||
this.table.configuration.on('change', this.handleConfigurationChanges);
|
||||
this.updateFilters(filters);
|
||||
},
|
||||
destroyed() {
|
||||
this.table.configuration.off('change', this.handleConfigurationChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -20,7 +20,12 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<td @click="selectCell($event.currentTarget, columnKey)" :title="formattedValue">{{formattedValue}}</td>
|
||||
<td
|
||||
:title="formattedValue"
|
||||
@click="selectCell($event.currentTarget, columnKey)"
|
||||
>
|
||||
{{ formattedValue }}
|
||||
</td>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
@ -32,11 +37,20 @@ export default {
|
||||
},
|
||||
columnKey: {
|
||||
type: String,
|
||||
require: true
|
||||
required: true
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
require: false
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
formattedValue() {
|
||||
return this.row.getFormattedValue(this.columnKey);
|
||||
},
|
||||
isSelectable() {
|
||||
let column = this.row.columns[this.columnKey];
|
||||
return column && column.selectable;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -57,15 +71,6 @@ export default {
|
||||
}], false);
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
formattedValue() {
|
||||
return this.row.getFormattedValue(this.columnKey);
|
||||
},
|
||||
isSelectable() {
|
||||
let column = this.row.columns[this.columnKey];
|
||||
return column && column.selectable;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -29,12 +29,17 @@
|
||||
drop: columnMoveEnd,
|
||||
dragleave: hideDropTarget,
|
||||
dragover: dragOverColumn
|
||||
} : {}">
|
||||
<div class="c-telemetry-table__headers__content" :class="[
|
||||
} : {}"
|
||||
>
|
||||
<div
|
||||
class="c-telemetry-table__headers__content"
|
||||
:class="[
|
||||
isSortable ? 'is-sortable' : '',
|
||||
isSortable && sortOptions.key === headerKey ? 'is-sorting' : '',
|
||||
isSortable && sortOptions.direction].join(' ')">
|
||||
<div class="c-telemetry-table__resize-hitarea"
|
||||
isSortable && sortOptions.direction].join(' ')"
|
||||
>
|
||||
<div
|
||||
class="c-telemetry-table__resize-hitarea"
|
||||
@mousedown="resizeColumnStart"
|
||||
></div>
|
||||
<slot></slot>
|
||||
@ -42,17 +47,31 @@
|
||||
</th>
|
||||
</template>
|
||||
<script>
|
||||
import _ from 'lodash';
|
||||
const MOVE_COLUMN_DT_TYPE = 'movecolumnfromindex';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
headerKey: String,
|
||||
headerIndex: Number,
|
||||
isHeaderTitle: Boolean,
|
||||
sortOptions: Object,
|
||||
columnWidth: Number,
|
||||
headerKey: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
headerIndex: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
isHeaderTitle: {
|
||||
type: Boolean,
|
||||
default: undefined
|
||||
},
|
||||
sortOptions: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
columnWidth: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
},
|
||||
hotzone: Boolean,
|
||||
isEditing: Boolean
|
||||
},
|
||||
@ -94,7 +113,7 @@ export default {
|
||||
return [...event.dataTransfer.types].includes(MOVE_COLUMN_DT_TYPE);
|
||||
},
|
||||
dragOverColumn(event) {
|
||||
if (this.isColumnMoveEvent(event)){
|
||||
if (this.isColumnMoveEvent(event)) {
|
||||
event.preventDefault();
|
||||
this.updateDropOffset(event.currentTarget, event.clientX);
|
||||
} else {
|
||||
@ -114,19 +133,19 @@ export default {
|
||||
this.$emit('dropTargetOffsetChanged', dropOffsetLeft);
|
||||
this.$emit('dropTargetActive', true);
|
||||
},
|
||||
hideDropTarget(){
|
||||
hideDropTarget() {
|
||||
this.$emit('dropTargetActive', false);
|
||||
},
|
||||
columnMoveEnd(event){
|
||||
if (this.isColumnMoveEvent(event)){
|
||||
columnMoveEnd(event) {
|
||||
if (this.isColumnMoveEvent(event)) {
|
||||
let toIndex = this.headerIndex;
|
||||
let fromIndex = event.dataTransfer.getData(MOVE_COLUMN_DT_TYPE);
|
||||
if (event.offsetX < event.target.offsetWidth / 2) {
|
||||
if (toIndex > fromIndex){
|
||||
if (toIndex > fromIndex) {
|
||||
toIndex--;
|
||||
}
|
||||
} else {
|
||||
if (toIndex < fromIndex){
|
||||
if (toIndex < fromIndex) {
|
||||
toIndex++;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,50 @@
|
||||
<template>
|
||||
<div class="c-properties">
|
||||
<template v-if="isEditing">
|
||||
<div class="c-properties__header">Table Column Size</div>
|
||||
<div class="c-properties__header">
|
||||
Table Column Size
|
||||
</div>
|
||||
<ul class="c-properties__section">
|
||||
<li class="c-properties__row">
|
||||
<div class="c-properties__label" title="Auto-size table"><label for="AutoSizeControl">Auto-size</label></div>
|
||||
<div class="c-properties__value"><input type="checkbox" id="AutoSizeControl" :checked="configuration.autosize !== false" @change="toggleAutosize()"></div>
|
||||
<div
|
||||
class="c-properties__label"
|
||||
title="Auto-size table"
|
||||
>
|
||||
<label for="AutoSizeControl">Auto-size</label>
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
<input
|
||||
id="AutoSizeControl"
|
||||
type="checkbox"
|
||||
:checked="configuration.autosize !== false"
|
||||
@change="toggleAutosize()"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="c-properties__header">Table Column Visibility</div>
|
||||
<div class="c-properties__header">
|
||||
Table Column Visibility
|
||||
</div>
|
||||
<ul class="c-properties__section">
|
||||
<li class="c-properties__row" v-for="(title, key) in headers">
|
||||
<div class="c-properties__label" title="Show or hide column"><label :for="key + 'ColumnControl'">{{title}}</label></div>
|
||||
<div class="c-properties__value"><input type="checkbox" :id="key + 'ColumnControl'" :checked="configuration.hiddenColumns[key] !== true" @change="toggleColumn(key)"></div>
|
||||
<li
|
||||
v-for="(title, key) in headers"
|
||||
:key="key"
|
||||
class="c-properties__row"
|
||||
>
|
||||
<div
|
||||
class="c-properties__label"
|
||||
title="Show or hide column"
|
||||
>
|
||||
<label :for="key + 'ColumnControl'">{{ title }}</label>
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
<input
|
||||
:id="key + 'ColumnControl'"
|
||||
type="checkbox"
|
||||
:checked="configuration.hiddenColumns[key] !== true"
|
||||
@change="toggleColumn(key)"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
@ -34,6 +66,28 @@ export default {
|
||||
configuration: this.tableConfiguration.getConfiguration()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.unlisteners = [];
|
||||
this.openmct.editor.on('isEditing', this.toggleEdit);
|
||||
let compositionCollection = this.openmct.composition.get(this.tableConfiguration.domainObject);
|
||||
|
||||
compositionCollection.load()
|
||||
.then((composition) => {
|
||||
this.addColumnsForAllObjects(composition);
|
||||
this.updateHeaders(this.tableConfiguration.getAllHeaders());
|
||||
|
||||
compositionCollection.on('add', this.addObject);
|
||||
this.unlisteners.push(compositionCollection.off.bind(compositionCollection, 'add', this.addObject));
|
||||
|
||||
compositionCollection.on('remove', this.removeObject);
|
||||
this.unlisteners.push(compositionCollection.off.bind(compositionCollection, 'remove', this.removeObject));
|
||||
});
|
||||
},
|
||||
destroyed() {
|
||||
this.tableConfiguration.destroy();
|
||||
this.openmct.editor.off('isEditing', this.toggleEdit);
|
||||
this.unlisteners.forEach((unlisten) => unlisten());
|
||||
},
|
||||
methods: {
|
||||
updateHeaders(headers) {
|
||||
this.headers = headers;
|
||||
@ -70,28 +124,6 @@ export default {
|
||||
this.tableConfiguration.addSingleColumnForObject(telemetryObject, column);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.unlisteners = [];
|
||||
this.openmct.editor.on('isEditing', this.toggleEdit);
|
||||
let compositionCollection = this.openmct.composition.get(this.tableConfiguration.domainObject);
|
||||
|
||||
compositionCollection.load()
|
||||
.then((composition) => {
|
||||
this.addColumnsForAllObjects(composition);
|
||||
this.updateHeaders(this.tableConfiguration.getAllHeaders());
|
||||
|
||||
compositionCollection.on('add', this.addObject);
|
||||
this.unlisteners.push(compositionCollection.off.bind(compositionCollection, 'add', this.addObject));
|
||||
|
||||
compositionCollection.on('remove', this.removeObject);
|
||||
this.unlisteners.push(compositionCollection.off.bind(compositionCollection, 'remove', this.removeObject));
|
||||
});
|
||||
},
|
||||
destroyed() {
|
||||
this.tableConfiguration.destroy();
|
||||
this.openmct.editor.off('isEditing', this.toggleEdit);
|
||||
this.unlisteners.forEach((unlisten) => unlisten());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -20,22 +20,25 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<tr :style="{ top: rowTop }"
|
||||
<tr
|
||||
:style="{ top: rowTop }"
|
||||
class="noselect"
|
||||
:class="[
|
||||
rowClass,
|
||||
{'is-selected': marked}
|
||||
]"
|
||||
v-on="listeners">
|
||||
<component v-for="(title, key) in headers"
|
||||
:key="key"
|
||||
v-on="listeners"
|
||||
>
|
||||
<component
|
||||
:is="componentList[key]"
|
||||
:columnKey="key"
|
||||
v-for="(title, key) in headers"
|
||||
:key="key"
|
||||
:column-key="key"
|
||||
:style="columnWidths[key] === undefined ? {} : { width: columnWidths[key] + 'px', 'max-width': columnWidths[key] + 'px'}"
|
||||
:class="[cellLimitClasses[key], selectableColumns[key] ? 'is-selectable' : '']"
|
||||
:objectPath="objectPath"
|
||||
:row="row">
|
||||
</component>
|
||||
:object-path="objectPath"
|
||||
:row="row"
|
||||
/>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
@ -55,21 +58,9 @@
|
||||
import TableCell from './table-cell.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'objectPath'],
|
||||
data: function () {
|
||||
return {
|
||||
rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px',
|
||||
rowClass: this.row.getRowClass(),
|
||||
cellLimitClasses: this.row.getCellLimitClasses(),
|
||||
componentList: Object.keys(this.headers).reduce((components, header) => {
|
||||
components[header] = this.row.getCellComponentName(header) || 'table-cell';
|
||||
return components
|
||||
}, {}),
|
||||
selectableColumns : Object.keys(this.row.columns).reduce((selectable, columnKeys) => {
|
||||
selectable[columnKeys] = this.row.columns[columnKeys].selectable;
|
||||
return selectable;
|
||||
}, {})
|
||||
}
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
TableCell
|
||||
},
|
||||
props: {
|
||||
headers: {
|
||||
@ -86,7 +77,7 @@ export default {
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
required: false
|
||||
required: true
|
||||
},
|
||||
rowIndex: {
|
||||
type: Number,
|
||||
@ -109,6 +100,42 @@ export default {
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px',
|
||||
rowClass: this.row.getRowClass(),
|
||||
cellLimitClasses: this.row.getCellLimitClasses(),
|
||||
componentList: Object.keys(this.headers).reduce((components, header) => {
|
||||
components[header] = this.row.getCellComponentName(header) || 'table-cell';
|
||||
return components
|
||||
}, {}),
|
||||
selectableColumns : Object.keys(this.row.columns).reduce((selectable, columnKeys) => {
|
||||
selectable[columnKeys] = this.row.columns[columnKeys].selectable;
|
||||
return selectable;
|
||||
}, {})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
listeners() {
|
||||
let listenersObject = {
|
||||
click: this.markRow
|
||||
}
|
||||
|
||||
if (this.row.getContextMenuActions().length) {
|
||||
listenersObject.contextmenu = this.showContextMenu;
|
||||
}
|
||||
|
||||
return listenersObject;
|
||||
}
|
||||
},
|
||||
// TODO: use computed properties
|
||||
watch: {
|
||||
rowOffset: 'calculateRowTop',
|
||||
row: {
|
||||
handler: 'formatRow',
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
calculateRowTop: function (rowOffset) {
|
||||
this.rowTop = (rowOffset + this.rowIndex) * this.rowHeight + 'px';
|
||||
@ -163,30 +190,6 @@ export default {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(contextualObjectPath, event.x, event.y, this.row.getContextMenuActions());
|
||||
});
|
||||
}
|
||||
},
|
||||
// TODO: use computed properties
|
||||
watch: {
|
||||
rowOffset: 'calculateRowTop',
|
||||
row: {
|
||||
handler: 'formatRow',
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
TableCell
|
||||
},
|
||||
computed: {
|
||||
listeners() {
|
||||
let listenersObject = {
|
||||
click: this.markRow
|
||||
}
|
||||
|
||||
if (this.row.getContextMenuActions().length) {
|
||||
listenersObject.contextmenu = this.showContextMenu;
|
||||
}
|
||||
|
||||
return listenersObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -22,131 +22,178 @@
|
||||
<template>
|
||||
<div class="c-table-wrapper">
|
||||
<div class="c-table-control-bar c-control-bar">
|
||||
<button class="c-button icon-download labeled"
|
||||
<button
|
||||
v-if="allowExport"
|
||||
v-on:click="exportAllDataAsCSV()"
|
||||
title="Export This View's Data">
|
||||
class="c-button icon-download labeled"
|
||||
title="Export This View's Data"
|
||||
@click="exportAllDataAsCSV()"
|
||||
>
|
||||
<span class="c-button__label">Export Table Data</span>
|
||||
</button>
|
||||
<button class="c-button icon-download labeled"
|
||||
<button
|
||||
v-if="allowExport"
|
||||
v-show="markedRows.length"
|
||||
v-on:click="exportMarkedDataAsCSV()"
|
||||
title="Export Marked Rows As CSV">
|
||||
class="c-button icon-download labeled"
|
||||
title="Export Marked Rows As CSV"
|
||||
@click="exportMarkedDataAsCSV()"
|
||||
>
|
||||
<span class="c-button__label">Export Marked Rows</span>
|
||||
</button>
|
||||
<button class="c-button icon-x labeled"
|
||||
<button
|
||||
v-show="markedRows.length"
|
||||
v-on:click="unmarkAllRows()"
|
||||
title="Unmark All Rows">
|
||||
class="c-button icon-x labeled"
|
||||
title="Unmark All Rows"
|
||||
@click="unmarkAllRows()"
|
||||
>
|
||||
<span class="c-button__label">Unmark All Rows</span>
|
||||
</button>
|
||||
<div v-if="enableMarking"
|
||||
class="c-separator">
|
||||
</div>
|
||||
<button v-if="enableMarking"
|
||||
<div
|
||||
v-if="enableMarking"
|
||||
class="c-separator"
|
||||
></div>
|
||||
<button
|
||||
v-if="enableMarking"
|
||||
class="c-button icon-pause pause-play labeled"
|
||||
:class=" paused ? 'icon-play is-paused' : 'icon-pause'"
|
||||
v-on:click="togglePauseByButton()"
|
||||
:title="paused ? 'Continue Data Flow' : 'Pause Data Flow'">
|
||||
:title="paused ? 'Continue Data Flow' : 'Pause Data Flow'"
|
||||
@click="togglePauseByButton()"
|
||||
>
|
||||
<span class="c-button__label">
|
||||
{{paused ? 'Play' : 'Pause'}}
|
||||
{{ paused ? 'Play' : 'Pause' }}
|
||||
</span>
|
||||
</button>
|
||||
<slot name="buttons"></slot>
|
||||
</div>
|
||||
|
||||
<div class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
|
||||
<div
|
||||
class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
|
||||
:class="{
|
||||
'loading': loading,
|
||||
'paused' : paused
|
||||
}">
|
||||
}"
|
||||
>
|
||||
<div :style="{ 'max-width': widthWithScroll, 'min-width': '150px'}">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<div :style="{ 'max-width': widthWithScroll, 'min-width': '150px'}"><slot></slot></div>
|
||||
|
||||
<div v-if="isDropTargetActive" class="c-telemetry-table__drop-target" :style="dropTargetStyle"></div>
|
||||
<div
|
||||
v-if="isDropTargetActive"
|
||||
class="c-telemetry-table__drop-target"
|
||||
:style="dropTargetStyle"
|
||||
></div>
|
||||
<!-- Headers table -->
|
||||
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
|
||||
<div
|
||||
ref="headersTable"
|
||||
class="c-telemetry-table__headers-w js-table__headers-w"
|
||||
:style="{ 'max-width': widthWithScroll}"
|
||||
>
|
||||
<table class="c-table__headers c-telemetry-table__headers">
|
||||
<thead>
|
||||
<tr class="c-telemetry-table__headers__labels">
|
||||
<table-column-header
|
||||
v-for="(title, key, headerIndex) in headers"
|
||||
:key="key"
|
||||
:headerKey="key"
|
||||
:headerIndex="headerIndex"
|
||||
:header-key="key"
|
||||
:header-index="headerIndex"
|
||||
:column-width="columnWidths[key]"
|
||||
:sort-options="sortOptions"
|
||||
:is-editing="isEditing"
|
||||
@sort="allowSorting && sortBy(key)"
|
||||
@resizeColumn="resizeColumn"
|
||||
@dropTargetOffsetChanged="setDropTargetOffset"
|
||||
@dropTargetActive="dropTargetActive"
|
||||
@reorderColumn="reorderColumn"
|
||||
@resizeColumnEnd="updateConfiguredColumnWidths"
|
||||
:columnWidth="columnWidths[key]"
|
||||
:sortOptions="sortOptions"
|
||||
:isEditing="isEditing"
|
||||
><span class="c-telemetry-table__headers__label">{{title}}</span>
|
||||
>
|
||||
<span class="c-telemetry-table__headers__label">{{ title }}</span>
|
||||
</table-column-header>
|
||||
</tr>
|
||||
<tr v-if="allowFiltering" class="c-telemetry-table__headers__filter">
|
||||
<tr
|
||||
v-if="allowFiltering"
|
||||
class="c-telemetry-table__headers__filter"
|
||||
>
|
||||
<table-column-header
|
||||
v-for="(title, key, headerIndex) in headers"
|
||||
:key="key"
|
||||
:headerKey="key"
|
||||
:headerIndex="headerIndex"
|
||||
:header-key="key"
|
||||
:header-index="headerIndex"
|
||||
:column-width="columnWidths[key]"
|
||||
:is-editing="isEditing"
|
||||
@resizeColumn="resizeColumn"
|
||||
@dropTargetOffsetChanged="setDropTargetOffset"
|
||||
@dropTargetActive="dropTargetActive"
|
||||
@reorderColumn="reorderColumn"
|
||||
@resizeColumnEnd="updateConfiguredColumnWidths"
|
||||
:columnWidth="columnWidths[key]"
|
||||
:isEditing="isEditing"
|
||||
>
|
||||
<search class="c-table__search"
|
||||
<search
|
||||
v-model="filters[key]"
|
||||
v-on:input="filterChanged(key)"
|
||||
v-on:clear="clearFilter(key)" />
|
||||
class="c-table__search"
|
||||
@input="filterChanged(key)"
|
||||
@clear="clearFilter(key)"
|
||||
/>
|
||||
</table-column-header>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Content table -->
|
||||
<div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
|
||||
<div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
|
||||
<table class="c-table__body c-telemetry-table__body js-telemetry-table__content"
|
||||
:style="{ height: totalHeight + 'px'}">
|
||||
<div
|
||||
class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w"
|
||||
:style="{ 'max-width': widthWithScroll}"
|
||||
@scroll="scroll"
|
||||
>
|
||||
<div
|
||||
class="c-telemetry-table__scroll-forcer"
|
||||
:style="{ width: totalWidth + 'px' }"
|
||||
></div>
|
||||
<table
|
||||
class="c-table__body c-telemetry-table__body js-telemetry-table__content"
|
||||
:style="{ height: totalHeight + 'px'}"
|
||||
>
|
||||
<tbody>
|
||||
<telemetry-table-row v-for="(row, rowIndex) in visibleRows"
|
||||
<telemetry-table-row
|
||||
v-for="(row, rowIndex) in visibleRows"
|
||||
:key="rowIndex"
|
||||
:headers="headers"
|
||||
:columnWidths="columnWidths"
|
||||
:rowIndex="rowIndex"
|
||||
:objectPath="objectPath"
|
||||
:rowOffset="rowOffset"
|
||||
:rowHeight="rowHeight"
|
||||
:column-widths="columnWidths"
|
||||
:row-index="rowIndex"
|
||||
:object-path="objectPath"
|
||||
:row-offset="rowOffset"
|
||||
:row-height="rowHeight"
|
||||
:row="row"
|
||||
:marked="row.marked"
|
||||
@mark="markRow"
|
||||
@unmark="unmarkRow"
|
||||
@markMultipleConcurrent="markMultipleConcurrentRows">
|
||||
</telemetry-table-row>
|
||||
@markMultipleConcurrent="markMultipleConcurrentRows"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Sizing table -->
|
||||
<table class="c-telemetry-table__sizing js-telemetry-table__sizing" :style="sizingTableWidth">
|
||||
<table
|
||||
class="c-telemetry-table__sizing js-telemetry-table__sizing"
|
||||
:style="sizingTableWidth"
|
||||
>
|
||||
<tr>
|
||||
<template v-for="(title, key) in headers">
|
||||
<th :key="key" :style="{ width: configuredColumnWidths[key] + 'px', 'max-width': configuredColumnWidths[key] + 'px'}">{{title}}</th>
|
||||
<th
|
||||
:key="key"
|
||||
:style="{ width: configuredColumnWidths[key] + 'px', 'max-width': configuredColumnWidths[key] + 'px'}"
|
||||
>
|
||||
{{ title }}
|
||||
</th>
|
||||
</template>
|
||||
</tr>
|
||||
<telemetry-table-row v-for="(sizingRowData, objectKeyString) in sizingRows"
|
||||
<telemetry-table-row
|
||||
v-for="(sizingRowData, objectKeyString) in sizingRows"
|
||||
:key="objectKeyString"
|
||||
:headers="headers"
|
||||
:columnWidths="configuredColumnWidths"
|
||||
:row="sizingRowData">
|
||||
</telemetry-table-row>
|
||||
:column-widths="configuredColumnWidths"
|
||||
:row="sizingRowData"
|
||||
:object-path="objectPath"
|
||||
/>
|
||||
</table>
|
||||
<telemetry-filter-indicator></telemetry-filter-indicator>
|
||||
<telemetry-filter-indicator />
|
||||
</div>
|
||||
</div><!-- closes c-table-wrapper -->
|
||||
</template>
|
||||
@ -343,9 +390,6 @@ const VISIBLE_ROW_COUNT = 100;
|
||||
const ROW_HEIGHT = 17;
|
||||
const RESIZE_POLL_INTERVAL = 200;
|
||||
const AUTO_SCROLL_TRIGGER_HEIGHT = 100;
|
||||
const RESIZE_HOT_ZONE = 10;
|
||||
const MOVE_TRIGGER_WAIT = 500;
|
||||
const VERTICAL_SCROLL_WIDTH = 30;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -440,6 +484,59 @@ export default {
|
||||
return style;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.filterChanged = _.debounce(this.filterChanged, 500);
|
||||
},
|
||||
mounted() {
|
||||
this.csvExporter = new CSVExporter();
|
||||
this.rowsAdded = _.throttle(this.rowsAdded, 200);
|
||||
this.rowsRemoved = _.throttle(this.rowsRemoved, 200);
|
||||
this.scroll = _.throttle(this.scroll, 100);
|
||||
|
||||
this.table.on('object-added', this.addObject);
|
||||
this.table.on('object-removed', this.removeObject);
|
||||
this.table.on('outstanding-requests', this.outstandingRequests);
|
||||
this.table.on('refresh', this.clearRowsAndRerender);
|
||||
|
||||
this.table.filteredRows.on('add', this.rowsAdded);
|
||||
this.table.filteredRows.on('remove', this.rowsRemoved);
|
||||
this.table.filteredRows.on('sort', this.updateVisibleRows);
|
||||
this.table.filteredRows.on('filter', this.updateVisibleRows);
|
||||
|
||||
//Default sort
|
||||
this.sortOptions = this.table.filteredRows.sortBy();
|
||||
this.scrollable = this.$el.querySelector('.js-telemetry-table__body-w');
|
||||
this.contentTable = this.$el.querySelector('.js-telemetry-table__content');
|
||||
this.sizingTable = this.$el.querySelector('.js-telemetry-table__sizing');
|
||||
this.headersHolderEl = this.$el.querySelector('.js-table__headers-w');
|
||||
|
||||
this.table.configuration.on('change', this.updateConfiguration);
|
||||
|
||||
this.calculateTableSize();
|
||||
this.pollForResize();
|
||||
this.calculateScrollbarWidth();
|
||||
|
||||
this.table.initialize();
|
||||
},
|
||||
destroyed() {
|
||||
this.table.off('object-added', this.addObject);
|
||||
this.table.off('object-removed', this.removeObject);
|
||||
this.table.off('outstanding-requests', this.outstandingRequests);
|
||||
this.table.off('refresh', this.clearRowsAndRerender);
|
||||
|
||||
this.table.filteredRows.off('add', this.rowsAdded);
|
||||
this.table.filteredRows.off('remove', this.rowsRemoved);
|
||||
this.table.filteredRows.off('sort', this.updateVisibleRows);
|
||||
this.table.filteredRows.off('filter', this.updateVisibleRows);
|
||||
|
||||
this.table.configuration.off('change', this.updateConfiguration);
|
||||
|
||||
clearInterval(this.resizePollHandle);
|
||||
|
||||
this.table.configuration.destroy();
|
||||
|
||||
this.table.destroy();
|
||||
},
|
||||
methods: {
|
||||
updateVisibleRows() {
|
||||
if (!this.updatingView) {
|
||||
@ -527,7 +624,7 @@ export default {
|
||||
}
|
||||
this.table.sortBy(this.sortOptions);
|
||||
},
|
||||
scroll () {
|
||||
scroll() {
|
||||
this.updateVisibleRows();
|
||||
this.synchronizeScrollX();
|
||||
|
||||
@ -557,7 +654,7 @@ export default {
|
||||
this.table.filteredRows.setColumnFilter(columnKey, '');
|
||||
this.setHeight();
|
||||
},
|
||||
rowsAdded (rows) {
|
||||
rowsAdded(rows) {
|
||||
this.setHeight();
|
||||
|
||||
let sizingRow;
|
||||
@ -578,7 +675,7 @@ export default {
|
||||
|
||||
this.updateVisibleRows();
|
||||
},
|
||||
rowsRemoved (rows) {
|
||||
rowsRemoved(rows) {
|
||||
this.setHeight();
|
||||
this.updateVisibleRows();
|
||||
},
|
||||
@ -811,66 +908,12 @@ export default {
|
||||
let row = allRows[i];
|
||||
row.marked = true;
|
||||
|
||||
if (row !== baseRow){
|
||||
if (row !== baseRow) {
|
||||
this.markedRows.push(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.filterChanged = _.debounce(this.filterChanged, 500);
|
||||
},
|
||||
mounted() {
|
||||
console.log("Table mounted");
|
||||
this.csvExporter = new CSVExporter();
|
||||
this.rowsAdded = _.throttle(this.rowsAdded, 200);
|
||||
this.rowsRemoved = _.throttle(this.rowsRemoved, 200);
|
||||
this.scroll = _.throttle(this.scroll, 100);
|
||||
|
||||
this.table.on('object-added', this.addObject);
|
||||
this.table.on('object-removed', this.removeObject);
|
||||
this.table.on('outstanding-requests', this.outstandingRequests);
|
||||
this.table.on('refresh', this.clearRowsAndRerender);
|
||||
|
||||
this.table.filteredRows.on('add', this.rowsAdded);
|
||||
this.table.filteredRows.on('remove', this.rowsRemoved);
|
||||
this.table.filteredRows.on('sort', this.updateVisibleRows);
|
||||
this.table.filteredRows.on('filter', this.updateVisibleRows);
|
||||
|
||||
//Default sort
|
||||
this.sortOptions = this.table.filteredRows.sortBy();
|
||||
this.scrollable = this.$el.querySelector('.js-telemetry-table__body-w');
|
||||
this.contentTable = this.$el.querySelector('.js-telemetry-table__content');
|
||||
this.sizingTable = this.$el.querySelector('.js-telemetry-table__sizing');
|
||||
this.headersHolderEl = this.$el.querySelector('.js-table__headers-w');
|
||||
|
||||
this.table.configuration.on('change', this.updateConfiguration);
|
||||
|
||||
this.calculateTableSize();
|
||||
this.pollForResize();
|
||||
this.calculateScrollbarWidth();
|
||||
|
||||
this.table.initialize();
|
||||
},
|
||||
destroyed() {
|
||||
this.table.off('object-added', this.addObject);
|
||||
this.table.off('object-removed', this.removeObject);
|
||||
this.table.off('outstanding-requests', this.outstandingRequests);
|
||||
this.table.off('refresh', this.clearRowsAndRerender);
|
||||
|
||||
this.table.filteredRows.off('add', this.rowsAdded);
|
||||
this.table.filteredRows.off('remove', this.rowsRemoved);
|
||||
this.table.filteredRows.off('sort', this.updateVisibleRows);
|
||||
this.table.filteredRows.off('filter', this.updateVisibleRows);
|
||||
|
||||
this.table.configuration.off('change', this.updateConfiguration);
|
||||
|
||||
clearInterval(this.resizePollHandle);
|
||||
|
||||
this.table.configuration.destroy();
|
||||
|
||||
this.table.destroy();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -20,39 +20,63 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-conductor"
|
||||
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode']">
|
||||
<form class="u-contents" ref="conductorForm" @submit.prevent="updateTimeFromConductor">
|
||||
<div
|
||||
class="c-conductor"
|
||||
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode']"
|
||||
>
|
||||
<form
|
||||
ref="conductorForm"
|
||||
class="u-contents"
|
||||
@submit.prevent="updateTimeFromConductor"
|
||||
>
|
||||
<div class="c-conductor__time-bounds">
|
||||
<button class="c-input--submit" type="submit" ref="submitButton"></button>
|
||||
<ConductorModeIcon class="c-conductor__mode-icon"></ConductorModeIcon>
|
||||
<button
|
||||
ref="submitButton"
|
||||
class="c-input--submit"
|
||||
type="submit"
|
||||
></button>
|
||||
<ConductorModeIcon class="c-conductor__mode-icon" />
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-fixed"
|
||||
v-if="isFixed">
|
||||
<div
|
||||
v-if="isFixed"
|
||||
class="c-ctrl-wrapper c-conductor-input c-conductor__start-fixed"
|
||||
>
|
||||
<!-- Fixed start -->
|
||||
<div class="c-conductor__start-fixed__label">Start</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
<div class="c-conductor__start-fixed__label">
|
||||
Start
|
||||
</div>
|
||||
<input
|
||||
ref="startDate"
|
||||
v-model="formattedBounds.start"
|
||||
@change="validateAllBounds(); submitForm()" />
|
||||
class="c-input--datetime"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
@change="validateAllBounds(); submitForm()"
|
||||
>
|
||||
<date-picker
|
||||
v-if="isFixed && isUTCBased"
|
||||
:default-date-time="formattedBounds.start"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="startDateSelected"></date-picker>
|
||||
@date-selected="startDateSelected"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-delta"
|
||||
v-if="!isFixed">
|
||||
<div
|
||||
v-if="!isFixed"
|
||||
class="c-ctrl-wrapper c-conductor-input c-conductor__start-delta"
|
||||
>
|
||||
<!-- RT start -->
|
||||
<div class="c-direction-indicator icon-minus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text" autocorrect="off"
|
||||
<input
|
||||
ref="startOffset"
|
||||
spellcheck="false"
|
||||
v-model="offsets.start"
|
||||
@change="validateAllOffsets(); submitForm()">
|
||||
class="c-input--hrs-min-sec"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
@change="validateAllOffsets(); submitForm()"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-fixed">
|
||||
@ -60,47 +84,59 @@
|
||||
<div class="c-conductor__end-fixed__label">
|
||||
{{ isFixed ? 'End' : 'Updated' }}
|
||||
</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="formattedBounds.end"
|
||||
:disabled="!isFixed"
|
||||
<input
|
||||
ref="endDate"
|
||||
@change="validateAllBounds(); submitForm()">
|
||||
v-model="formattedBounds.end"
|
||||
class="c-input--datetime"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
:disabled="!isFixed"
|
||||
@change="validateAllBounds(); submitForm()"
|
||||
>
|
||||
<date-picker
|
||||
v-if="isFixed && isUTCBased"
|
||||
class="c-ctrl-wrapper--menus-left"
|
||||
:default-date-time="formattedBounds.end"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="endDateSelected"></date-picker>
|
||||
@date-selected="endDateSelected"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-delta"
|
||||
v-if="!isFixed">
|
||||
<div
|
||||
v-if="!isFixed"
|
||||
class="c-ctrl-wrapper c-conductor-input c-conductor__end-delta"
|
||||
>
|
||||
<!-- RT end -->
|
||||
<div class="c-direction-indicator icon-plus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
<input
|
||||
ref="endOffset"
|
||||
v-model="offsets.end"
|
||||
class="c-input--hrs-min-sec"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
ref="endOffset"
|
||||
v-model="offsets.end"
|
||||
@change="validateAllOffsets(); submitForm()">
|
||||
@change="validateAllOffsets(); submitForm()"
|
||||
>
|
||||
</div>
|
||||
|
||||
<conductor-axis
|
||||
class="c-conductor__ticks"
|
||||
:bounds="rawBounds"
|
||||
@panAxis="setViewFromBounds"></conductor-axis>
|
||||
|
||||
@panAxis="setViewFromBounds"
|
||||
/>
|
||||
</div>
|
||||
<div class="c-conductor__controls">
|
||||
<!-- Mode, time system menu buttons and duration slider -->
|
||||
<ConductorMode class="c-conductor__mode-select"></ConductorMode>
|
||||
<ConductorTimeSystem class="c-conductor__time-system-select"></ConductorTimeSystem>
|
||||
<ConductorMode class="c-conductor__mode-select" />
|
||||
<ConductorTimeSystem class="c-conductor__time-system-select" />
|
||||
</div>
|
||||
<input type="submit" class="invisible">
|
||||
<input
|
||||
type="submit"
|
||||
class="invisible"
|
||||
>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -288,7 +324,6 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import ConductorMode from './ConductorMode.vue';
|
||||
import ConductorTimeSystem from './ConductorTimeSystem.vue';
|
||||
import DatePicker from './DatePicker.vue';
|
||||
@ -296,11 +331,6 @@ import ConductorAxis from './ConductorAxis.vue';
|
||||
import ConductorModeIcon from './ConductorModeIcon.vue';
|
||||
|
||||
const DEFAULT_DURATION_FORMATTER = 'duration';
|
||||
const SECONDS = 1000;
|
||||
const DAYS = 24 * 60 * 60 * SECONDS;
|
||||
const YEARS = 365 * DAYS;
|
||||
|
||||
const RESIZE_POLL_INTERVAL = 200;
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'configuration'],
|
||||
@ -323,7 +353,7 @@ export default {
|
||||
durationFormatter: durationFormatter,
|
||||
offsets: {
|
||||
start: offsets && durationFormatter.format(Math.abs(offsets.start)),
|
||||
end: offsets && durationFormatter.format(Math.abs(offsets.end)),
|
||||
end: offsets && durationFormatter.format(Math.abs(offsets.end))
|
||||
},
|
||||
formattedBounds: {
|
||||
start: timeFormatter.format(bounds.start),
|
||||
@ -338,6 +368,14 @@ export default {
|
||||
showDatePicker: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.timeSystem())));
|
||||
|
||||
this.openmct.time.on('bounds', this.setViewFromBounds);
|
||||
this.openmct.time.on('timeSystem', this.setTimeSystem);
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
this.openmct.time.on('clockOffsets', this.setViewFromOffsets)
|
||||
},
|
||||
methods: {
|
||||
setTimeSystem(timeSystem) {
|
||||
this.timeFormatter = this.getFormatter(timeSystem.timeFormat);
|
||||
@ -347,7 +385,7 @@ export default {
|
||||
this.isUTCBased = timeSystem.isUTCBased;
|
||||
},
|
||||
setOffsetsFromView($event) {
|
||||
if (this.$refs.conductorForm.checkValidity()){
|
||||
if (this.$refs.conductorForm.checkValidity()) {
|
||||
let startOffset = 0 - this.durationFormatter.parse(this.offsets.start);
|
||||
let endOffset = this.durationFormatter.parse(this.offsets.end);
|
||||
|
||||
@ -362,7 +400,7 @@ export default {
|
||||
}
|
||||
},
|
||||
setBoundsFromView($event) {
|
||||
if (this.$refs.conductorForm.checkValidity()){
|
||||
if (this.$refs.conductorForm.checkValidity()) {
|
||||
let start = this.timeFormatter.parse(this.formattedBounds.start);
|
||||
let end = this.timeFormatter.parse(this.formattedBounds.end);
|
||||
|
||||
@ -404,7 +442,7 @@ export default {
|
||||
[this.$refs.startOffset, this.$refs.endOffset].forEach(this.clearValidationForInput);
|
||||
}
|
||||
},
|
||||
clearValidationForInput(input){
|
||||
clearValidationForInput(input) {
|
||||
input.setCustomValidity('');
|
||||
input.title = '';
|
||||
},
|
||||
@ -419,7 +457,7 @@ export default {
|
||||
formattedDate = this.formattedBounds.end;
|
||||
}
|
||||
|
||||
if (!this.timeFormatter.validate(formattedDate)){
|
||||
if (!this.timeFormatter.validate(formattedDate)) {
|
||||
validationResult = 'Invalid date';
|
||||
} else {
|
||||
let boundsValues = {
|
||||
@ -429,7 +467,7 @@ export default {
|
||||
validationResult = this.openmct.time.validateBounds(boundsValues);
|
||||
}
|
||||
|
||||
if (validationResult !== true){
|
||||
if (validationResult !== true) {
|
||||
input.setCustomValidity(validationResult);
|
||||
input.title = validationResult;
|
||||
return false;
|
||||
@ -461,7 +499,7 @@ export default {
|
||||
validationResult = this.openmct.time.validateOffsets(offsetValues);
|
||||
}
|
||||
|
||||
if (validationResult !== true){
|
||||
if (validationResult !== true) {
|
||||
input.setCustomValidity(validationResult);
|
||||
input.title = validationResult;
|
||||
return false;
|
||||
@ -482,24 +520,16 @@ export default {
|
||||
format: key
|
||||
}).formatter;
|
||||
},
|
||||
startDateSelected(date){
|
||||
startDateSelected(date) {
|
||||
this.formattedBounds.start = this.timeFormatter.format(date);
|
||||
this.validateAllBounds();
|
||||
this.submitForm();
|
||||
},
|
||||
endDateSelected(date){
|
||||
endDateSelected(date) {
|
||||
this.formattedBounds.end = this.timeFormatter.format(date);
|
||||
this.validateAllBounds();
|
||||
this.submitForm();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.timeSystem())));
|
||||
|
||||
this.openmct.time.on('bounds', this.setViewFromBounds);
|
||||
this.openmct.time.on('timeSystem', this.setTimeSystem);
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
this.openmct.time.on('clockOffsets', this.setViewFromOffsets)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -20,10 +20,11 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-conductor-axis"
|
||||
<div
|
||||
ref="axisHolder"
|
||||
@mousedown="dragStart($event)">
|
||||
</div>
|
||||
class="c-conductor-axis"
|
||||
@mousedown="dragStart($event)"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -126,106 +127,9 @@ const PIXELS_PER_TICK_WIDE = 200;
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
bounds: Object
|
||||
},
|
||||
methods: {
|
||||
setScale() {
|
||||
let timeSystem = this.openmct.time.timeSystem();
|
||||
let bounds = this.bounds;
|
||||
|
||||
if (timeSystem.isUTCBased) {
|
||||
this.xScale.domain([new Date(bounds.start), new Date(bounds.end)]);
|
||||
} else {
|
||||
this.xScale.domain([bounds.start, bounds.end]);
|
||||
}
|
||||
|
||||
this.xAxis.scale(this.xScale);
|
||||
|
||||
this.xScale.range([PADDING, this.width - PADDING * 2]);
|
||||
this.axisElement.call(this.xAxis);
|
||||
|
||||
if (this.width > 1800) {
|
||||
this.xAxis.ticks(this.width / PIXELS_PER_TICK_WIDE);
|
||||
} else {
|
||||
this.xAxis.ticks(this.width / PIXELS_PER_TICK);
|
||||
}
|
||||
|
||||
this.msPerPixel = (bounds.end - bounds.start) / this.width;
|
||||
},
|
||||
setViewFromTimeSystem(timeSystem) {
|
||||
let format = this.getActiveFormatter();
|
||||
let bounds = this.openmct.time.bounds();
|
||||
|
||||
//The D3 scale used depends on the type of time system as d3
|
||||
// supports UTC out of the box.
|
||||
if (timeSystem.isUTCBased) {
|
||||
this.xScale = d3Scale.scaleUtc();
|
||||
} else {
|
||||
this.xScale = d3Scale.scaleLinear();
|
||||
}
|
||||
|
||||
this.xAxis.scale(this.xScale);
|
||||
this.xAxis.tickFormat(utcMultiTimeFormat);
|
||||
this.axisElement.call(this.xAxis);
|
||||
this.setScale();
|
||||
},
|
||||
getActiveFormatter() {
|
||||
let timeSystem = this.openmct.time.timeSystem();
|
||||
let isFixed = this.openmct.time.clock() === undefined;
|
||||
|
||||
if (isFixed) {
|
||||
return this.getFormatter(timeSystem.timeFormat);
|
||||
} else {
|
||||
return this.getFormatter(timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
|
||||
}
|
||||
},
|
||||
getFormatter(key) {
|
||||
return this.openmct.telemetry.getValueFormatter({
|
||||
format: key
|
||||
}).formatter;
|
||||
},
|
||||
dragStart($event){
|
||||
let isFixed = this.openmct.time.clock() === undefined;
|
||||
if (isFixed){
|
||||
this.dragStartX = $event.clientX;
|
||||
|
||||
document.addEventListener('mousemove', this.drag);
|
||||
document.addEventListener('mouseup', this.dragEnd, {
|
||||
once: true
|
||||
});
|
||||
}
|
||||
},
|
||||
drag($event) {
|
||||
if (!this.dragging){
|
||||
this.dragging = true;
|
||||
requestAnimationFrame(()=>{
|
||||
let deltaX = $event.clientX - this.dragStartX;
|
||||
let percX = deltaX / this.width;
|
||||
let bounds = this.openmct.time.bounds();
|
||||
let deltaTime = bounds.end - bounds.start;
|
||||
let newStart = bounds.start - percX * deltaTime;
|
||||
this.$emit('panAxis',{
|
||||
start: newStart,
|
||||
end: newStart + deltaTime
|
||||
});
|
||||
this.dragging = false;
|
||||
})
|
||||
} else {
|
||||
console.log('Rejected drag due to RAF cap');
|
||||
}
|
||||
},
|
||||
dragEnd() {
|
||||
document.removeEventListener('mousemove', this.drag);
|
||||
this.openmct.time.bounds({
|
||||
start: this.bounds.start,
|
||||
end: this.bounds.end
|
||||
});
|
||||
},
|
||||
resize() {
|
||||
if (this.$refs.axisHolder.clientWidth !== this.width) {
|
||||
this.width = this.$refs.axisHolder.clientWidth;
|
||||
this.setScale();
|
||||
}
|
||||
bounds: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -259,6 +163,103 @@ export default {
|
||||
setInterval(this.resize, RESIZE_POLL_INTERVAL);
|
||||
},
|
||||
destroyed() {
|
||||
},
|
||||
methods: {
|
||||
setScale() {
|
||||
let timeSystem = this.openmct.time.timeSystem();
|
||||
let bounds = this.bounds;
|
||||
|
||||
if (timeSystem.isUTCBased) {
|
||||
this.xScale.domain([new Date(bounds.start), new Date(bounds.end)]);
|
||||
} else {
|
||||
this.xScale.domain([bounds.start, bounds.end]);
|
||||
}
|
||||
|
||||
this.xAxis.scale(this.xScale);
|
||||
|
||||
this.xScale.range([PADDING, this.width - PADDING * 2]);
|
||||
this.axisElement.call(this.xAxis);
|
||||
|
||||
if (this.width > 1800) {
|
||||
this.xAxis.ticks(this.width / PIXELS_PER_TICK_WIDE);
|
||||
} else {
|
||||
this.xAxis.ticks(this.width / PIXELS_PER_TICK);
|
||||
}
|
||||
|
||||
this.msPerPixel = (bounds.end - bounds.start) / this.width;
|
||||
},
|
||||
setViewFromTimeSystem(timeSystem) {
|
||||
//The D3 scale used depends on the type of time system as d3
|
||||
// supports UTC out of the box.
|
||||
if (timeSystem.isUTCBased) {
|
||||
this.xScale = d3Scale.scaleUtc();
|
||||
} else {
|
||||
this.xScale = d3Scale.scaleLinear();
|
||||
}
|
||||
|
||||
this.xAxis.scale(this.xScale);
|
||||
this.xAxis.tickFormat(utcMultiTimeFormat);
|
||||
this.axisElement.call(this.xAxis);
|
||||
this.setScale();
|
||||
},
|
||||
getActiveFormatter() {
|
||||
let timeSystem = this.openmct.time.timeSystem();
|
||||
let isFixed = this.openmct.time.clock() === undefined;
|
||||
|
||||
if (isFixed) {
|
||||
return this.getFormatter(timeSystem.timeFormat);
|
||||
} else {
|
||||
return this.getFormatter(timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
|
||||
}
|
||||
},
|
||||
getFormatter(key) {
|
||||
return this.openmct.telemetry.getValueFormatter({
|
||||
format: key
|
||||
}).formatter;
|
||||
},
|
||||
dragStart($event) {
|
||||
let isFixed = this.openmct.time.clock() === undefined;
|
||||
if (isFixed) {
|
||||
this.dragStartX = $event.clientX;
|
||||
|
||||
document.addEventListener('mousemove', this.drag);
|
||||
document.addEventListener('mouseup', this.dragEnd, {
|
||||
once: true
|
||||
});
|
||||
}
|
||||
},
|
||||
drag($event) {
|
||||
if (!this.dragging) {
|
||||
this.dragging = true;
|
||||
requestAnimationFrame(()=>{
|
||||
let deltaX = $event.clientX - this.dragStartX;
|
||||
let percX = deltaX / this.width;
|
||||
let bounds = this.openmct.time.bounds();
|
||||
let deltaTime = bounds.end - bounds.start;
|
||||
let newStart = bounds.start - percX * deltaTime;
|
||||
this.$emit('panAxis',{
|
||||
start: newStart,
|
||||
end: newStart + deltaTime
|
||||
});
|
||||
this.dragging = false;
|
||||
})
|
||||
} else {
|
||||
console.log('Rejected drag due to RAF cap');
|
||||
}
|
||||
},
|
||||
dragEnd() {
|
||||
document.removeEventListener('mousemove', this.drag);
|
||||
this.openmct.time.bounds({
|
||||
start: this.bounds.start,
|
||||
end: this.bounds.end
|
||||
});
|
||||
},
|
||||
resize() {
|
||||
if (this.$refs.axisHolder.clientWidth !== this.width) {
|
||||
this.width = this.$refs.axisHolder.clientWidth;
|
||||
this.setScale();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,33 +20,43 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up">
|
||||
<button class="c-button--menu c-mode-button"
|
||||
@click.prevent="toggle">
|
||||
<span class="c-button__label">{{selectedMode.name}}</span>
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up">
|
||||
<button
|
||||
class="c-button--menu c-mode-button"
|
||||
@click.prevent="toggle"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedMode.name }}</span>
|
||||
</button>
|
||||
<div class="c-menu c-super-menu c-conductor__mode-menu"
|
||||
v-if="open">
|
||||
<div
|
||||
v-if="open"
|
||||
class="c-menu c-super-menu c-conductor__mode-menu"
|
||||
>
|
||||
<div class="c-super-menu__menu">
|
||||
<ul>
|
||||
<li v-for="mode in modes"
|
||||
<li
|
||||
v-for="mode in modes"
|
||||
:key="mode.key"
|
||||
class="menu-item-a"
|
||||
:class="mode.cssClass"
|
||||
@click="setOption(mode)"
|
||||
@mouseover="hoveredMode = mode"
|
||||
@mouseleave="hoveredMode = {}"
|
||||
class="menu-item-a"
|
||||
:class="mode.cssClass">
|
||||
{{mode.name}}
|
||||
>
|
||||
{{ mode.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="c-super-menu__item-description">
|
||||
<div :class="['l-item-description__icon', 'bg-' + hoveredMode.cssClass]"></div>
|
||||
<div class="l-item-description__name">{{hoveredMode.name}}</div>
|
||||
<div class="l-item-description__description">{{hoveredMode.description}}</div>
|
||||
<div class="l-item-description__name">
|
||||
{{ hoveredMode.name }}
|
||||
</div>
|
||||
<div class="l-item-description__description">
|
||||
{{ hoveredMode.description }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -87,6 +97,14 @@ export default {
|
||||
hoveredMode: {}
|
||||
};
|
||||
},
|
||||
mounted: function () {
|
||||
this.loadClocksFromConfiguration();
|
||||
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.time.off('clock', this.setViewFromClock);
|
||||
},
|
||||
methods: {
|
||||
loadClocksFromConfiguration() {
|
||||
let clocks = this.configuration.menuOptions
|
||||
@ -180,14 +198,6 @@ export default {
|
||||
setViewFromClock(clock) {
|
||||
this.selectedMode = this.getModeOptionForClock(clock);
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.loadClocksFromConfiguration();
|
||||
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.time.off('clock', this.setViewFromClock);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,10 +20,10 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-clock-symbol">
|
||||
<div class="c-clock-symbol">
|
||||
<div class="hand-little"></div>
|
||||
<div class="hand-big"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -20,24 +20,33 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up"
|
||||
v-if="selectedTimeSystem.name">
|
||||
<button class="c-button--menu c-time-system-button"
|
||||
<div
|
||||
v-if="selectedTimeSystem.name"
|
||||
class="c-ctrl-wrapper c-ctrl-wrapper--menus-up"
|
||||
>
|
||||
<button
|
||||
class="c-button--menu c-time-system-button"
|
||||
:class="selectedTimeSystem.cssClass"
|
||||
@click.prevent="toggle">
|
||||
<span class="c-button__label">{{selectedTimeSystem.name}}</span>
|
||||
@click.prevent="toggle"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedTimeSystem.name }}</span>
|
||||
</button>
|
||||
<div class="c-menu" v-if="open">
|
||||
<div
|
||||
v-if="open"
|
||||
class="c-menu"
|
||||
>
|
||||
<ul>
|
||||
<li @click="setTimeSystemFromView(timeSystem)"
|
||||
<li
|
||||
v-for="timeSystem in timeSystems"
|
||||
:key="timeSystem.key"
|
||||
:class="timeSystem.cssClass">
|
||||
{{timeSystem.name}}
|
||||
:class="timeSystem.cssClass"
|
||||
@click="setTimeSystemFromView(timeSystem)"
|
||||
>
|
||||
{{ timeSystem.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -54,6 +63,14 @@ export default {
|
||||
timeSystems: this.getValidTimesystemsForClock(activeClock)
|
||||
};
|
||||
},
|
||||
mounted: function () {
|
||||
this.openmct.time.on('timeSystem', this.setViewFromTimeSystem);
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.time.off('timeSystem', this.setViewFromTimeSystem);
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
},
|
||||
methods: {
|
||||
getValidTimesystemsForClock(clock) {
|
||||
return this.configuration.menuOptions
|
||||
@ -111,14 +128,6 @@ export default {
|
||||
let activeClock = this.openmct.time.clock();
|
||||
this.timeSystems = this.getValidTimesystemsForClock(activeClock);
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.openmct.time.on('timeSystem', this.setViewFromTimeSystem);
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.time.off('timeSystem', this.setViewFromTimeSystem);
|
||||
this.openmct.time.on('clock', this.setViewFromClock);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,41 +20,68 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up c-datetime-picker__wrapper" ref="calendarHolder">
|
||||
<a class="c-icon-button icon-calendar"
|
||||
@click="toggle"></a>
|
||||
<div class="c-menu c-menu--mobile-modal c-datetime-picker"
|
||||
v-if="open">
|
||||
<div
|
||||
ref="calendarHolder"
|
||||
class="c-ctrl-wrapper c-ctrl-wrapper--menus-up c-datetime-picker__wrapper"
|
||||
>
|
||||
<a
|
||||
class="c-icon-button icon-calendar"
|
||||
@click="toggle"
|
||||
></a>
|
||||
<div
|
||||
v-if="open"
|
||||
class="c-menu c-menu--mobile-modal c-datetime-picker"
|
||||
>
|
||||
<div class="c-datetime-picker__close-button">
|
||||
<button class="c-click-icon icon-x-in-circle"
|
||||
@click="toggle"></button>
|
||||
<button
|
||||
class="c-click-icon icon-x-in-circle"
|
||||
@click="toggle"
|
||||
></button>
|
||||
</div>
|
||||
<div class="c-datetime-picker__pager c-pager l-month-year-pager">
|
||||
<div class="c-pager__prev c-icon-button icon-arrow-left"
|
||||
@click.stop="changeMonth(-1)"></div>
|
||||
<div class="c-pager__month-year">{{model.month}} {{model.year}}</div>
|
||||
<div class="c-pager__next c-icon-button icon-arrow-right"
|
||||
@click.stop="changeMonth(1)"></div>
|
||||
<div
|
||||
class="c-pager__prev c-icon-button icon-arrow-left"
|
||||
@click.stop="changeMonth(-1)"
|
||||
></div>
|
||||
<div class="c-pager__month-year">
|
||||
{{ model.month }} {{ model.year }}
|
||||
</div>
|
||||
<div
|
||||
class="c-pager__next c-icon-button icon-arrow-right"
|
||||
@click.stop="changeMonth(1)"
|
||||
></div>
|
||||
</div>
|
||||
<div class="c-datetime-picker__calendar c-calendar">
|
||||
<ul class="c-calendar__row--header l-cal-row">
|
||||
<li v-for="day in ['Su','Mo','Tu','We','Th','Fr','Sa']"
|
||||
:key="day">{{day}}</li>
|
||||
<li
|
||||
v-for="day in ['Su','Mo','Tu','We','Th','Fr','Sa']"
|
||||
:key="day"
|
||||
>
|
||||
{{ day }}
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="c-calendar__row--body"
|
||||
v-for="(row, index) in table"
|
||||
:key="index">
|
||||
<li v-for="(cell, index) in row"
|
||||
:key="index"
|
||||
<ul
|
||||
v-for="(row, tableIndex) in table"
|
||||
:key="tableIndex"
|
||||
class="c-calendar__row--body"
|
||||
>
|
||||
<li
|
||||
v-for="(cell, rowIndex) in row"
|
||||
:key="rowIndex"
|
||||
:class="{ 'is-in-month': isInCurrentMonth(cell), selected: isSelected(cell) }"
|
||||
@click="select(cell)"
|
||||
:class="{ 'is-in-month': isInCurrentMonth(cell), selected: isSelected(cell) }">
|
||||
<div class="c-calendar__day--prime">{{cell.day}}</div>
|
||||
<div class="c-calendar__day--sub">{{cell.dayOfYear}}</div>
|
||||
>
|
||||
<div class="c-calendar__day--prime">
|
||||
{{ cell.day }}
|
||||
</div>
|
||||
<div class="c-calendar__day--sub">
|
||||
{{ cell.dayOfYear }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -166,7 +193,7 @@ const TIME_NAMES = {
|
||||
'hours': "Hour",
|
||||
'minutes': "Minute",
|
||||
'seconds': "Second"
|
||||
};
|
||||
};
|
||||
const MONTHS = moment.months();
|
||||
const TIME_OPTIONS = (function makeRanges() {
|
||||
let arr = [];
|
||||
@ -184,8 +211,14 @@ export default {
|
||||
inject: ['openmct'],
|
||||
mixins: [toggleMixin],
|
||||
props: {
|
||||
defaultDateTime: String,
|
||||
formatter: Object
|
||||
defaultDateTime: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
formatter: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
@ -196,13 +229,17 @@ export default {
|
||||
},
|
||||
model: {
|
||||
year: undefined,
|
||||
month: undefined,
|
||||
month: undefined
|
||||
},
|
||||
table: undefined,
|
||||
date: undefined,
|
||||
time: undefined
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.updateFromModel(this.defaultDateTime);
|
||||
this.updateViewForMonth();
|
||||
},
|
||||
methods: {
|
||||
generateTable() {
|
||||
let m = moment.utc({ year: this.picker.year, month: this.picker.month }).day(0),
|
||||
@ -233,9 +270,7 @@ export default {
|
||||
},
|
||||
|
||||
updateFromModel(defaultDateTime) {
|
||||
let m;
|
||||
|
||||
m = moment.utc(defaultDateTime);
|
||||
let m = moment.utc(defaultDateTime);
|
||||
|
||||
this.date = {
|
||||
year: m.year(),
|
||||
@ -314,11 +349,7 @@ export default {
|
||||
|
||||
optionsFor(key) {
|
||||
return TIME_OPTIONS[key];
|
||||
},
|
||||
},
|
||||
mounted: function () {
|
||||
this.updateFromModel(this.defaultDateTime);
|
||||
this.updateViewForMonth();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -37,6 +37,7 @@ export default function WebPage(openmct) {
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
el: element,
|
||||
components: {
|
||||
WebPageComponent: WebPageComponent
|
||||
},
|
||||
@ -44,7 +45,6 @@ export default function WebPage(openmct) {
|
||||
openmct,
|
||||
domainObject
|
||||
},
|
||||
el: element,
|
||||
template: '<web-page-component></web-page-component>'
|
||||
});
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="l-iframe abs">
|
||||
<div class="l-iframe abs">
|
||||
<iframe :src="currentDomainObject.url"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -20,34 +20,40 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="c-so-view has-local-controls"
|
||||
<div
|
||||
class="c-so-view has-local-controls"
|
||||
:class="{
|
||||
'c-so-view--no-frame': !hasFrame,
|
||||
'has-complex-content': complexContent
|
||||
}">
|
||||
}"
|
||||
>
|
||||
<div class="c-so-view__header">
|
||||
<div class="c-so-view__header__icon" :class="cssClass"></div>
|
||||
<div
|
||||
class="c-so-view__header__icon"
|
||||
:class="cssClass"
|
||||
></div>
|
||||
<div class="c-so-view__header__name">
|
||||
{{ domainObject && domainObject.name }}
|
||||
</div>
|
||||
<context-menu-drop-down
|
||||
:object-path="objectPath">
|
||||
</context-menu-drop-down>
|
||||
:object-path="objectPath"
|
||||
/>
|
||||
</div>
|
||||
<div class="c-so-view__local-controls c-so-view__view-large h-local-controls c-local-controls--show-on-hover">
|
||||
<button class="c-button icon-expand"
|
||||
<button
|
||||
class="c-button icon-expand"
|
||||
title="View Large"
|
||||
@click="expand">
|
||||
</button>
|
||||
@click="expand"
|
||||
></button>
|
||||
</div>
|
||||
<object-view
|
||||
class="c-so-view__object-view"
|
||||
ref="objectView"
|
||||
class="c-so-view__object-view"
|
||||
:object="domainObject"
|
||||
:show-edit-view="showEditView"
|
||||
:object-path="objectPath">
|
||||
</object-view>
|
||||
</div>
|
||||
:object-path="objectPath"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -131,30 +137,46 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ObjectView from './ObjectView.vue'
|
||||
import ContextMenuDropDown from './contextMenuDropDown.vue';
|
||||
import ObjectView from './ObjectView.vue'
|
||||
import ContextMenuDropDown from './contextMenuDropDown.vue';
|
||||
|
||||
const SIMPLE_CONTENT_TYPES = [
|
||||
const SIMPLE_CONTENT_TYPES = [
|
||||
'clock',
|
||||
'timer',
|
||||
'summary-widget',
|
||||
'hyperlink'
|
||||
];
|
||||
];
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
ObjectView,
|
||||
ContextMenuDropDown
|
||||
},
|
||||
props: {
|
||||
domainObject: Object,
|
||||
objectPath: Array,
|
||||
domainObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
hasFrame: Boolean,
|
||||
showEditView: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
default: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ObjectView,
|
||||
ContextMenuDropDown,
|
||||
data() {
|
||||
let objectType = this.openmct.types.get(this.domainObject.type),
|
||||
cssClass = objectType && objectType.definition ? objectType.definition.cssClass : 'icon-object-unknown',
|
||||
complexContent = !SIMPLE_CONTENT_TYPES.includes(this.domainObject.type);
|
||||
|
||||
return {
|
||||
cssClass,
|
||||
complexContent
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
expand() {
|
||||
@ -173,16 +195,6 @@
|
||||
getSelectionContext() {
|
||||
return this.$refs.objectView.getSelectionContext();
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let objectType = this.openmct.types.get(this.domainObject.type),
|
||||
cssClass = objectType && objectType.definition ? objectType.definition.cssClass : 'icon-object-unknown',
|
||||
complexContent = !SIMPLE_CONTENT_TYPES.includes(this.domainObject.type);
|
||||
|
||||
return {
|
||||
cssClass,
|
||||
complexContent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,11 +1,15 @@
|
||||
<template>
|
||||
<a class="c-tree__item__label c-object-label"
|
||||
<a
|
||||
class="c-tree__item__label c-object-label"
|
||||
draggable="true"
|
||||
:href="objectLink"
|
||||
@dragstart="dragStart"
|
||||
@click="navigateOrPreview"
|
||||
:href="objectLink">
|
||||
<div class="c-tree__item__type-icon c-object-label__type-icon"
|
||||
:class="typeClass"></div>
|
||||
>
|
||||
<div
|
||||
class="c-tree__item__type-icon c-object-label__type-icon"
|
||||
:class="typeClass"
|
||||
></div>
|
||||
<div class="c-tree__item__name c-object-label__name">{{ observedObject.name }}</div>
|
||||
</a>
|
||||
</template>
|
||||
@ -53,29 +57,24 @@ export default {
|
||||
mixins: [ObjectLink, ContextMenuGesture],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
domainObject: Object,
|
||||
domainObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
required: true
|
||||
},
|
||||
navigateToPath: String
|
||||
navigateToPath: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
observedObject: this.domainObject
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.observedObject) {
|
||||
let removeListener = this.openmct.objects.observe(this.observedObject, '*', (newObject) => {
|
||||
this.observedObject = newObject;
|
||||
});
|
||||
this.$once('hook:destroyed', removeListener);
|
||||
}
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
},
|
||||
computed: {
|
||||
typeClass() {
|
||||
let type = this.openmct.types.get(this.observedObject.type);
|
||||
@ -85,15 +84,24 @@ export default {
|
||||
return type.definition.cssClass;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.observedObject) {
|
||||
let removeListener = this.openmct.objects.observe(this.observedObject, '*', (newObject) => {
|
||||
this.observedObject = newObject;
|
||||
});
|
||||
this.$once('hook:destroyed', removeListener);
|
||||
}
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
},
|
||||
methods: {
|
||||
navigateOrPreview(event) {
|
||||
if (this.openmct.editor.isEditing()){
|
||||
if (this.openmct.editor.isEditing()) {
|
||||
event.preventDefault();
|
||||
this.preview();
|
||||
}
|
||||
},
|
||||
preview() {
|
||||
if (this.previewAction.appliesTo(this.objectPath)){
|
||||
if (this.previewAction.appliesTo(this.objectPath)) {
|
||||
this.previewAction.invoke(this.objectPath);
|
||||
}
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -7,10 +8,23 @@ import _ from "lodash"
|
||||
export default {
|
||||
inject: ["openmct"],
|
||||
props: {
|
||||
view: String,
|
||||
object: Object,
|
||||
object: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
showEditView: Boolean,
|
||||
objectPath: Array
|
||||
objectPath: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
object(newObject, oldObject) {
|
||||
this.currentObject = newObject;
|
||||
this.debounceUpdateView();
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.clear();
|
||||
@ -18,16 +32,6 @@ export default {
|
||||
this.releaseEditModeHandler();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view(newView, oldView) {
|
||||
this.viewKey = newView;
|
||||
this.debounceUpdateView();
|
||||
},
|
||||
object(newObject, oldObject) {
|
||||
this.currentObject = newObject;
|
||||
this.debounceUpdateView();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.debounceUpdateView = _.debounce(this.updateView, 10);
|
||||
},
|
||||
@ -114,7 +118,7 @@ export default {
|
||||
this.currentView.show(this.viewContainer, this.openmct.editor.isEditing());
|
||||
|
||||
if (immediatelySelect) {
|
||||
this.removeSelectable = openmct.selection.selectable(
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.getSelectionContext(), true);
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,20 @@
|
||||
<template>
|
||||
<div class="c-progress-bar">
|
||||
<div class="c-progress-bar">
|
||||
<div class="c-progress-bar__holder">
|
||||
<div class="c-progress-bar__bar"
|
||||
<div
|
||||
class="c-progress-bar__bar"
|
||||
:class="{'--indeterminate': model.progressPerc === 'unknown'}"
|
||||
:style="`width: ${model.progressPerc}%;`">
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-progress-bar__text"
|
||||
v-if="model.progressText !== undefined">
|
||||
<span v-if="model.progressPerc > 0">{{model.progressPerc}}% complete.</span>
|
||||
{{model.progressText}}
|
||||
:style="styleBarWidth"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
v-if="model.progressText !== undefined"
|
||||
class="c-progress-bar__text"
|
||||
>
|
||||
<span v-if="model.progressPerc > 0">{{ model.progressPerc }}% complete.</span>
|
||||
{{ model.progressText }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -64,6 +67,16 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props:['model']
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styleBarWidth() {
|
||||
return `width: ${this.model.progressPerc}%;`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<label class="c-toggle-switch">
|
||||
<input type="checkbox"
|
||||
<label class="c-toggle-switch">
|
||||
<input
|
||||
:id="id"
|
||||
type="checkbox"
|
||||
:checked="checked"
|
||||
@change="onUserSelect($event)"/>
|
||||
@change="onUserSelect($event)"
|
||||
>
|
||||
<span class="c-toggle-switch__slider"></span>
|
||||
</label>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -63,10 +65,13 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
id: String,
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
checked: Boolean
|
||||
},
|
||||
methods: {
|
||||
@ -74,5 +79,5 @@
|
||||
this.$emit('change', event.target.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,14 +1,21 @@
|
||||
<template>
|
||||
<div class="c-so-view__context-actions c-disclosure-button"
|
||||
@click="showContextMenu"></div>
|
||||
<div
|
||||
class="c-so-view__context-actions c-disclosure-button"
|
||||
@click="showContextMenu"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import contextMenu from '../mixins/context-menu-gesture'
|
||||
|
||||
export default {
|
||||
props: ['objectPath'],
|
||||
mixins: [contextMenu],
|
||||
props: {
|
||||
objectPath: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1,15 +1,21 @@
|
||||
<template>
|
||||
<div class="c-search"
|
||||
:class="{ 'is-active': active === true }">
|
||||
<input class="c-search__input"
|
||||
<div
|
||||
class="c-search"
|
||||
:class="{ 'is-active': active === true }"
|
||||
>
|
||||
<input
|
||||
class="c-search__input"
|
||||
tabindex="10000"
|
||||
type="search"
|
||||
v-bind="$attrs"
|
||||
v-bind:value="value"
|
||||
v-on="inputListeners"/>
|
||||
<a class="c-search__clear-input icon-x-in-circle"
|
||||
v-on:click="clearInput"></a>
|
||||
</div>
|
||||
:value="value"
|
||||
v-on="inputListeners"
|
||||
>
|
||||
<a
|
||||
class="c-search__clear-input icon-x-in-circle"
|
||||
@click="clearInput"
|
||||
></a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -44,11 +50,19 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/* Emits input and clear events */
|
||||
export default {
|
||||
/* Emits input and clear events */
|
||||
export default {
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
value: String
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
active: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
inputListeners: function () {
|
||||
@ -64,11 +78,6 @@
|
||||
)
|
||||
}
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
active: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clearInput() {
|
||||
// Clear the user's input and set 'active' to false
|
||||
@ -76,5 +85,5 @@
|
||||
this.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,14 +1,16 @@
|
||||
<template>
|
||||
<span class="c-disclosure-triangle"
|
||||
<span
|
||||
class="c-disclosure-triangle"
|
||||
:class="{
|
||||
'c-disclosure-triangle--expanded' : value,
|
||||
'is-enabled' : enabled
|
||||
}"
|
||||
@click="$emit('input', !value)"></span>
|
||||
@click="$emit('input', !value)"
|
||||
></span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
@ -21,5 +23,5 @@
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,29 +1,49 @@
|
||||
<template>
|
||||
<div class="c-elements-pool">
|
||||
<Search class="c-elements-pool__search"
|
||||
<Search
|
||||
class="c-elements-pool__search"
|
||||
:value="currentSearch"
|
||||
@input="applySearch"
|
||||
@clear="applySearch">
|
||||
</Search>
|
||||
<div class="c-elements-pool__elements"
|
||||
:class="{'is-dragging': isDragging}">
|
||||
<ul class="c-tree c-elements-pool__tree" id="inspector-elements-tree"
|
||||
v-if="elements.length > 0">
|
||||
<li :key="element.identifier.key" v-for="(element, index) in elements"
|
||||
@clear="applySearch"
|
||||
/>
|
||||
<div
|
||||
class="c-elements-pool__elements"
|
||||
:class="{'is-dragging': isDragging}"
|
||||
>
|
||||
<ul
|
||||
v-if="elements.length > 0"
|
||||
id="inspector-elements-tree"
|
||||
class="c-tree c-elements-pool__tree"
|
||||
>
|
||||
<li
|
||||
v-for="(element, index) in elements"
|
||||
:key="element.identifier.key"
|
||||
@drop="moveTo(index)"
|
||||
@dragover="allowDrop">
|
||||
<div class="c-tree__item c-elements-pool__item"
|
||||
@dragover="allowDrop"
|
||||
>
|
||||
<div
|
||||
class="c-tree__item c-elements-pool__item"
|
||||
draggable="true"
|
||||
@dragstart="moveFrom(index)">
|
||||
<span class="c-elements-pool__grippy"
|
||||
v-if="elements.length > 1 && isEditing">
|
||||
</span>
|
||||
<object-label :domainObject="element" :objectPath="[element, parentObject]"></object-label>
|
||||
@dragstart="moveFrom(index)"
|
||||
>
|
||||
<span
|
||||
v-if="elements.length > 1 && isEditing"
|
||||
class="c-elements-pool__grippy"
|
||||
></span>
|
||||
<object-label
|
||||
:domain-object="element"
|
||||
:object-path="[element, parentObject]"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li class="js-last-place" @drop="moveToIndex(elements.length)"></li>
|
||||
<li
|
||||
class="js-last-place"
|
||||
@drop="moveToIndex(elements.length)"
|
||||
></li>
|
||||
</ul>
|
||||
<div v-if="elements.length === 0">No contained elements</div>
|
||||
<div v-if="elements.length === 0">
|
||||
No contained elements
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -89,12 +109,23 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
let selection = this.openmct.selection.get();
|
||||
if (selection && selection.length > 0){
|
||||
if (selection && selection.length > 0) {
|
||||
this.showSelection(selection);
|
||||
}
|
||||
this.openmct.selection.on('change', this.showSelection);
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.editor.off('isEditing', this.setEditState);
|
||||
this.openmct.selection.off('change', this.showSelection);
|
||||
|
||||
if (this.mutationUnobserver) {
|
||||
this.mutationUnobserver();
|
||||
}
|
||||
if (this.compositionUnlistener) {
|
||||
this.compositionUnlistener();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setEditState(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
@ -168,7 +199,7 @@ export default {
|
||||
moveTo(moveToIndex) {
|
||||
this.composition.reorder(this.moveFromIndex, moveToIndex);
|
||||
},
|
||||
moveFrom(index){
|
||||
moveFrom(index) {
|
||||
this.isDragging = true;
|
||||
this.moveFromIndex = index;
|
||||
document.addEventListener('dragend', this.hideDragStyling);
|
||||
@ -177,17 +208,6 @@ export default {
|
||||
this.isDragging = false;
|
||||
document.removeEventListener('dragend', this.hideDragStyling);
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.editor.off('isEditing', this.setEditState);
|
||||
this.openmct.selection.off('change', this.showSelection);
|
||||
|
||||
if (this.mutationUnobserver) {
|
||||
this.mutationUnobserver();
|
||||
}
|
||||
if (this.compositionUnlistener) {
|
||||
this.compositionUnlistener();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,17 +1,22 @@
|
||||
<template>
|
||||
<multipane class="c-inspector"
|
||||
type="vertical">
|
||||
<multipane
|
||||
class="c-inspector"
|
||||
type="vertical"
|
||||
>
|
||||
<pane class="c-inspector__properties">
|
||||
<properties></properties>
|
||||
<location></location>
|
||||
<inspector-views></inspector-views>
|
||||
<properties />
|
||||
<location />
|
||||
<inspector-views />
|
||||
</pane>
|
||||
<pane class="c-inspector__elements"
|
||||
<pane
|
||||
v-if="isEditing && hasComposition"
|
||||
class="c-inspector__elements"
|
||||
handle="before"
|
||||
label="Elements" v-if="isEditing && hasComposition">
|
||||
<elements></elements>
|
||||
label="Elements"
|
||||
>
|
||||
<elements />
|
||||
</pane>
|
||||
</multipane>
|
||||
</multipane>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -174,18 +179,15 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import multipane from '../layout/multipane.vue';
|
||||
import pane from '../layout/pane.vue';
|
||||
import Elements from './Elements.vue';
|
||||
import Location from './Location.vue';
|
||||
import Properties from './Properties.vue';
|
||||
import InspectorViews from './InspectorViews.vue';
|
||||
import multipane from '../layout/multipane.vue';
|
||||
import pane from '../layout/pane.vue';
|
||||
import Elements from './Elements.vue';
|
||||
import Location from './Location.vue';
|
||||
import Properties from './Properties.vue';
|
||||
import InspectorViews from './InspectorViews.vue';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
'isEditing': Boolean
|
||||
},
|
||||
components: {
|
||||
multipane,
|
||||
pane,
|
||||
@ -194,11 +196,21 @@
|
||||
Location,
|
||||
InspectorViews
|
||||
},
|
||||
props: {
|
||||
'isEditing': Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasComposition: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.refreshComposition);
|
||||
this.refreshComposition(this.openmct.selection.get());
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.selection.off('change', this.refreshComposition);
|
||||
},
|
||||
methods: {
|
||||
refreshComposition(selection) {
|
||||
if (selection.length > 0 && selection[0].length > 0) {
|
||||
@ -207,13 +219,6 @@
|
||||
this.hasComposition = !!(parentObject && this.openmct.composition.get(parentObject));
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.refreshComposition);
|
||||
this.refreshComposition(this.openmct.selection.get());
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.selection.off('change', this.refreshComposition);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,16 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
</div>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
return {
|
||||
selection: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.updateSelection);
|
||||
this.updateSelection(this.openmct.selection.get());
|
||||
@ -18,11 +20,6 @@ import _ from 'lodash';
|
||||
destroyed() {
|
||||
this.openmct.selection.off('change', this.updateSelection);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selection: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateSelection(selection) {
|
||||
this.selection = selection;
|
||||
@ -42,5 +39,5 @@ import _ from 'lodash';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,21 +1,39 @@
|
||||
<template>
|
||||
<div class="c-properties c-properties--location">
|
||||
<div class="c-properties__header" title="The location of this linked object.">Original Location</div>
|
||||
<ul class="c-properties__section" v-if="!multiSelect">
|
||||
<li class="c-properties__row" v-if="originalPath.length">
|
||||
<div
|
||||
class="c-properties__header"
|
||||
title="The location of this linked object."
|
||||
>
|
||||
Original Location
|
||||
</div>
|
||||
<ul
|
||||
v-if="!multiSelect"
|
||||
class="c-properties__section"
|
||||
>
|
||||
<li
|
||||
v-if="originalPath.length"
|
||||
class="c-properties__row"
|
||||
>
|
||||
<ul class="c-properties__value c-location">
|
||||
<li v-for="pathObject in orderedOriginalPath"
|
||||
<li
|
||||
v-for="pathObject in orderedOriginalPath"
|
||||
:key="pathObject.key"
|
||||
class="c-location__item"
|
||||
:key="pathObject.key">
|
||||
>
|
||||
<object-label
|
||||
:domainObject="pathObject.domainObject"
|
||||
:objectPath="pathObject.objectPath">
|
||||
</object-label>
|
||||
:domain-object="pathObject.domainObject"
|
||||
:object-path="pathObject.objectPath"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="c-properties__row--span-all" v-if="multiSelect">No location to display for multiple items</div>
|
||||
<div
|
||||
v-if="multiSelect"
|
||||
class="c-properties__row--span-all"
|
||||
>
|
||||
No location to display for multiple items
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -78,6 +96,11 @@ export default {
|
||||
keyString: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
orderedOriginalPath() {
|
||||
return this.originalPath.slice().reverse();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.updateSelection);
|
||||
this.updateSelection(this.openmct.selection.get());
|
||||
@ -139,11 +162,6 @@ export default {
|
||||
.then(this.setOriginalPath);
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
orderedOriginalPath() {
|
||||
return this.originalPath.reverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,32 +1,75 @@
|
||||
<template>
|
||||
<div class="c-properties c-properties--properties">
|
||||
<div class="c-properties__header">Properties</div>
|
||||
<ul class="c-properties__section" v-if="!multiSelect && !singleSelectNonObject">
|
||||
<div class="c-properties__header">
|
||||
Properties
|
||||
</div>
|
||||
<ul
|
||||
v-if="!multiSelect && !singleSelectNonObject"
|
||||
class="c-properties__section"
|
||||
>
|
||||
<li class="c-properties__row">
|
||||
<div class="c-properties__label">Title</div>
|
||||
<div class="c-properties__value">{{ item.name }}</div>
|
||||
<div class="c-properties__label">
|
||||
Title
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</li>
|
||||
<li class="c-properties__row">
|
||||
<div class="c-properties__label">Type</div>
|
||||
<div class="c-properties__value">{{ typeName }}</div>
|
||||
<div class="c-properties__label">
|
||||
Type
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
{{ typeName }}
|
||||
</div>
|
||||
</li>
|
||||
<li class="c-properties__row" v-if="item.created">
|
||||
<div class="c-properties__label">Created</div>
|
||||
<div class="c-properties__value c-ne__text">{{ formatTime(item.created) }}</div>
|
||||
<li
|
||||
v-if="item.created"
|
||||
class="c-properties__row"
|
||||
>
|
||||
<div class="c-properties__label">
|
||||
Created
|
||||
</div>
|
||||
<div class="c-properties__value c-ne__text">
|
||||
{{ formatTime(item.created) }}
|
||||
</div>
|
||||
</li>
|
||||
<li class="c-properties__row" v-if="item.modified">
|
||||
<div class="c-properties__label">Modified</div>
|
||||
<div class="c-properties__value c-ne__text">{{ formatTime(item.modified) }}</div>
|
||||
<li
|
||||
v-if="item.modified"
|
||||
class="c-properties__row"
|
||||
>
|
||||
<div class="c-properties__label">
|
||||
Modified
|
||||
</div>
|
||||
<div class="c-properties__value c-ne__text">
|
||||
{{ formatTime(item.modified) }}
|
||||
</div>
|
||||
</li>
|
||||
<li class="c-properties__row"
|
||||
<li
|
||||
v-for="prop in typeProperties"
|
||||
:key="prop.name">
|
||||
<div class="c-properties__label">{{ prop.name }}</div>
|
||||
<div class="c-properties__value">{{ prop.value }}</div>
|
||||
:key="prop.name"
|
||||
class="c-properties__row"
|
||||
>
|
||||
<div class="c-properties__label">
|
||||
{{ prop.name }}
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
{{ prop.value }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="c-properties__row--span-all" v-if="multiSelect">No properties to display for multiple items</div>
|
||||
<div class="c-properties__row--span-all" v-if="singleSelectNonObject">No properties to display for this item</div>
|
||||
<div
|
||||
v-if="multiSelect"
|
||||
class="c-properties__row--span-all"
|
||||
>
|
||||
No properties to display for multiple items
|
||||
</div>
|
||||
<div
|
||||
v-if="singleSelectNonObject"
|
||||
class="c-properties__row--span-all"
|
||||
>
|
||||
No properties to display for this item
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -77,8 +120,8 @@ export default {
|
||||
.map((field) => {
|
||||
return {
|
||||
name: field.name,
|
||||
value: field.path.reduce((object, field) => {
|
||||
return object[field];
|
||||
value: field.path.reduce((object, key) => {
|
||||
return object[key];
|
||||
}, this.item)
|
||||
};
|
||||
});
|
||||
|
@ -1,22 +1,34 @@
|
||||
<template>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div class="c-about c-about--splash">
|
||||
<div class="c-about__image c-splash-image"></div>
|
||||
<div class="c-about__text s-text">
|
||||
<div class="c-about__text__element" v-if="branding.aboutHtml" v-html="branding.aboutHtml"></div>
|
||||
<div
|
||||
v-if="branding.aboutHtml"
|
||||
class="c-about__text__element"
|
||||
v-html="branding.aboutHtml"
|
||||
></div>
|
||||
<div class="c-about__text__element">
|
||||
<h1 class="l-title s-title">Open MCT</h1>
|
||||
<h1 class="l-title s-title">
|
||||
Open MCT
|
||||
</h1>
|
||||
<div class="l-description s-description">
|
||||
<p>Open MCT, Copyright © 2014-2019, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.</p>
|
||||
<p>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 <a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>.</p>
|
||||
<p>
|
||||
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 <a
|
||||
target="_blank"
|
||||
href="http://www.apache.org/licenses/LICENSE-2.0"
|
||||
>http://www.apache.org/licenses/LICENSE-2.0</a>.
|
||||
</p>
|
||||
<p>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.</p>
|
||||
<p>Open MCT includes source code licensed under additional open source licenses. See the Open Source Licenses file included with this distribution or <a @click="showLicenses">click here for third party licensing information</a>.</p>
|
||||
</div>
|
||||
<h2>Version Information</h2>
|
||||
<ul class="t-info l-info s-info">
|
||||
<li>Version: {{buildInfo.version || 'Unknown'}}</li>
|
||||
<li>Build Date: {{buildInfo.buildDate || 'Unknown'}}</li>
|
||||
<li>Revision: {{buildInfo.revision || 'Unknown'}}</li>
|
||||
<li>Branch: {{buildInfo.branch || 'Unknown'}}</li>
|
||||
<li>Version: {{ buildInfo.version || 'Unknown' }}</li>
|
||||
<li>Build Date: {{ buildInfo.buildDate || 'Unknown' }}</li>
|
||||
<li>Revision: {{ buildInfo.revision || 'Unknown' }}</li>
|
||||
<li>Branch: {{ buildInfo.branch || 'Unknown' }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -20,7 +20,11 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="l-shell__app-logo" @click="launchAbout" ref="aboutLogo"></div>
|
||||
<div
|
||||
ref="aboutLogo"
|
||||
class="l-shell__app-logo"
|
||||
@click="launchAbout"
|
||||
></div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.l-shell__app-logo {
|
||||
@ -38,12 +42,12 @@ export default {
|
||||
inject: ['openmct'],
|
||||
mounted() {
|
||||
let branding = this.openmct.branding();
|
||||
if (branding.smallLogoImage){
|
||||
if (branding.smallLogoImage) {
|
||||
this.$refs.aboutLogo.style.backgroundImage = `url('${branding.smallLogoImage}')`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
launchAbout(){
|
||||
launchAbout() {
|
||||
let vm = new Vue({
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
|
@ -1,61 +1,93 @@
|
||||
<template>
|
||||
<div class="l-browse-bar">
|
||||
<div class="l-browse-bar">
|
||||
<div class="l-browse-bar__start">
|
||||
<button v-if="hasParent"
|
||||
<button
|
||||
v-if="hasParent"
|
||||
class="l-browse-bar__nav-to-parent-button c-icon-button c-icon-button--major icon-pointer-left"
|
||||
@click="goToParent"></button>
|
||||
<div class="l-browse-bar__object-name--w"
|
||||
:class="type.cssClass">
|
||||
@click="goToParent"
|
||||
></button>
|
||||
<div
|
||||
class="l-browse-bar__object-name--w"
|
||||
:class="type.cssClass"
|
||||
>
|
||||
<span
|
||||
class="l-browse-bar__object-name c-input-inline"
|
||||
contenteditable
|
||||
@blur="updateName"
|
||||
@keydown.enter.prevent
|
||||
@keyup.enter.prevent="updateNameOnEnterKeyPress"
|
||||
contenteditable>
|
||||
>
|
||||
{{ domainObject.name }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="l-browse-bar__context-actions c-disclosure-button" @click.prevent.stop="showContextMenu"></div>
|
||||
<div
|
||||
class="l-browse-bar__context-actions c-disclosure-button"
|
||||
@click.prevent.stop="showContextMenu"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="l-browse-bar__end">
|
||||
<view-switcher
|
||||
:currentView="currentView"
|
||||
:current-view="currentView"
|
||||
:views="views"
|
||||
@setView="setView">
|
||||
</view-switcher>
|
||||
@setView="setView"
|
||||
/>
|
||||
<!-- Action buttons -->
|
||||
<div class="l-browse-bar__actions">
|
||||
<button v-if="notebookEnabled"
|
||||
<button
|
||||
v-if="notebookEnabled"
|
||||
class="l-browse-bar__actions__notebook-entry c-button icon-notebook"
|
||||
title="New Notebook entry"
|
||||
@click="snapshot()">
|
||||
</button>
|
||||
<button class="l-browse-bar__actions__edit c-button c-button--major icon-pencil" title="Edit" v-if="isViewEditable & !isEditing" @click="edit()"></button>
|
||||
@click="snapshot()"
|
||||
></button>
|
||||
<button
|
||||
v-if="isViewEditable & !isEditing"
|
||||
class="l-browse-bar__actions__edit c-button c-button--major icon-pencil"
|
||||
title="Edit"
|
||||
@click="edit()"
|
||||
></button>
|
||||
|
||||
<div class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
v-if="isEditing">
|
||||
<button class="c-button--menu c-button--major icon-save" title="Save" @click.stop="toggleSaveMenu"></button>
|
||||
<div class="c-menu" v-show="showSaveMenu">
|
||||
<div
|
||||
v-if="isEditing"
|
||||
class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
>
|
||||
<button
|
||||
class="c-button--menu c-button--major icon-save"
|
||||
title="Save"
|
||||
@click.stop="toggleSaveMenu"
|
||||
></button>
|
||||
<div
|
||||
v-show="showSaveMenu"
|
||||
class="c-menu"
|
||||
>
|
||||
<ul>
|
||||
<li @click="saveAndFinishEditing"
|
||||
<li
|
||||
class="icon-save"
|
||||
title="Save and Finish Editing">
|
||||
title="Save and Finish Editing"
|
||||
@click="saveAndFinishEditing"
|
||||
>
|
||||
Save and Finish Editing
|
||||
</li>
|
||||
<li @click="saveAndContinueEditing"
|
||||
<li
|
||||
class="icon-save"
|
||||
title="Save and Continue Editing">
|
||||
title="Save and Continue Editing"
|
||||
@click="saveAndContinueEditing"
|
||||
>
|
||||
Save and Continue Editing
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="l-browse-bar__actions c-button icon-x" title="Cancel Editing" v-if="isEditing" @click="promptUserandCancelEditing()"></button>
|
||||
</div>
|
||||
<button
|
||||
v-if="isEditing"
|
||||
class="l-browse-bar__actions c-button icon-x"
|
||||
title="Cancel Editing"
|
||||
@click="promptUserandCancelEditing()"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -63,103 +95,11 @@ import NotebookSnapshot from '../utils/notebook-snapshot';
|
||||
import ViewSwitcher from './ViewSwitcher.vue';
|
||||
const PLACEHOLDER_OBJECT = {};
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
ViewSwitcher
|
||||
},
|
||||
methods: {
|
||||
toggleSaveMenu() {
|
||||
this.showSaveMenu = !this.showSaveMenu;
|
||||
},
|
||||
closeViewAndSaveMenu() {
|
||||
this.showViewMenu = false;
|
||||
this.showSaveMenu = false;
|
||||
},
|
||||
updateName(event) {
|
||||
if (event.target.innerText !== this.domainObject.name && event.target.innerText.match(/\S/)) {
|
||||
this.openmct.objects.mutate(this.domainObject, 'name', event.target.innerText);
|
||||
} else {
|
||||
event.target.innerText = this.domainObject.name;
|
||||
}
|
||||
},
|
||||
updateNameOnEnterKeyPress (event) {
|
||||
event.target.blur();
|
||||
},
|
||||
setView(view) {
|
||||
this.viewKey = view.key;
|
||||
this.openmct.router.updateParams({
|
||||
view: this.viewKey
|
||||
});
|
||||
},
|
||||
edit() {
|
||||
this.openmct.editor.edit();
|
||||
},
|
||||
promptUserandCancelEditing() {
|
||||
let dialog = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: 'Any unsaved changes will be lost. Are you sure you want to continue?',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Ok',
|
||||
emphasis: true,
|
||||
callback: () => {
|
||||
this.openmct.editor.cancel().then(() => {
|
||||
//refresh object view
|
||||
this.openmct.layout.$refs.browseObject.show(this.domainObject, this.viewKey, true);
|
||||
});
|
||||
dialog.dismiss();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: () => {
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
promptUserbeforeNavigatingAway(event) {
|
||||
if(this.openmct.editor.isEditing()) {
|
||||
event.preventDefault();
|
||||
event.returnValue = '';
|
||||
}
|
||||
},
|
||||
saveAndFinishEditing() {
|
||||
let dialog = this.openmct.overlays.progressDialog({
|
||||
progressPerc: 'unknown',
|
||||
message: 'Do not navigate away from this page or close this browser tab while this message is displayed.',
|
||||
iconClass: 'info',
|
||||
title: 'Saving',
|
||||
});
|
||||
|
||||
return this.openmct.editor.save()
|
||||
.then(()=> {
|
||||
dialog.dismiss();
|
||||
this.openmct.notifications.info('Save successful');
|
||||
}).catch((error) => {
|
||||
dialog.dismiss();
|
||||
this.openmct.notifications.error('Error saving objects');
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
saveAndContinueEditing() {
|
||||
this.saveAndFinishEditing().then(() => {
|
||||
this.openmct.editor.edit();
|
||||
});
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.openmct.router.path, event.clientX, event.clientY);
|
||||
},
|
||||
snapshot() {
|
||||
let element = document.getElementsByClassName("l-shell__main-container")[0];
|
||||
this.notebookSnapshot.capture(this.domainObject, element);
|
||||
},
|
||||
goToParent(){
|
||||
window.location.hash = this.parentUrl;
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
showViewMenu: false,
|
||||
@ -212,6 +152,16 @@ const PLACEHOLDER_OBJECT = {};
|
||||
return false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
domainObject() {
|
||||
if (this.mutationObserver) {
|
||||
this.mutationObserver();
|
||||
}
|
||||
this.mutationObserver = this.openmct.objects.observe(this.domainObject, '*', (domainObject) => {
|
||||
this.domainObject = domainObject;
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
|
||||
if (this.openmct.types.get('notebook')) {
|
||||
@ -226,24 +176,105 @@ const PLACEHOLDER_OBJECT = {};
|
||||
this.isEditing = isEditing;
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
domainObject() {
|
||||
if (this.mutationObserver) {
|
||||
this.mutationObserver();
|
||||
}
|
||||
this.mutationObserver = this.openmct.objects.observe(this.domainObject, '*', (domainObject) => {
|
||||
this.domainObject = domainObject;
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeDestroy: function () {
|
||||
if (this.mutationObserver) {
|
||||
this.mutationObserver();
|
||||
}
|
||||
document.removeEventListener('click', this.closeViewAndSaveMenu);
|
||||
window.removeEventListener('click', this.promptUserbeforeNavigatingAway);
|
||||
},
|
||||
methods: {
|
||||
toggleSaveMenu() {
|
||||
this.showSaveMenu = !this.showSaveMenu;
|
||||
},
|
||||
closeViewAndSaveMenu() {
|
||||
this.showViewMenu = false;
|
||||
this.showSaveMenu = false;
|
||||
},
|
||||
updateName(event) {
|
||||
if (event.target.innerText !== this.domainObject.name && event.target.innerText.match(/\S/)) {
|
||||
this.openmct.objects.mutate(this.domainObject, 'name', event.target.innerText);
|
||||
} else {
|
||||
event.target.innerText = this.domainObject.name;
|
||||
}
|
||||
},
|
||||
updateNameOnEnterKeyPress(event) {
|
||||
event.target.blur();
|
||||
},
|
||||
setView(view) {
|
||||
this.viewKey = view.key;
|
||||
this.openmct.router.updateParams({
|
||||
view: this.viewKey
|
||||
});
|
||||
},
|
||||
edit() {
|
||||
this.openmct.editor.edit();
|
||||
},
|
||||
promptUserandCancelEditing() {
|
||||
let dialog = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: 'Any unsaved changes will be lost. Are you sure you want to continue?',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Ok',
|
||||
emphasis: true,
|
||||
callback: () => {
|
||||
this.openmct.editor.cancel().then(() => {
|
||||
//refresh object view
|
||||
this.openmct.layout.$refs.browseObject.show(this.domainObject, this.viewKey, true);
|
||||
});
|
||||
dialog.dismiss();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: () => {
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
promptUserbeforeNavigatingAway(event) {
|
||||
if(this.openmct.editor.isEditing()) {
|
||||
event.preventDefault();
|
||||
event.returnValue = '';
|
||||
}
|
||||
},
|
||||
saveAndFinishEditing() {
|
||||
let dialog = this.openmct.overlays.progressDialog({
|
||||
progressPerc: 'unknown',
|
||||
message: 'Do not navigate away from this page or close this browser tab while this message is displayed.',
|
||||
iconClass: 'info',
|
||||
title: 'Saving'
|
||||
});
|
||||
|
||||
return this.openmct.editor.save().then(()=> {
|
||||
dialog.dismiss();
|
||||
this.openmct.notifications.info('Save successful');
|
||||
}).catch((error) => {
|
||||
dialog.dismiss();
|
||||
this.openmct.notifications.error('Error saving objects');
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
saveAndContinueEditing() {
|
||||
this.saveAndFinishEditing().then(() => {
|
||||
this.openmct.editor.edit();
|
||||
});
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.openmct.router.path, event.clientX, event.clientY);
|
||||
},
|
||||
snapshot() {
|
||||
let element = document.getElementsByClassName("l-shell__main-container")[0];
|
||||
this.notebookSnapshot.capture(this.domainObject, element);
|
||||
},
|
||||
goToParent() {
|
||||
window.location.hash = this.parentUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -1,30 +1,40 @@
|
||||
<template>
|
||||
<div class="c-create-button--w">
|
||||
<button class="c-create-button c-button--menu c-button--major icon-plus"
|
||||
@click="open">
|
||||
<div class="c-create-button--w">
|
||||
<button
|
||||
class="c-create-button c-button--menu c-button--major icon-plus"
|
||||
@click="open"
|
||||
>
|
||||
<span class="c-button__label">Create</span>
|
||||
</button>
|
||||
<div class="c-create-menu c-super-menu"
|
||||
v-if="opened">
|
||||
<div
|
||||
v-if="opened"
|
||||
class="c-create-menu c-super-menu"
|
||||
>
|
||||
<div class="c-super-menu__menu">
|
||||
<ul>
|
||||
<li v-for="(item, index) in sortedItems"
|
||||
<li
|
||||
v-for="(item, index) in sortedItems"
|
||||
:key="index"
|
||||
:class="item.class"
|
||||
:title="item.title"
|
||||
@mouseover="showItemDescription(item)"
|
||||
@click="create(item)">
|
||||
@click="create(item)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="c-super-menu__item-description">
|
||||
<div :class="['l-item-description__icon', 'bg-' + selectedMenuItem.class]"></div>
|
||||
<div class="l-item-description__name">{{selectedMenuItem.name}}</div>
|
||||
<div class="l-item-description__description">{{selectedMenuItem.title}}</div>
|
||||
<div class="l-item-description__name">
|
||||
{{ selectedMenuItem.name }}
|
||||
</div>
|
||||
<div class="l-item-description__description">
|
||||
{{ selectedMenuItem.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -62,16 +72,51 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import CreateAction from '../../../platform/commonUI/edit/src/creation/CreateAction';
|
||||
import objectUtils from '../../api/objects/object-utils';
|
||||
import CreateAction from '../../../platform/commonUI/edit/src/creation/CreateAction';
|
||||
import objectUtils from '../../api/objects/object-utils';
|
||||
|
||||
function convertToLegacyObject(domainObject) {
|
||||
let keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
let oldModel = objectUtils.toOldFormat(domainObject);
|
||||
return instantiate(oldModel, keyString);
|
||||
}
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data: function () {
|
||||
let items = [];
|
||||
|
||||
this.openmct.types.listKeys().forEach(key => {
|
||||
let menuItem = this.openmct.types.get(key).definition;
|
||||
|
||||
if (menuItem.creatable) {
|
||||
let menuItemTemplate = {
|
||||
key: key,
|
||||
name: menuItem.name,
|
||||
class: menuItem.cssClass,
|
||||
title: menuItem.description
|
||||
};
|
||||
|
||||
items.push(menuItemTemplate);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
items: items,
|
||||
selectedMenuItem: {},
|
||||
opened: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sortedItems() {
|
||||
return this.items.slice().sort((a,b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
} else if (a.name > b.name) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('click', this.close);
|
||||
},
|
||||
methods: {
|
||||
open: function () {
|
||||
if (this.opened) {
|
||||
@ -113,51 +158,11 @@
|
||||
return action.perform();
|
||||
});
|
||||
},
|
||||
convertToLegacy (domainObject) {
|
||||
convertToLegacy(domainObject) {
|
||||
let keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
let oldModel = objectUtils.toOldFormat(domainObject);
|
||||
return this.openmct.$injector.get('instantiate')(oldModel, keyString);
|
||||
}
|
||||
},
|
||||
destroyed () {
|
||||
document.removeEventListener('click', this.close);
|
||||
},
|
||||
data: function() {
|
||||
let items = [];
|
||||
|
||||
this.openmct.types.listKeys().forEach(key => {
|
||||
let menuItem = this.openmct.types.get(key).definition;
|
||||
|
||||
if (menuItem.creatable) {
|
||||
let menuItemTemplate = {
|
||||
key: key,
|
||||
name: menuItem.name,
|
||||
class: menuItem.cssClass,
|
||||
title: menuItem.description
|
||||
};
|
||||
|
||||
items.push(menuItemTemplate);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
items: items,
|
||||
selectedMenuItem: {},
|
||||
opened: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sortedItems () {
|
||||
return this.items.sort((a,b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
} else if (a.name > b.name) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,60 +1,84 @@
|
||||
<template>
|
||||
<div class="l-shell" :class="{
|
||||
<div
|
||||
class="l-shell"
|
||||
:class="{
|
||||
'is-editing': isEditing
|
||||
}">
|
||||
<div class="l-shell__head" :class="{
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="l-shell__head"
|
||||
:class="{
|
||||
'l-shell__head--expanded': headExpanded,
|
||||
'l-shell__head--minify-indicators': !headExpanded
|
||||
}">
|
||||
<CreateButton class="l-shell__create-button"></CreateButton>
|
||||
<indicators class="l-shell__head-section l-shell__indicators">
|
||||
</indicators>
|
||||
<button class="l-shell__head__collapse-button c-button"
|
||||
@click="toggleShellHead"></button>
|
||||
<notification-banner></notification-banner>
|
||||
}"
|
||||
>
|
||||
<CreateButton class="l-shell__create-button" />
|
||||
<indicators class="l-shell__head-section l-shell__indicators" />
|
||||
<button
|
||||
class="l-shell__head__collapse-button c-button"
|
||||
@click="toggleShellHead"
|
||||
></button>
|
||||
<notification-banner />
|
||||
<div class="l-shell__head-section l-shell__controls">
|
||||
<button class="c-icon-button c-icon-button--major icon-new-window" title="Open in a new browser tab"
|
||||
<button
|
||||
class="c-icon-button c-icon-button--major icon-new-window"
|
||||
title="Open in a new browser tab"
|
||||
target="_blank"
|
||||
@click="openInNewTab"
|
||||
target="_blank">
|
||||
</button>
|
||||
<button v-bind:class="['c-icon-button c-icon-button--major', fullScreen ? 'icon-fullscreen-collapse' : 'icon-fullscreen-expand']"
|
||||
v-bind:title="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
|
||||
@click="fullScreenToggle">
|
||||
</button>
|
||||
></button>
|
||||
<button
|
||||
:class="['c-icon-button c-icon-button--major', fullScreen ? 'icon-fullscreen-collapse' : 'icon-fullscreen-expand']"
|
||||
:title="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
|
||||
@click="fullScreenToggle"
|
||||
></button>
|
||||
</div>
|
||||
<app-logo></app-logo>
|
||||
<app-logo />
|
||||
</div>
|
||||
<multipane class="l-shell__main"
|
||||
type="horizontal">
|
||||
<pane class="l-shell__pane-tree"
|
||||
<multipane
|
||||
class="l-shell__main"
|
||||
type="horizontal"
|
||||
>
|
||||
<pane
|
||||
class="l-shell__pane-tree"
|
||||
handle="after"
|
||||
label="Browse"
|
||||
collapsable>
|
||||
<mct-tree class="l-shell__tree"></mct-tree>
|
||||
collapsable
|
||||
>
|
||||
<mct-tree class="l-shell__tree" />
|
||||
</pane>
|
||||
<pane class="l-shell__pane-main">
|
||||
<browse-bar class="l-shell__main-view-browse-bar"
|
||||
ref="browseBar">
|
||||
</browse-bar>
|
||||
<toolbar v-if="toolbar" class="l-shell__toolbar"></toolbar>
|
||||
<object-view class="l-shell__main-container"
|
||||
<browse-bar
|
||||
ref="browseBar"
|
||||
class="l-shell__main-view-browse-bar"
|
||||
/>
|
||||
<toolbar
|
||||
v-if="toolbar"
|
||||
class="l-shell__toolbar"
|
||||
/>
|
||||
<object-view
|
||||
ref="browseObject"
|
||||
:showEditView="true"
|
||||
class="l-shell__main-container"
|
||||
:show-edit-view="true"
|
||||
data-selectable
|
||||
>
|
||||
</object-view>
|
||||
<component class="l-shell__time-conductor"
|
||||
:is="conductorComponent">
|
||||
</component>
|
||||
/>
|
||||
<component
|
||||
:is="conductorComponent"
|
||||
class="l-shell__time-conductor"
|
||||
/>
|
||||
</pane>
|
||||
<pane class="l-shell__pane-inspector l-pane--holds-multipane"
|
||||
<pane
|
||||
class="l-shell__pane-inspector l-pane--holds-multipane"
|
||||
handle="before"
|
||||
label="Inspect"
|
||||
collapsable>
|
||||
<Inspector :isEditing="isEditing" ref="inspector"></Inspector>
|
||||
collapsable
|
||||
>
|
||||
<Inspector
|
||||
ref="inspector"
|
||||
:is-editing="isEditing"
|
||||
/>
|
||||
</pane>
|
||||
</multipane>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -302,20 +326,20 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
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';
|
||||
import BrowseBar from './BrowseBar.vue';
|
||||
import Toolbar from '../toolbar/Toolbar.vue';
|
||||
import AppLogo from './AppLogo.vue';
|
||||
import Indicators from './status-bar/Indicators.vue';
|
||||
import NotificationBanner from './status-bar/NotificationBanner.vue';
|
||||
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';
|
||||
import BrowseBar from './BrowseBar.vue';
|
||||
import Toolbar from '../toolbar/Toolbar.vue';
|
||||
import AppLogo from './AppLogo.vue';
|
||||
import Indicators from './status-bar/Indicators.vue';
|
||||
import NotificationBanner from './status-bar/NotificationBanner.vue';
|
||||
|
||||
var enterFullScreen = () => {
|
||||
var enterFullScreen = () => {
|
||||
var docElm = document.documentElement;
|
||||
|
||||
if (docElm.requestFullscreen) {
|
||||
@ -327,8 +351,8 @@
|
||||
} else if (docElm.msRequestFullscreen) { /* IE/Edge */
|
||||
docElm.msRequestFullscreen();
|
||||
}
|
||||
};
|
||||
var exitFullScreen = () => {
|
||||
};
|
||||
var exitFullScreen = () => {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
@ -341,9 +365,9 @@
|
||||
else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
Inspector,
|
||||
@ -359,13 +383,6 @@
|
||||
Indicators,
|
||||
NotificationBanner
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', (isEditing)=>{
|
||||
this.isEditing = isEditing;
|
||||
});
|
||||
|
||||
this.openmct.selection.on('change', this.toggleHasToolbar);
|
||||
},
|
||||
data: function () {
|
||||
let storedHeadProps = window.localStorage.getItem('openmct-shell-head');
|
||||
let headExpanded = true;
|
||||
@ -386,6 +403,13 @@
|
||||
return this.hasToolbar && this.isEditing;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', (isEditing)=>{
|
||||
this.isEditing = isEditing;
|
||||
});
|
||||
|
||||
this.openmct.selection.on('change', this.toggleHasToolbar);
|
||||
},
|
||||
methods: {
|
||||
toggleShellHead() {
|
||||
this.headExpanded = !this.headExpanded;
|
||||
@ -423,5 +447,5 @@
|
||||
this.hasToolbar = structure.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<div class="c-search c-search--major">
|
||||
<input type="search" placeholder="Search"/>
|
||||
</div>
|
||||
<div class="c-search c-search--major">
|
||||
<input
|
||||
type="search"
|
||||
placeholder="Search"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -20,6 +23,6 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
}
|
||||
export default {
|
||||
}
|
||||
</script>
|
||||
|
@ -1,39 +1,60 @@
|
||||
<template>
|
||||
<div class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
v-if="views.length > 1">
|
||||
<button class="c-button--menu"
|
||||
<div
|
||||
v-if="views.length > 1"
|
||||
class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
>
|
||||
<button
|
||||
class="c-button--menu"
|
||||
:class="currentView.cssClass"
|
||||
title="Switch view type"
|
||||
@click.stop="toggleViewMenu">
|
||||
@click.stop="toggleViewMenu"
|
||||
>
|
||||
<span class="c-button__label">
|
||||
{{ currentView.name }}
|
||||
</span>
|
||||
</button>
|
||||
<div class="c-menu" v-show="showViewMenu">
|
||||
<div
|
||||
v-show="showViewMenu"
|
||||
class="c-menu"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="(view, index) in views"
|
||||
@click="setView(view)"
|
||||
<li
|
||||
v-for="(view, index) in views"
|
||||
:key="index"
|
||||
:class="view.cssClass"
|
||||
:title="view.name">
|
||||
:title="view.name"
|
||||
@click="setView(view)"
|
||||
>
|
||||
{{ view.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'currentView',
|
||||
'views'
|
||||
],
|
||||
props: {
|
||||
currentView: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
views: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showViewMenu: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('click', this.hideViewMenu);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('click', this.hideViewMenu);
|
||||
},
|
||||
methods: {
|
||||
setView(view) {
|
||||
this.$emit('setView', view);
|
||||
@ -44,12 +65,6 @@ export default {
|
||||
hideViewMenu() {
|
||||
this.showViewMenu = false;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('click', this.hideViewMenu);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('click', this.hideViewMenu);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,44 +1,56 @@
|
||||
<template>
|
||||
<div class="c-tree-and-search">
|
||||
<div class="c-tree-and-search">
|
||||
<div class="c-tree-and-search__search">
|
||||
<search class="c-search" ref="shell-search"
|
||||
<search
|
||||
ref="shell-search"
|
||||
class="c-search"
|
||||
:value="searchValue"
|
||||
@input="searchTree"
|
||||
@clear="searchTree">
|
||||
</search>
|
||||
@clear="searchTree"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- loading -->
|
||||
<div class="c-tree-and-search__loading loading"
|
||||
v-if="isLoading"></div>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="c-tree-and-search__loading loading"
|
||||
></div>
|
||||
<!-- end loading -->
|
||||
|
||||
<div class="c-tree-and-search__no-results"
|
||||
v-if="(allTreeItems.length === 0) || (searchValue && filteredTreeItems.length === 0)">
|
||||
<div
|
||||
v-if="(allTreeItems.length === 0) || (searchValue && filteredTreeItems.length === 0)"
|
||||
class="c-tree-and-search__no-results"
|
||||
>
|
||||
No results found
|
||||
</div>
|
||||
|
||||
<!-- main tree -->
|
||||
<ul class="c-tree-and-search__tree c-tree"
|
||||
<ul
|
||||
v-if="!isLoading"
|
||||
v-show="!searchValue">
|
||||
<tree-item v-for="treeItem in allTreeItems"
|
||||
v-show="!searchValue"
|
||||
class="c-tree-and-search__tree c-tree"
|
||||
>
|
||||
<tree-item
|
||||
v-for="treeItem in allTreeItems"
|
||||
:key="treeItem.id"
|
||||
:node="treeItem">
|
||||
</tree-item>
|
||||
:node="treeItem"
|
||||
/>
|
||||
</ul>
|
||||
<!-- end main tree -->
|
||||
|
||||
<!-- search tree -->
|
||||
<ul class="c-tree-and-search__tree c-tree"
|
||||
v-if="searchValue">
|
||||
<tree-item v-for="treeItem in filteredTreeItems"
|
||||
<ul
|
||||
v-if="searchValue"
|
||||
class="c-tree-and-search__tree c-tree"
|
||||
>
|
||||
<tree-item
|
||||
v-for="treeItem in filteredTreeItems"
|
||||
:key="treeItem.id"
|
||||
:node="treeItem">
|
||||
</tree-item>
|
||||
:node="treeItem"
|
||||
/>
|
||||
</ul>
|
||||
<!-- end search tree -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -185,12 +197,12 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import treeItem from './tree-item.vue'
|
||||
import search from '../components/search.vue';
|
||||
import treeItem from './tree-item.vue'
|
||||
import search from '../components/search.vue';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
name: 'mct-tree',
|
||||
name: 'MctTree',
|
||||
components: {
|
||||
search,
|
||||
treeItem
|
||||
@ -203,6 +215,10 @@
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.searchService = this.openmct.$injector.get('searchService');
|
||||
this.getAllChildren();
|
||||
},
|
||||
methods: {
|
||||
getAllChildren() {
|
||||
this.isLoading = true;
|
||||
@ -256,10 +272,6 @@
|
||||
this.getFilteredChildren();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.searchService = this.openmct.$injector.get('searchService');
|
||||
this.getAllChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="l-multipane"
|
||||
<div
|
||||
class="l-multipane"
|
||||
:class="{
|
||||
'l-multipane--vertical': type === 'vertical',
|
||||
'l-multipane--horizontal': type === 'horizontal'
|
||||
}">
|
||||
}"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -13,6 +15,7 @@ export default {
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: function (value) {
|
||||
return ['vertical', 'horizontal'].indexOf(value) !== -1;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="l-pane"
|
||||
<div
|
||||
class="l-pane"
|
||||
:class="{
|
||||
'l-pane--horizontal-handle-before': type === 'horizontal' && handle === 'before',
|
||||
'l-pane--horizontal-handle-after': type === 'horizontal' && handle === 'after',
|
||||
@ -8,22 +9,28 @@
|
||||
'l-pane--collapsed': collapsed,
|
||||
'l-pane--reacts': !handle,
|
||||
'l-pane--resizing': resizing === true
|
||||
}">
|
||||
<div v-if="handle"
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="handle"
|
||||
class="l-pane__handle"
|
||||
@mousedown="start">
|
||||
</div>
|
||||
<div class="l-pane__header"
|
||||
v-if="label">
|
||||
@mousedown="start"
|
||||
></div>
|
||||
<div
|
||||
v-if="label"
|
||||
class="l-pane__header"
|
||||
>
|
||||
<span class="l-pane__label">{{ label }}</span>
|
||||
<button class="l-pane__collapse-button c-button"
|
||||
<button
|
||||
v-if="collapsable"
|
||||
@click="toggleCollapse"></button>
|
||||
class="l-pane__collapse-button c-button"
|
||||
@click="toggleCollapse"
|
||||
></button>
|
||||
</div>
|
||||
<div class="l-pane__contents">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -350,15 +357,19 @@ export default {
|
||||
props: {
|
||||
handle: {
|
||||
type: String,
|
||||
default: '',
|
||||
validator: function (value) {
|
||||
return ['before', 'after'].indexOf(value) !== -1;
|
||||
return ['', 'before', 'after'].indexOf(value) !== -1;
|
||||
}
|
||||
},
|
||||
collapsable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
label: String
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -384,7 +395,7 @@ export default {
|
||||
delete this.dragCollapse;
|
||||
}
|
||||
},
|
||||
trackSize: function() {
|
||||
trackSize: function () {
|
||||
if (!this.dragCollapse === true) {
|
||||
if (this.type === 'vertical') {
|
||||
this.initial = this.$el.offsetHeight;
|
||||
|
@ -17,6 +17,7 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -152,7 +153,7 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
|
||||
mounted() {
|
||||
@ -160,5 +161,5 @@
|
||||
this.$el.appendChild(indicator.element);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -17,7 +17,9 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div class="c-message-banner"
|
||||
<div
|
||||
v-if="activeModel.message"
|
||||
class="c-message-banner"
|
||||
:class="[
|
||||
activeModel.severity,
|
||||
{
|
||||
@ -25,14 +27,17 @@
|
||||
'new': !activeModel.minimized
|
||||
}]"
|
||||
@click="maximize()"
|
||||
v-if="activeModel.message">
|
||||
<span class="c-message-banner__message">{{activeModel.message}}</span>
|
||||
>
|
||||
<span class="c-message-banner__message">{{ activeModel.message }}</span>
|
||||
<progress-bar
|
||||
v-if="activeModel.progressPerc !== undefined"
|
||||
class="c-message-banner__progress-bar"
|
||||
v-if="activeModel.progressPerc !== undefined" :model="activeModel">
|
||||
</progress-bar>
|
||||
<button class="c-message-banner__close-button c-click-icon icon-x-in-circle"
|
||||
@click.stop="dismiss()"></button>
|
||||
:model="activeModel"
|
||||
/>
|
||||
<button
|
||||
class="c-message-banner__close-button c-click-icon icon-x-in-circle"
|
||||
@click.stop="dismiss()"
|
||||
></button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -116,23 +121,22 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ProgressBar from '../../components/ProgressBar.vue';
|
||||
let activeNotification = undefined;
|
||||
let dialogService = undefined;
|
||||
let maximizedDialog = undefined;
|
||||
let minimizeButton = {
|
||||
import ProgressBar from '../../components/ProgressBar.vue';
|
||||
let activeNotification = undefined;
|
||||
let maximizedDialog = undefined;
|
||||
let minimizeButton = {
|
||||
label: 'Dismiss',
|
||||
callback: dismissMaximizedDialog
|
||||
}
|
||||
}
|
||||
|
||||
function dismissMaximizedDialog() {
|
||||
function dismissMaximizedDialog() {
|
||||
if (maximizedDialog) {
|
||||
maximizedDialog.dismiss();
|
||||
maximizedDialog = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateMaxProgressBar(progressPerc, progressText) {
|
||||
function updateMaxProgressBar(progressPerc, progressText) {
|
||||
if (maximizedDialog) {
|
||||
maximizedDialog.updateProgress(progressPerc, progressText);
|
||||
|
||||
@ -140,9 +144,9 @@
|
||||
dismissMaximizedDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
ProgressBar: ProgressBar
|
||||
@ -157,6 +161,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
progressWidth() {
|
||||
return {
|
||||
width: this.activeModel.progress + '%'
|
||||
};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.notifications.on('notification', this.showNotification);
|
||||
},
|
||||
methods: {
|
||||
showNotification(notification) {
|
||||
if (activeNotification) {
|
||||
@ -226,17 +240,7 @@
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
progressWidth() {
|
||||
return {
|
||||
width: this.activeModel.progress + '%'
|
||||
};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.notifications.on('notification', this.showNotification);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,40 +1,57 @@
|
||||
<template>
|
||||
<li class="c-tree__item-h">
|
||||
<div class="c-tree__item"
|
||||
:class="{ 'is-alias': isAlias, 'is-navigated-object': isNavigated }">
|
||||
<view-control class="c-tree__item__view-control"
|
||||
<li class="c-tree__item-h">
|
||||
<div
|
||||
class="c-tree__item"
|
||||
:class="{ 'is-alias': isAlias, 'is-navigated-object': isNavigated }"
|
||||
>
|
||||
<view-control
|
||||
v-model="expanded"
|
||||
class="c-tree__item__view-control"
|
||||
:enabled="hasChildren"
|
||||
v-model="expanded">
|
||||
</view-control>
|
||||
<object-label :domainObject="node.object"
|
||||
:objectPath="node.objectPath"
|
||||
:navigateToPath="navigateToPath">
|
||||
</object-label>
|
||||
/>
|
||||
<object-label
|
||||
:domain-object="node.object"
|
||||
:object-path="node.objectPath"
|
||||
:navigate-to-path="navigateToPath"
|
||||
/>
|
||||
</div>
|
||||
<ul v-if="expanded" class="c-tree">
|
||||
<li class="c-tree__item-h"
|
||||
v-if="isLoading && !loaded">
|
||||
<ul
|
||||
v-if="expanded"
|
||||
class="c-tree"
|
||||
>
|
||||
<li
|
||||
v-if="isLoading && !loaded"
|
||||
class="c-tree__item-h"
|
||||
>
|
||||
<div class="c-tree__item loading">
|
||||
<span class="c-tree__item__label">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
<tree-item v-for="child in children"
|
||||
<tree-item
|
||||
v-for="child in children"
|
||||
:key="child.id"
|
||||
:node="child">
|
||||
</tree-item>
|
||||
:node="child"
|
||||
/>
|
||||
</ul>
|
||||
</li>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import viewControl from '../components/viewControl.vue';
|
||||
import ObjectLabel from '../components/ObjectLabel.vue';
|
||||
import viewControl from '../components/viewControl.vue';
|
||||
import ObjectLabel from '../components/ObjectLabel.vue';
|
||||
|
||||
export default {
|
||||
name: 'tree-item',
|
||||
export default {
|
||||
name: 'TreeItem',
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
viewControl,
|
||||
ObjectLabel
|
||||
},
|
||||
props: {
|
||||
node: Object
|
||||
node: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.navigateToPath = this.buildPathString(this.node.navigateToParent)
|
||||
@ -57,6 +74,20 @@
|
||||
return parentKeyString !== this.node.object.location;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
expanded(isExpanded) {
|
||||
if (!this.hasChildren) {
|
||||
return;
|
||||
}
|
||||
if (!this.loaded && !this.isLoading) {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load().then(this.finishLoading);
|
||||
this.isLoading = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// TODO: should update on mutation.
|
||||
// TODO: click navigation should not fubar hash quite so much.
|
||||
@ -85,22 +116,8 @@
|
||||
delete this.composition;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
expanded(isExpanded) {
|
||||
if (!this.hasChildren) {
|
||||
return;
|
||||
}
|
||||
if (!this.loaded && !this.isLoading) {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load().then(this.finishLoading);
|
||||
this.isLoading = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addChild (child) {
|
||||
addChild(child) {
|
||||
this.children.push({
|
||||
id: this.openmct.objects.makeKeyString(child.identifier),
|
||||
object: child,
|
||||
@ -113,24 +130,20 @@
|
||||
this.children = this.children
|
||||
.filter(c => c.id !== removeId);
|
||||
},
|
||||
finishLoading () {
|
||||
finishLoading() {
|
||||
this.isLoading = false;
|
||||
this.loaded = true;
|
||||
},
|
||||
buildPathString(parentPath) {
|
||||
return [parentPath, this.openmct.objects.makeKeyString(this.node.object.identifier)].join('/');
|
||||
},
|
||||
highlightIfNavigated(newPath, oldPath){
|
||||
highlightIfNavigated(newPath, oldPath) {
|
||||
if (newPath === this.navigateToPath) {
|
||||
this.isNavigated = true;
|
||||
} else if (oldPath === this.navigateToPath) {
|
||||
this.isNavigated = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
viewControl,
|
||||
ObjectLabel
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,12 +1,15 @@
|
||||
<template>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
templateKey: String
|
||||
templateKey: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let openmct = this.openmct;
|
||||
|
@ -19,37 +19,40 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="l-preview-window">
|
||||
<template>
|
||||
<div class="l-preview-window">
|
||||
<div class="l-browse-bar">
|
||||
<div class="l-browse-bar__start">
|
||||
<div class="l-browse-bar__object-name--w"
|
||||
:class="type.cssClass">
|
||||
<div
|
||||
class="l-browse-bar__object-name--w"
|
||||
:class="type.cssClass"
|
||||
>
|
||||
<span class="l-browse-bar__object-name">
|
||||
{{ domainObject.name }}
|
||||
</span>
|
||||
<context-menu-drop-down :object-path="objectPath"></context-menu-drop-down>
|
||||
<context-menu-drop-down :object-path="objectPath" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="l-browse-bar__end">
|
||||
<div class="l-browse-bar__actions">
|
||||
<view-switcher
|
||||
:views="views"
|
||||
:currentView="currentView"
|
||||
@setView="setView">
|
||||
</view-switcher>
|
||||
<button v-if="notebookEnabled"
|
||||
:current-view="currentView"
|
||||
@setView="setView"
|
||||
/>
|
||||
<button
|
||||
v-if="notebookEnabled"
|
||||
class="l-browse-bar__actions__edit c-button icon-notebook"
|
||||
title="New Notebook entry"
|
||||
@click="snapshot">
|
||||
</button>
|
||||
@click="snapshot"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="l-preview-window__object-view">
|
||||
<div ref="objectView"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -83,12 +86,12 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ContextMenuDropDown from '../../ui/components/contextMenuDropDown.vue';
|
||||
import ViewSwitcher from '../../ui/layout/ViewSwitcher.vue';
|
||||
import NotebookSnapshot from '../utils/notebook-snapshot';
|
||||
<script>
|
||||
import ContextMenuDropDown from '../../ui/components/contextMenuDropDown.vue';
|
||||
import ViewSwitcher from '../../ui/layout/ViewSwitcher.vue';
|
||||
import NotebookSnapshot from '../utils/notebook-snapshot';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
components: {
|
||||
ContextMenuDropDown,
|
||||
ViewSwitcher
|
||||
@ -97,6 +100,17 @@
|
||||
'openmct',
|
||||
'objectPath'
|
||||
],
|
||||
data() {
|
||||
let domainObject = this.objectPath[0];
|
||||
let type = this.openmct.types.get(domainObject.type);
|
||||
|
||||
return {
|
||||
domainObject: domainObject,
|
||||
type: type,
|
||||
notebookEnabled: false,
|
||||
viewKey: undefined
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
views() {
|
||||
return this
|
||||
@ -108,6 +122,18 @@
|
||||
return this.views.filter(v => v.key === this.viewKey)[0] || {};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let view = this.openmct.objectViews.get(this.domainObject)[0];
|
||||
this.setView(view);
|
||||
|
||||
if (this.openmct.types.get('notebook')) {
|
||||
this.notebookSnapshot = new NotebookSnapshot(this.openmct);
|
||||
this.notebookEnabled = true;
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.view.destroy();
|
||||
},
|
||||
methods: {
|
||||
snapshot() {
|
||||
let element = document.getElementsByClassName("l-preview-window__object-view")[0];
|
||||
@ -132,29 +158,6 @@
|
||||
this.view = this.currentView.view(this.domainObject, this.objectPath);
|
||||
this.view.show(this.viewContainer, false);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let domainObject = this.objectPath[0];
|
||||
let type = this.openmct.types.get(domainObject.type);
|
||||
|
||||
return {
|
||||
domainObject: domainObject,
|
||||
type: type,
|
||||
notebookEnabled: false,
|
||||
viewKey: undefined
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
let view = this.openmct.objectViews.get(this.domainObject)[0];
|
||||
this.setView(view);
|
||||
|
||||
if (this.openmct.types.get('notebook')) {
|
||||
this.notebookSnapshot = new NotebookSnapshot(this.openmct);
|
||||
this.notebookEnabled = true;
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.view.destroy();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
|
@ -1,26 +1,29 @@
|
||||
<template>
|
||||
<div class="c-toolbar">
|
||||
<component v-for="item in structure"
|
||||
<div class="c-toolbar">
|
||||
<component
|
||||
:is="item.control"
|
||||
v-for="(item, index) in structure"
|
||||
:key="index"
|
||||
:options="item"
|
||||
@click="triggerMethod(item, $event)"
|
||||
@change="updateObjectValue"></component>
|
||||
</div>
|
||||
@change="updateObjectValue"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import toolbarButton from './components/toolbar-button.vue';
|
||||
import toolbarColorPicker from './components/toolbar-color-picker.vue';
|
||||
import toolbarCheckbox from './components/toolbar-checkbox.vue';
|
||||
import toolbarInput from './components/toolbar-input.vue';
|
||||
import toolbarMenu from './components/toolbar-menu.vue';
|
||||
import toolbarSelectMenu from './components/toolbar-select-menu.vue';
|
||||
import toolbarSeparator from './components/toolbar-separator.vue';
|
||||
import toolbarToggleButton from './components/toolbar-toggle-button.vue';
|
||||
import toolbarButton from './components/toolbar-button.vue';
|
||||
import toolbarColorPicker from './components/toolbar-color-picker.vue';
|
||||
import toolbarCheckbox from './components/toolbar-checkbox.vue';
|
||||
import toolbarInput from './components/toolbar-input.vue';
|
||||
import toolbarMenu from './components/toolbar-menu.vue';
|
||||
import toolbarSelectMenu from './components/toolbar-select-menu.vue';
|
||||
import toolbarSeparator from './components/toolbar-separator.vue';
|
||||
import toolbarToggleButton from './components/toolbar-toggle-button.vue';
|
||||
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default {
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
toolbarButton,
|
||||
@ -37,6 +40,14 @@
|
||||
structure: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.handleSelection);
|
||||
this.handleSelection(this.openmct.selection.get());
|
||||
|
||||
// Toolbars may change when edit mode is enabled/disabled, so listen
|
||||
// for edit mode changes and update toolbars if necessary.
|
||||
this.openmct.editor.on('isEditing', this.handleEditing);
|
||||
},
|
||||
methods: {
|
||||
handleSelection(selection) {
|
||||
this.removeListeners();
|
||||
@ -81,7 +92,7 @@
|
||||
}
|
||||
},
|
||||
observeObject(domainObject, id) {
|
||||
let unobserveObject = this.openmct.objects.observe(domainObject, '*', function(newObject) {
|
||||
let unobserveObject = this.openmct.objects.observe(domainObject, '*', function (newObject) {
|
||||
this.domainObjectsById[id].newObject = JSON.parse(JSON.stringify(newObject));
|
||||
this.updateToolbarAfterMutation();
|
||||
}.bind(this));
|
||||
@ -133,7 +144,7 @@
|
||||
}
|
||||
|
||||
// If all values are the same, use it, otherwise mark the item as non-specific.
|
||||
if (values.every(value => value === values[0])) {
|
||||
if (values.every(val => val === values[0])) {
|
||||
value = values[0];
|
||||
toolbarItem.nonSpecific = false;
|
||||
} else {
|
||||
@ -169,7 +180,7 @@
|
||||
});
|
||||
|
||||
for (const key in values) {
|
||||
if (values[key].every(value => value === values[key][0])) {
|
||||
if (values[key].every(val => val === values[key][0])) {
|
||||
value[key] = values[key][0];
|
||||
toolbarItem.nonSpecific = false;
|
||||
} else {
|
||||
@ -250,18 +261,10 @@
|
||||
this.handleSelection(this.openmct.selection.get());
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.handleSelection);
|
||||
this.handleSelection(this.openmct.selection.get());
|
||||
|
||||
// Toolbars may change when edit mode is enabled/disabled, so listen
|
||||
// for edit mode changes and update toolbars if necessary.
|
||||
this.openmct.editor.on('isEditing', this.handleEditing);
|
||||
},
|
||||
detroyed() {
|
||||
this.openmct.selection.off('change', this.handleSelection);
|
||||
this.openmct.editor.off('isEditing', this.handleEditing);
|
||||
this.removeListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,26 +1,33 @@
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div class="c-icon-button"
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div
|
||||
class="c-icon-button"
|
||||
:title="options.title"
|
||||
:class="{
|
||||
[options.icon]: true,
|
||||
'c-icon-button--caution': options.modifier === 'caution',
|
||||
'c-icon-button--mixed': nonSpecific
|
||||
}"
|
||||
@click="onClick">
|
||||
<div class="c-icon-button__label"
|
||||
v-if="options.label">
|
||||
@click="onClick"
|
||||
>
|
||||
<div
|
||||
v-if="options.label"
|
||||
class="c-icon-button__label"
|
||||
>
|
||||
{{ options.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
options: Object
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nonSpecific() {
|
||||
|
@ -1,19 +1,21 @@
|
||||
<template>
|
||||
<div class="c-custom-checkbox">
|
||||
<input type="checkbox"
|
||||
<div class="c-custom-checkbox">
|
||||
<input
|
||||
:id="uid"
|
||||
type="checkbox"
|
||||
:name="options.name"
|
||||
:checked="options.value"
|
||||
:disabled="options.disabled"
|
||||
@change="onChange">
|
||||
@change="onChange"
|
||||
>
|
||||
|
||||
<label :for="uid">
|
||||
<div class="c-custom-checkbox__box"></div>
|
||||
<div class="c-custom-checkbox__label-text">
|
||||
{{options.name}}
|
||||
{{ options.name }}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -72,7 +74,10 @@ let uniqueId = 100;
|
||||
|
||||
export default {
|
||||
props: {
|
||||
options: Object
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
uniqueId++;
|
||||
|
@ -1,30 +1,41 @@
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div class="c-icon-button c-icon-button--swatched"
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div
|
||||
class="c-icon-button c-icon-button--swatched"
|
||||
:class="[options.icon, {'c-icon-button--mixed': nonSpecific}]"
|
||||
:title="options.title"
|
||||
@click="toggle">
|
||||
<div class="c-swatch" :style="{
|
||||
@click="toggle"
|
||||
>
|
||||
<div
|
||||
class="c-swatch"
|
||||
:style="{
|
||||
background: options.value
|
||||
}"></div>
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="c-menu c-palette c-palette--color"
|
||||
v-if="open">
|
||||
<div class="c-palette__item-none"
|
||||
v-if="!this.options.preventNone"
|
||||
@click="select({value: 'transparent'})">
|
||||
<div
|
||||
v-if="open"
|
||||
class="c-menu c-palette c-palette--color"
|
||||
>
|
||||
<div
|
||||
v-if="!options.preventNone"
|
||||
class="c-palette__item-none"
|
||||
@click="select({value: 'transparent'})"
|
||||
>
|
||||
<div class="c-palette__item"></div>
|
||||
None
|
||||
</div>
|
||||
<div class="c-palette__items">
|
||||
<div class="c-palette__item"
|
||||
v-for="color in colorPalette"
|
||||
<div
|
||||
v-for="(color, index) in colorPalette"
|
||||
:key="index"
|
||||
class="c-palette__item"
|
||||
:style="{ background: color.value }"
|
||||
@click="select(color)"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -34,18 +45,9 @@ import toggleMixin from '../../mixins/toggle-mixin';
|
||||
export default {
|
||||
mixins: [toggleMixin],
|
||||
props: {
|
||||
options: Object
|
||||
},
|
||||
computed: {
|
||||
nonSpecific() {
|
||||
return this.options.nonSpecific === true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
select(color) {
|
||||
if (color.value !== this.options.value) {
|
||||
this.$emit('change', color.value, this.options);
|
||||
}
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -133,6 +135,18 @@ export default {
|
||||
{ value: '#4c1130' }
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
nonSpecific() {
|
||||
return this.options.nonSpecific === true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
select(color) {
|
||||
if (color.value !== this.options.value) {
|
||||
this.$emit('change', color.value, this.options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,14 +1,18 @@
|
||||
<template>
|
||||
<div class="c-labeled-input"
|
||||
:title="options.title">
|
||||
<div
|
||||
class="c-labeled-input"
|
||||
:title="options.title"
|
||||
>
|
||||
<label :for="uid">
|
||||
<div class="c-labeled-input__label">{{ options.label }}</div>
|
||||
</label>
|
||||
<input :id="uid"
|
||||
<input
|
||||
:id="uid"
|
||||
:type="options.type"
|
||||
:value="options.value"
|
||||
v-bind="options.attrs"/>
|
||||
</div>
|
||||
v-bind="options.attrs"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -19,6 +23,7 @@ export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator(value) {
|
||||
return ['number', 'text'].indexOf(value.type) !== -1;
|
||||
}
|
||||
|
@ -1,24 +1,34 @@
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div class="c-icon-button c-icon-button--menu"
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div
|
||||
class="c-icon-button c-icon-button--menu"
|
||||
:class="options.icon"
|
||||
:title="options.title"
|
||||
@click="toggle">
|
||||
<div class="c-icon-button__label"
|
||||
v-if="options.label">
|
||||
@click="toggle"
|
||||
>
|
||||
<div
|
||||
v-if="options.label"
|
||||
class="c-icon-button__label"
|
||||
>
|
||||
{{ options.label }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-menu" v-if="open">
|
||||
<div
|
||||
v-if="open"
|
||||
class="c-menu"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="option in options.options"
|
||||
<li
|
||||
v-for="(option, index) in options.options"
|
||||
:key="index"
|
||||
:class="option.class"
|
||||
@click="onClick(option)"
|
||||
:class="option.class">
|
||||
>
|
||||
{{ option.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -28,6 +38,7 @@ export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator(value) {
|
||||
// must pass valid options array.
|
||||
return Array.isArray(value.options) &&
|
||||
|
@ -1,21 +1,30 @@
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div class="c-icon-button c-icon-button--menu"
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div
|
||||
class="c-icon-button c-icon-button--menu"
|
||||
:class="[options.icon, {'c-click-icon--mixed': nonSpecific}]"
|
||||
:title="options.title"
|
||||
@click="toggle">
|
||||
<div class="c-button__label">{{ selectedName }}</div>
|
||||
@click="toggle"
|
||||
>
|
||||
<div class="c-button__label">
|
||||
{{ selectedName }}
|
||||
</div>
|
||||
<div class="c-menu" v-if="open">
|
||||
</div>
|
||||
<div
|
||||
v-if="open"
|
||||
class="c-menu"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="option in options.options"
|
||||
<li
|
||||
v-for="option in options.options"
|
||||
:key="option.value"
|
||||
@click="select(option)">
|
||||
@click="select(option)"
|
||||
>
|
||||
{{ option.name || option.value }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -26,6 +35,7 @@ export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator(value) {
|
||||
// must pass valid options array.
|
||||
return Array.isArray(value.options) &&
|
||||
@ -33,14 +43,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
select(option) {
|
||||
if (this.options.value === option.value) {
|
||||
return;
|
||||
}
|
||||
this.$emit('change', option.value, this.options);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectedName() {
|
||||
let selectedOption = this.options.options.filter((o) => o.value === this.options.value)[0];
|
||||
@ -53,6 +55,14 @@ export default {
|
||||
nonSpecific() {
|
||||
return this.options.nonSpecific === true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
select(option) {
|
||||
if (this.options.value === option.value) {
|
||||
return;
|
||||
}
|
||||
this.$emit('change', option.value, this.options);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,11 +1,14 @@
|
||||
<template>
|
||||
<div class="c-toolbar__separator"></div>
|
||||
<div class="c-toolbar__separator"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
options: Object
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,18 +1,20 @@
|
||||
<template>
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div class="c-icon-button"
|
||||
<div class="c-ctrl-wrapper">
|
||||
<div
|
||||
class="c-icon-button"
|
||||
:title="nextValue.title"
|
||||
:class="[nextValue.icon, {'c-icon-button--mixed': nonSpecific}]"
|
||||
@click="cycle">
|
||||
</div>
|
||||
</div>
|
||||
@click="cycle"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
Loading…
Reference in New Issue
Block a user