mirror of
https://github.com/nasa/openmct.git
synced 2025-06-17 06:38:17 +00:00
Feature/eslint plugin vue (#2548)
* Use eslint-plugin-vue to lint vue files
This commit is contained in:
@ -21,70 +21,78 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-properties" v-if="isEditing">
|
||||
<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">
|
||||
<label for="telemetryPrintfFormat">Format</label>
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
<input id="telemetryPrintfFormat"
|
||||
type="text"
|
||||
@change="formatTelemetry"
|
||||
:value="telemetryFormat"
|
||||
:placeholder="nonMixedFormat ? '' : 'Mixed'"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<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"
|
||||
>
|
||||
<label for="telemetryPrintfFormat">Format</label>
|
||||
</div>
|
||||
<div class="c-properties__value">
|
||||
<input
|
||||
id="telemetryPrintfFormat"
|
||||
type="text"
|
||||
:value="telemetryFormat"
|
||||
:placeholder="nonMixedFormat ? '' : 'Mixed'"
|
||||
@change="formatTelemetry"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
let selectionPath = this.openmct.selection.get()[0];
|
||||
return {
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
telemetryFormat: undefined,
|
||||
nonMixedFormat: false
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
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;
|
||||
},
|
||||
formatTelemetry(event) {
|
||||
let newFormat = event.currentTarget.value;
|
||||
this.openmct.selection.get().forEach(selectionPath => {
|
||||
selectionPath[0].context.updateTelemetryFormat(newFormat);
|
||||
});
|
||||
this.telemetryFormat = newFormat;
|
||||
},
|
||||
handleSelection(selection) {
|
||||
if (selection.length === 0 || selection[0].length < 2) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleEdit(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
},
|
||||
formatTelemetry(event) {
|
||||
let newFormat = event.currentTarget.value;
|
||||
this.openmct.selection.get().forEach(selectionPath => {
|
||||
selectionPath[0].context.updateTelemetryFormat(newFormat);
|
||||
});
|
||||
this.telemetryFormat = newFormat;
|
||||
},
|
||||
handleSelection(selection) {
|
||||
if (selection.length === 0 || selection[0].length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
let format = selection[0][0].context.layoutItem.format;
|
||||
this.nonMixedFormat = selection.every(selectionPath => {
|
||||
return selectionPath[0].context.layoutItem.format === format;
|
||||
});
|
||||
let format = selection[0][0].context.layoutItem.format;
|
||||
this.nonMixedFormat = selection.every(selectionPath => {
|
||||
return selectionPath[0].context.layoutItem.format === format;
|
||||
});
|
||||
|
||||
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);
|
||||
this.telemetryFormat = this.nonMixedFormat ? format : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
@ -21,15 +21,18 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -44,60 +47,70 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
export default {
|
||||
makeDefinition() {
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#717171',
|
||||
stroke: 'transparent',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
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 {
|
||||
fill: '#717171',
|
||||
stroke: 'transparent',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5
|
||||
backgroundColor: this.item.fill,
|
||||
border: '1px solid ' + this.item.stroke
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
index: Number,
|
||||
initSelect: Boolean
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
border: '1px solid ' + this.item.stroke
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
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.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
}
|
||||
</script>
|
||||
|
@ -21,42 +21,49 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout"
|
||||
@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"
|
||||
v-if="gridSize[0] >= 3"
|
||||
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
|
||||
</div>
|
||||
<div class="c-grid__y l-grid l-grid-y"
|
||||
v-if="gridSize[1] >= 3"
|
||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
|
||||
</div>
|
||||
<component v-for="(item, index) in layoutItems"
|
||||
:is="item.type"
|
||||
:item="item"
|
||||
:key="item.id"
|
||||
:gridSize="gridSize"
|
||||
:initSelect="initSelectIndex === index"
|
||||
:index="index"
|
||||
:multiSelect="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
|
||||
class="l-layout"
|
||||
:class="{
|
||||
'is-multi-selected': selectedLayoutItems.length > 1
|
||||
}"
|
||||
@dragover="handleDragOver"
|
||||
@click.capture="bypassSelection"
|
||||
@drop="handleDrop"
|
||||
>
|
||||
<!-- Background grid -->
|
||||
<div class="l-layout__grid-holder c-grid">
|
||||
<div
|
||||
v-if="gridSize[0] >= 3"
|
||||
class="c-grid__x l-grid l-grid-x"
|
||||
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]"
|
||||
></div>
|
||||
<div
|
||||
v-if="gridSize[1] >= 3"
|
||||
class="c-grid__y l-grid l-grid-y"
|
||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"
|
||||
></div>
|
||||
</div>
|
||||
<component
|
||||
:is="item.type"
|
||||
v-for="(item, index) in layoutItems"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:init-select="initSelectIndex === index"
|
||||
:index="index"
|
||||
:multi-select="selectedLayoutItems.length > 1"
|
||||
@move="move"
|
||||
@endMove="endMove"
|
||||
@endLineResize="endLineResize"
|
||||
@formatChanged="updateTelemetryFormat"
|
||||
/>
|
||||
<edit-marquee
|
||||
v-if="showMarquee"
|
||||
:grid-size="gridSize"
|
||||
:selected-layout-items="selectedLayoutItems"
|
||||
@endResize="endResize"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -135,452 +142,455 @@
|
||||
</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 = {
|
||||
'subobject-view': SubobjectView,
|
||||
'telemetry-view': TelemetryView,
|
||||
'box-view': BoxView,
|
||||
'line-view': LineView,
|
||||
'text-view': TextView,
|
||||
'image-view': ImageView
|
||||
};
|
||||
const ORDERS = {
|
||||
top: Number.POSITIVE_INFINITY,
|
||||
up: 1,
|
||||
down: -1,
|
||||
bottom: Number.NEGATIVE_INFINITY
|
||||
};
|
||||
const DRAG_OBJECT_TRANSFER_PREFIX = 'openmct/domain-object/';
|
||||
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 = {
|
||||
top: Number.POSITIVE_INFINITY,
|
||||
up: 1,
|
||||
down: -1,
|
||||
bottom: Number.NEGATIVE_INFINITY
|
||||
};
|
||||
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) {
|
||||
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
|
||||
function getItemDefinition(itemType, ...options) {
|
||||
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
|
||||
|
||||
if (!itemView) {
|
||||
throw `Invalid itemType: ${itemType}`;
|
||||
}
|
||||
|
||||
return itemView.makeDefinition(...options);
|
||||
if (!itemView) {
|
||||
throw `Invalid itemType: ${itemType}`;
|
||||
}
|
||||
|
||||
export default {
|
||||
data() {
|
||||
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
|
||||
return {
|
||||
internalDomainObject: domainObject,
|
||||
initSelectIndex: undefined,
|
||||
selection: []
|
||||
};
|
||||
return itemView.makeDefinition(...options);
|
||||
}
|
||||
|
||||
export default {
|
||||
components: components,
|
||||
props: {
|
||||
domainObject: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
|
||||
return {
|
||||
internalDomainObject: domainObject,
|
||||
initSelectIndex: undefined,
|
||||
selection: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
gridSize() {
|
||||
return this.internalDomainObject.configuration.layoutGrid;
|
||||
},
|
||||
computed: {
|
||||
gridSize() {
|
||||
return this.internalDomainObject.configuration.layoutGrid;
|
||||
},
|
||||
layoutItems() {
|
||||
return this.internalDomainObject.configuration.items;
|
||||
},
|
||||
selectedLayoutItems() {
|
||||
return this.layoutItems.filter(item => {
|
||||
return this.itemIsInCurrentSelection(item);
|
||||
});
|
||||
},
|
||||
showMarquee() {
|
||||
let selectionPath = this.selection[0];
|
||||
let singleSelectedLine = this.selection.length === 1 &&
|
||||
layoutItems() {
|
||||
return this.internalDomainObject.configuration.items;
|
||||
},
|
||||
selectedLayoutItems() {
|
||||
return this.layoutItems.filter(item => {
|
||||
return this.itemIsInCurrentSelection(item);
|
||||
});
|
||||
},
|
||||
showMarquee() {
|
||||
let selectionPath = this.selection[0];
|
||||
let singleSelectedLine = this.selection.length === 1 &&
|
||||
selectionPath[0].context.layoutItem && selectionPath[0].context.layoutItem.type === 'line-view';
|
||||
return selectionPath && selectionPath.length > 1 && !singleSelectedLine;
|
||||
return selectionPath && selectionPath.length > 1 && !singleSelectedLine;
|
||||
}
|
||||
},
|
||||
inject: ['openmct', 'options', 'objectPath'],
|
||||
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);
|
||||
},
|
||||
setSelection(selection) {
|
||||
this.selection = selection;
|
||||
},
|
||||
itemIsInCurrentSelection(item) {
|
||||
return this.selection.some(selectionPath =>
|
||||
selectionPath[0].context.layoutItem && selectionPath[0].context.layoutItem.id === item.id);
|
||||
},
|
||||
bypassSelection($event) {
|
||||
if (this.dragInProgress) {
|
||||
if ($event) {
|
||||
$event.stopImmediatePropagation();
|
||||
}
|
||||
this.dragInProgress = false;
|
||||
return;
|
||||
}
|
||||
},
|
||||
inject: ['openmct', 'options', 'objectPath'],
|
||||
props: ['domainObject'],
|
||||
components: components,
|
||||
methods: {
|
||||
addElement(itemType, element) {
|
||||
this.addItem(itemType + '-view', element);
|
||||
},
|
||||
setSelection(selection) {
|
||||
this.selection = selection;
|
||||
},
|
||||
itemIsInCurrentSelection(item) {
|
||||
return this.selection.some(selectionPath =>
|
||||
selectionPath[0].context.layoutItem && selectionPath[0].context.layoutItem.id === item.id);
|
||||
},
|
||||
bypassSelection($event) {
|
||||
if (this.dragInProgress) {
|
||||
if ($event) {
|
||||
$event.stopImmediatePropagation();
|
||||
}
|
||||
this.dragInProgress = false;
|
||||
return;
|
||||
}
|
||||
},
|
||||
endLineResize(item, updates) {
|
||||
this.dragInProgress = true;
|
||||
let index = this.layoutItems.indexOf(item);
|
||||
Object.assign(item, updates);
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
},
|
||||
endResize(scaleWidth, scaleHeight, marqueeStart, marqueeOffset) {
|
||||
this.dragInProgress = true;
|
||||
this.layoutItems.forEach(item => {
|
||||
if (this.itemIsInCurrentSelection(item)) {
|
||||
let itemXInMarqueeSpace = item.x - marqueeStart.x;
|
||||
let itemXInMarqueeSpaceAfterScale = Math.round(itemXInMarqueeSpace * scaleWidth);
|
||||
item.x = itemXInMarqueeSpaceAfterScale + marqueeOffset.x + marqueeStart.x;
|
||||
endLineResize(item, updates) {
|
||||
this.dragInProgress = true;
|
||||
let index = this.layoutItems.indexOf(item);
|
||||
Object.assign(item, updates);
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
},
|
||||
endResize(scaleWidth, scaleHeight, marqueeStart, marqueeOffset) {
|
||||
this.dragInProgress = true;
|
||||
this.layoutItems.forEach(item => {
|
||||
if (this.itemIsInCurrentSelection(item)) {
|
||||
let itemXInMarqueeSpace = item.x - marqueeStart.x;
|
||||
let itemXInMarqueeSpaceAfterScale = Math.round(itemXInMarqueeSpace * scaleWidth);
|
||||
item.x = itemXInMarqueeSpaceAfterScale + marqueeOffset.x + marqueeStart.x;
|
||||
|
||||
let itemYInMarqueeSpace = item.y - marqueeStart.y;
|
||||
let itemYInMarqueeSpaceAfterScale = Math.round(itemYInMarqueeSpace * scaleHeight);
|
||||
item.y = itemYInMarqueeSpaceAfterScale + marqueeOffset.y + marqueeStart.y;
|
||||
let itemYInMarqueeSpace = item.y - marqueeStart.y;
|
||||
let itemYInMarqueeSpaceAfterScale = Math.round(itemYInMarqueeSpace * scaleHeight);
|
||||
item.y = itemYInMarqueeSpaceAfterScale + marqueeOffset.y + marqueeStart.y;
|
||||
|
||||
if (item.x2) {
|
||||
let itemX2InMarqueeSpace = item.x2 - marqueeStart.x;
|
||||
let itemX2InMarqueeSpaceAfterScale = Math.round(itemX2InMarqueeSpace * scaleWidth);
|
||||
item.x2 = itemX2InMarqueeSpaceAfterScale + marqueeOffset.x + marqueeStart.x;
|
||||
} else {
|
||||
item.width = Math.round(item.width * scaleWidth);
|
||||
}
|
||||
|
||||
if (item.y2) {
|
||||
let itemY2InMarqueeSpace = item.y2 - marqueeStart.y;
|
||||
let itemY2InMarqueeSpaceAfterScale = Math.round(itemY2InMarqueeSpace * scaleHeight);
|
||||
item.y2 = itemY2InMarqueeSpaceAfterScale + marqueeOffset.y + marqueeStart.y;
|
||||
} else {
|
||||
item.height = Math.round(item.height * scaleHeight);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.mutate("configuration.items", this.layoutItems);
|
||||
},
|
||||
move(gridDelta) {
|
||||
this.dragInProgress = true;
|
||||
|
||||
if (!this.initialPositions) {
|
||||
this.initialPositions = {};
|
||||
_.cloneDeep(this.selectedLayoutItems).forEach(selectedItem => {
|
||||
if (selectedItem.type === 'line-view') {
|
||||
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y, selectedItem.x2, selectedItem.y2];
|
||||
this.startingMinX2 = this.startingMinX2 !== undefined ? Math.min(this.startingMinX2, selectedItem.x2) : selectedItem.x2;
|
||||
this.startingMinY2 = this.startingMinY2 !== undefined ? Math.min(this.startingMinY2, selectedItem.y2) : selectedItem.y2;
|
||||
} else {
|
||||
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y];
|
||||
}
|
||||
|
||||
this.startingMinX = this.startingMinX !== undefined ? Math.min(this.startingMinX, selectedItem.x) : selectedItem.x;
|
||||
this.startingMinY = this.startingMinY !== undefined ? Math.min(this.startingMinY, selectedItem.y) : selectedItem.y;
|
||||
});
|
||||
}
|
||||
|
||||
let layoutItems = this.layoutItems.map(item => {
|
||||
if (this.initialPositions[item.id]) {
|
||||
this.updateItemPosition(item, gridDelta);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
},
|
||||
updateItemPosition(item, gridDelta) {
|
||||
let startingPosition = this.initialPositions[item.id];
|
||||
let [startingX, startingY, startingX2, startingY2] = startingPosition;
|
||||
|
||||
if (this.startingMinX + gridDelta[0] >= 0) {
|
||||
if (item.x2 !== undefined) {
|
||||
if (this.startingMinX2 + gridDelta[0] >= 0) {
|
||||
item.x = startingX + gridDelta[0];
|
||||
}
|
||||
if (item.x2) {
|
||||
let itemX2InMarqueeSpace = item.x2 - marqueeStart.x;
|
||||
let itemX2InMarqueeSpaceAfterScale = Math.round(itemX2InMarqueeSpace * scaleWidth);
|
||||
item.x2 = itemX2InMarqueeSpaceAfterScale + marqueeOffset.x + marqueeStart.x;
|
||||
} else {
|
||||
item.width = Math.round(item.width * scaleWidth);
|
||||
}
|
||||
|
||||
if (item.y2) {
|
||||
let itemY2InMarqueeSpace = item.y2 - marqueeStart.y;
|
||||
let itemY2InMarqueeSpaceAfterScale = Math.round(itemY2InMarqueeSpace * scaleHeight);
|
||||
item.y2 = itemY2InMarqueeSpaceAfterScale + marqueeOffset.y + marqueeStart.y;
|
||||
} else {
|
||||
item.height = Math.round(item.height * scaleHeight);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.mutate("configuration.items", this.layoutItems);
|
||||
},
|
||||
move(gridDelta) {
|
||||
this.dragInProgress = true;
|
||||
|
||||
if (!this.initialPositions) {
|
||||
this.initialPositions = {};
|
||||
_.cloneDeep(this.selectedLayoutItems).forEach(selectedItem => {
|
||||
if (selectedItem.type === 'line-view') {
|
||||
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y, selectedItem.x2, selectedItem.y2];
|
||||
this.startingMinX2 = this.startingMinX2 !== undefined ? Math.min(this.startingMinX2, selectedItem.x2) : selectedItem.x2;
|
||||
this.startingMinY2 = this.startingMinY2 !== undefined ? Math.min(this.startingMinY2, selectedItem.y2) : selectedItem.y2;
|
||||
} else {
|
||||
this.initialPositions[selectedItem.id] = [selectedItem.x, selectedItem.y];
|
||||
}
|
||||
|
||||
this.startingMinX = this.startingMinX !== undefined ? Math.min(this.startingMinX, selectedItem.x) : selectedItem.x;
|
||||
this.startingMinY = this.startingMinY !== undefined ? Math.min(this.startingMinY, selectedItem.y) : selectedItem.y;
|
||||
});
|
||||
}
|
||||
|
||||
this.layoutItems.forEach(item => {
|
||||
if (this.initialPositions[item.id]) {
|
||||
this.updateItemPosition(item, gridDelta);
|
||||
}
|
||||
});
|
||||
},
|
||||
updateItemPosition(item, gridDelta) {
|
||||
let startingPosition = this.initialPositions[item.id];
|
||||
let [startingX, startingY, startingX2, startingY2] = startingPosition;
|
||||
|
||||
if (this.startingMinX + gridDelta[0] >= 0) {
|
||||
if (item.x2 !== undefined) {
|
||||
if (this.startingMinX2 + gridDelta[0] >= 0) {
|
||||
item.x = startingX + gridDelta[0];
|
||||
}
|
||||
} else {
|
||||
item.x = startingX + gridDelta[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.startingMinY + gridDelta[1] >= 0) {
|
||||
if (item.y2 !== undefined) {
|
||||
if (this.startingMinY2 + gridDelta[1] >= 0) {
|
||||
item.y = startingY + gridDelta[1];
|
||||
}
|
||||
} else {
|
||||
if (this.startingMinY + gridDelta[1] >= 0) {
|
||||
if (item.y2 !== undefined) {
|
||||
if (this.startingMinY2 + gridDelta[1] >= 0) {
|
||||
item.y = startingY + gridDelta[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (item.x2 !== undefined && this.startingMinX2 + gridDelta[0] >= 0 && this.startingMinX + gridDelta[0] >= 0) {
|
||||
item.x2 = startingX2 + gridDelta[0];
|
||||
}
|
||||
|
||||
if (item.y2 !== undefined && this.startingMinY2 + gridDelta[1] >= 0 && this.startingMinY + gridDelta[1] >= 0) {
|
||||
item.y2 = startingY2 + gridDelta[1];
|
||||
}
|
||||
},
|
||||
endMove() {
|
||||
this.mutate('configuration.items', this.layoutItems);
|
||||
this.initialPositions = undefined;
|
||||
this.startingMinX = undefined;
|
||||
this.startingMinY = undefined;
|
||||
this.startingMinX2 = undefined;
|
||||
this.startingMinY2 = undefined;
|
||||
},
|
||||
mutate(path, value) {
|
||||
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
||||
},
|
||||
handleDrop($event) {
|
||||
if (!$event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event.preventDefault();
|
||||
|
||||
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object-path'))[0];
|
||||
let elementRect = this.$el.getBoundingClientRect();
|
||||
let droppedObjectPosition = [
|
||||
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
|
||||
Math.floor(($event.pageY - elementRect.top) / this.gridSize[1])
|
||||
];
|
||||
|
||||
if (this.isTelemetry(domainObject)) {
|
||||
this.addItem('telemetry-view', domainObject, droppedObjectPosition);
|
||||
} else {
|
||||
let identifier = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
if (!this.objectViewMap[identifier]) {
|
||||
this.addItem('subobject-view', domainObject, droppedObjectPosition);
|
||||
} else {
|
||||
let prompt = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: "This item is already in layout and will not be added again.",
|
||||
buttons: [
|
||||
{
|
||||
label: 'OK',
|
||||
callback: function () {
|
||||
prompt.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
containsObject(identifier) {
|
||||
return _.get(this.internalDomainObject, 'composition')
|
||||
.some(childId => this.openmct.objects.areIdsEqual(childId, identifier));
|
||||
},
|
||||
handleDragOver($event) {
|
||||
// Get the ID of the dragged object
|
||||
let draggedKeyString = $event.dataTransfer.types
|
||||
.filter(type => type.startsWith(DRAG_OBJECT_TRANSFER_PREFIX))
|
||||
.map(type => type.substring(DRAG_OBJECT_TRANSFER_PREFIX.length))[0];
|
||||
|
||||
// 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)){
|
||||
$event.preventDefault();
|
||||
}
|
||||
},
|
||||
isTelemetry(domainObject) {
|
||||
if (this.openmct.telemetry.isTelemetryObject(domainObject) &&
|
||||
!this.options.showAsView.includes(domainObject.type)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
addItem(itemType, ...options) {
|
||||
let item = getItemDefinition(itemType, this.openmct, this.gridSize, ...options);
|
||||
item.type = itemType;
|
||||
item.id = uuid();
|
||||
this.trackItem(item);
|
||||
this.layoutItems.push(item);
|
||||
this.openmct.objects.mutate(this.internalDomainObject, "configuration.items", this.layoutItems);
|
||||
this.initSelectIndex = this.layoutItems.length - 1;
|
||||
},
|
||||
trackItem(item) {
|
||||
if (!item.identifier) {
|
||||
return;
|
||||
item.y = startingY + gridDelta[1];
|
||||
}
|
||||
}
|
||||
|
||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||
if (item.x2 !== undefined && this.startingMinX2 + gridDelta[0] >= 0 && this.startingMinX + gridDelta[0] >= 0) {
|
||||
item.x2 = startingX2 + gridDelta[0];
|
||||
}
|
||||
|
||||
if (item.type === "telemetry-view") {
|
||||
let count = this.telemetryViewMap[keyString] || 0;
|
||||
this.telemetryViewMap[keyString] = ++count;
|
||||
} else if (item.type === "subobject-view") {
|
||||
this.objectViewMap[keyString] = true;
|
||||
}
|
||||
},
|
||||
removeItem(selectedItems) {
|
||||
let indices = [];
|
||||
this.initSelectIndex = -1;
|
||||
selectedItems.forEach(selectedItem => {
|
||||
indices.push(selectedItem[0].context.index);
|
||||
this.untrackItem(selectedItem[0].context.layoutItem);
|
||||
});
|
||||
_.pullAt(this.layoutItems, indices);
|
||||
this.mutate("configuration.items", this.layoutItems);
|
||||
this.$el.click();
|
||||
},
|
||||
untrackItem(item) {
|
||||
if (!item.identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||
|
||||
if (item.type === 'telemetry-view') {
|
||||
let count = --this.telemetryViewMap[keyString];
|
||||
|
||||
if (count === 0) {
|
||||
delete this.telemetryViewMap[keyString];
|
||||
this.removeFromComposition(keyString);
|
||||
}
|
||||
} else if (item.type === 'subobject-view') {
|
||||
delete this.objectViewMap[keyString];
|
||||
this.removeFromComposition(keyString);
|
||||
}
|
||||
},
|
||||
removeFromComposition(keyString) {
|
||||
let composition = _.get(this.internalDomainObject, 'composition');
|
||||
composition = composition.filter(identifier => {
|
||||
return this.openmct.objects.makeKeyString(identifier) !== keyString;
|
||||
});
|
||||
this.mutate("composition", composition);
|
||||
},
|
||||
initializeItems() {
|
||||
this.telemetryViewMap = {};
|
||||
this.objectViewMap = {};
|
||||
this.layoutItems.forEach(this.trackItem);
|
||||
},
|
||||
addChild(child) {
|
||||
let identifier = this.openmct.objects.makeKeyString(child.identifier);
|
||||
if (this.isTelemetry(child)) {
|
||||
if (!this.telemetryViewMap[identifier]) {
|
||||
this.addItem('telemetry-view', child);
|
||||
}
|
||||
} else if (!this.objectViewMap[identifier]) {
|
||||
this.addItem('subobject-view', child);
|
||||
}
|
||||
},
|
||||
removeChild(identifier) {
|
||||
let keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
|
||||
if (this.objectViewMap[keyString]) {
|
||||
delete this.objectViewMap[keyString];
|
||||
this.removeFromConfiguration(keyString);
|
||||
} else if (this.telemetryViewMap[keyString]) {
|
||||
delete this.telemetryViewMap[keyString];
|
||||
this.removeFromConfiguration(keyString);
|
||||
}
|
||||
},
|
||||
removeFromConfiguration(keyString) {
|
||||
let layoutItems = this.layoutItems.filter(item => {
|
||||
if (!item.identifier) {
|
||||
return true;
|
||||
} else {
|
||||
return this.openmct.objects.makeKeyString(item.identifier) !== keyString;
|
||||
}
|
||||
});
|
||||
this.mutate("configuration.items", layoutItems);
|
||||
this.$el.click();
|
||||
},
|
||||
orderItem(position, selectedItems) {
|
||||
let delta = ORDERS[position];
|
||||
let indices = [];
|
||||
let newIndex = -1;
|
||||
let items = [];
|
||||
|
||||
Object.assign(items, this.layoutItems);
|
||||
this.selectedLayoutItems.forEach(selectedItem => {
|
||||
indices.push(this.layoutItems.indexOf(selectedItem));
|
||||
});
|
||||
indices.sort((a, b) => a - b);
|
||||
|
||||
if (position === 'top' || position === 'up') {
|
||||
indices.reverse();
|
||||
}
|
||||
|
||||
if (position === 'top' || position === 'bottom') {
|
||||
this.moveToTopOrBottom(position, indices, items, delta);
|
||||
} else {
|
||||
this.moveUpOrDown(position, indices, items, delta);
|
||||
}
|
||||
|
||||
this.mutate('configuration.items', this.layoutItems);
|
||||
},
|
||||
moveUpOrDown(position, indices, items, delta) {
|
||||
let previousItemIndex = -1;
|
||||
let newIndex = -1;
|
||||
|
||||
indices.forEach((itemIndex, index) => {
|
||||
let isAdjacentItemSelected = position === 'up' ?
|
||||
itemIndex + 1 === previousItemIndex :
|
||||
itemIndex - 1 === previousItemIndex;
|
||||
|
||||
if (index > 0 && isAdjacentItemSelected) {
|
||||
if (position === 'up') {
|
||||
newIndex -= 1;
|
||||
} else {
|
||||
newIndex += 1;
|
||||
}
|
||||
} else {
|
||||
newIndex = Math.max(Math.min(itemIndex + delta, this.layoutItems.length - 1), 0);
|
||||
}
|
||||
|
||||
previousItemIndex = itemIndex;
|
||||
this.updateItemOrder(newIndex, itemIndex, items);
|
||||
});
|
||||
},
|
||||
moveToTopOrBottom(position, indices, items, delta) {
|
||||
let newIndex = -1;
|
||||
|
||||
indices.forEach((itemIndex, index) => {
|
||||
if (index === 0) {
|
||||
newIndex = Math.max(Math.min(itemIndex + delta, this.layoutItems.length - 1), 0);
|
||||
} else {
|
||||
if (position === 'top') {
|
||||
newIndex -= 1;
|
||||
} else {
|
||||
newIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateItemOrder(newIndex, itemIndex, items);
|
||||
});
|
||||
},
|
||||
updateItemOrder(newIndex, itemIndex, items) {
|
||||
if (newIndex !== itemIndex) {
|
||||
this.layoutItems.splice(itemIndex, 1);
|
||||
this.layoutItems.splice(newIndex, 0, items[itemIndex]);
|
||||
}
|
||||
},
|
||||
updateTelemetryFormat(item, format) {
|
||||
let index = _.findIndex(this.layoutItems, item);
|
||||
item.format = format;
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
if (item.y2 !== undefined && this.startingMinY2 + gridDelta[1] >= 0 && this.startingMinY + gridDelta[1] >= 0) {
|
||||
item.y2 = startingY2 + gridDelta[1];
|
||||
}
|
||||
},
|
||||
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();
|
||||
endMove() {
|
||||
this.mutate('configuration.items', this.layoutItems);
|
||||
this.initialPositions = undefined;
|
||||
this.startingMinX = undefined;
|
||||
this.startingMinY = undefined;
|
||||
this.startingMinX2 = undefined;
|
||||
this.startingMinY2 = undefined;
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
this.composition.off('add', this.addChild);
|
||||
this.composition.off('remove', this.removeChild);
|
||||
this.unlisten();
|
||||
mutate(path, value) {
|
||||
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
||||
},
|
||||
handleDrop($event) {
|
||||
if (!$event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event.preventDefault();
|
||||
|
||||
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object-path'))[0];
|
||||
let elementRect = this.$el.getBoundingClientRect();
|
||||
let droppedObjectPosition = [
|
||||
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
|
||||
Math.floor(($event.pageY - elementRect.top) / this.gridSize[1])
|
||||
];
|
||||
|
||||
if (this.isTelemetry(domainObject)) {
|
||||
this.addItem('telemetry-view', domainObject, droppedObjectPosition);
|
||||
} else {
|
||||
let identifier = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
if (!this.objectViewMap[identifier]) {
|
||||
this.addItem('subobject-view', domainObject, droppedObjectPosition);
|
||||
} else {
|
||||
let prompt = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: "This item is already in layout and will not be added again.",
|
||||
buttons: [
|
||||
{
|
||||
label: 'OK',
|
||||
callback: function () {
|
||||
prompt.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
containsObject(identifier) {
|
||||
return _.get(this.internalDomainObject, 'composition')
|
||||
.some(childId => this.openmct.objects.areIdsEqual(childId, identifier));
|
||||
},
|
||||
handleDragOver($event) {
|
||||
// Get the ID of the dragged object
|
||||
let draggedKeyString = $event.dataTransfer.types
|
||||
.filter(type => type.startsWith(DRAG_OBJECT_TRANSFER_PREFIX))
|
||||
.map(type => type.substring(DRAG_OBJECT_TRANSFER_PREFIX.length))[0];
|
||||
|
||||
// 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)) {
|
||||
$event.preventDefault();
|
||||
}
|
||||
},
|
||||
isTelemetry(domainObject) {
|
||||
if (this.openmct.telemetry.isTelemetryObject(domainObject) &&
|
||||
!this.options.showAsView.includes(domainObject.type)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
addItem(itemType, ...options) {
|
||||
let item = getItemDefinition(itemType, this.openmct, this.gridSize, ...options);
|
||||
item.type = itemType;
|
||||
item.id = uuid();
|
||||
this.trackItem(item);
|
||||
this.layoutItems.push(item);
|
||||
this.openmct.objects.mutate(this.internalDomainObject, "configuration.items", this.layoutItems);
|
||||
this.initSelectIndex = this.layoutItems.length - 1;
|
||||
},
|
||||
trackItem(item) {
|
||||
if (!item.identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||
|
||||
if (item.type === "telemetry-view") {
|
||||
let count = this.telemetryViewMap[keyString] || 0;
|
||||
this.telemetryViewMap[keyString] = ++count;
|
||||
} else if (item.type === "subobject-view") {
|
||||
this.objectViewMap[keyString] = true;
|
||||
}
|
||||
},
|
||||
removeItem(selectedItems) {
|
||||
let indices = [];
|
||||
this.initSelectIndex = -1;
|
||||
selectedItems.forEach(selectedItem => {
|
||||
indices.push(selectedItem[0].context.index);
|
||||
this.untrackItem(selectedItem[0].context.layoutItem);
|
||||
});
|
||||
_.pullAt(this.layoutItems, indices);
|
||||
this.mutate("configuration.items", this.layoutItems);
|
||||
this.$el.click();
|
||||
},
|
||||
untrackItem(item) {
|
||||
if (!item.identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||
|
||||
if (item.type === 'telemetry-view') {
|
||||
let count = --this.telemetryViewMap[keyString];
|
||||
|
||||
if (count === 0) {
|
||||
delete this.telemetryViewMap[keyString];
|
||||
this.removeFromComposition(keyString);
|
||||
}
|
||||
} else if (item.type === 'subobject-view') {
|
||||
delete this.objectViewMap[keyString];
|
||||
this.removeFromComposition(keyString);
|
||||
}
|
||||
},
|
||||
removeFromComposition(keyString) {
|
||||
let composition = _.get(this.internalDomainObject, 'composition');
|
||||
composition = composition.filter(identifier => {
|
||||
return this.openmct.objects.makeKeyString(identifier) !== keyString;
|
||||
});
|
||||
this.mutate("composition", composition);
|
||||
},
|
||||
initializeItems() {
|
||||
this.telemetryViewMap = {};
|
||||
this.objectViewMap = {};
|
||||
this.layoutItems.forEach(this.trackItem);
|
||||
},
|
||||
addChild(child) {
|
||||
let identifier = this.openmct.objects.makeKeyString(child.identifier);
|
||||
if (this.isTelemetry(child)) {
|
||||
if (!this.telemetryViewMap[identifier]) {
|
||||
this.addItem('telemetry-view', child);
|
||||
}
|
||||
} else if (!this.objectViewMap[identifier]) {
|
||||
this.addItem('subobject-view', child);
|
||||
}
|
||||
},
|
||||
removeChild(identifier) {
|
||||
let keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
|
||||
if (this.objectViewMap[keyString]) {
|
||||
delete this.objectViewMap[keyString];
|
||||
this.removeFromConfiguration(keyString);
|
||||
} else if (this.telemetryViewMap[keyString]) {
|
||||
delete this.telemetryViewMap[keyString];
|
||||
this.removeFromConfiguration(keyString);
|
||||
}
|
||||
},
|
||||
removeFromConfiguration(keyString) {
|
||||
let layoutItems = this.layoutItems.filter(item => {
|
||||
if (!item.identifier) {
|
||||
return true;
|
||||
} else {
|
||||
return this.openmct.objects.makeKeyString(item.identifier) !== keyString;
|
||||
}
|
||||
});
|
||||
this.mutate("configuration.items", layoutItems);
|
||||
this.$el.click();
|
||||
},
|
||||
orderItem(position, selectedItems) {
|
||||
let delta = ORDERS[position];
|
||||
let indices = [];
|
||||
let items = [];
|
||||
|
||||
Object.assign(items, this.layoutItems);
|
||||
this.selectedLayoutItems.forEach(selectedItem => {
|
||||
indices.push(this.layoutItems.indexOf(selectedItem));
|
||||
});
|
||||
indices.sort((a, b) => a - b);
|
||||
|
||||
if (position === 'top' || position === 'up') {
|
||||
indices.reverse();
|
||||
}
|
||||
|
||||
if (position === 'top' || position === 'bottom') {
|
||||
this.moveToTopOrBottom(position, indices, items, delta);
|
||||
} else {
|
||||
this.moveUpOrDown(position, indices, items, delta);
|
||||
}
|
||||
|
||||
this.mutate('configuration.items', this.layoutItems);
|
||||
},
|
||||
moveUpOrDown(position, indices, items, delta) {
|
||||
let previousItemIndex = -1;
|
||||
let newIndex = -1;
|
||||
|
||||
indices.forEach((itemIndex, index) => {
|
||||
let isAdjacentItemSelected = position === 'up' ?
|
||||
itemIndex + 1 === previousItemIndex :
|
||||
itemIndex - 1 === previousItemIndex;
|
||||
|
||||
if (index > 0 && isAdjacentItemSelected) {
|
||||
if (position === 'up') {
|
||||
newIndex -= 1;
|
||||
} else {
|
||||
newIndex += 1;
|
||||
}
|
||||
} else {
|
||||
newIndex = Math.max(Math.min(itemIndex + delta, this.layoutItems.length - 1), 0);
|
||||
}
|
||||
|
||||
previousItemIndex = itemIndex;
|
||||
this.updateItemOrder(newIndex, itemIndex, items);
|
||||
});
|
||||
},
|
||||
moveToTopOrBottom(position, indices, items, delta) {
|
||||
let newIndex = -1;
|
||||
|
||||
indices.forEach((itemIndex, index) => {
|
||||
if (index === 0) {
|
||||
newIndex = Math.max(Math.min(itemIndex + delta, this.layoutItems.length - 1), 0);
|
||||
} else {
|
||||
if (position === 'top') {
|
||||
newIndex -= 1;
|
||||
} else {
|
||||
newIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateItemOrder(newIndex, itemIndex, items);
|
||||
});
|
||||
},
|
||||
updateItemOrder(newIndex, itemIndex, items) {
|
||||
if (newIndex !== itemIndex) {
|
||||
this.layoutItems.splice(itemIndex, 1);
|
||||
this.layoutItems.splice(newIndex, 0, items[itemIndex]);
|
||||
}
|
||||
},
|
||||
updateTelemetryFormat(item, format) {
|
||||
let index = _.findIndex(this.layoutItems, item);
|
||||
item.format = format;
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
</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,139 +106,146 @@
|
||||
|
||||
|
||||
<script>
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
selectedLayoutItems: Array,
|
||||
gridSize: Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dragPosition: undefined
|
||||
}
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
selectedLayoutItems: {
|
||||
type: Array,
|
||||
default: undefined
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let x = Number.POSITIVE_INFINITY;
|
||||
let y = Number.POSITIVE_INFINITY;
|
||||
let width = Number.NEGATIVE_INFINITY;
|
||||
let height = Number.NEGATIVE_INFINITY;
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dragPosition: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
marqueePosition() {
|
||||
let x = Number.POSITIVE_INFINITY;
|
||||
let y = Number.POSITIVE_INFINITY;
|
||||
let width = Number.NEGATIVE_INFINITY;
|
||||
let height = Number.NEGATIVE_INFINITY;
|
||||
|
||||
this.selectedLayoutItems.forEach(item => {
|
||||
if (item.x2 !== undefined) {
|
||||
let lineWidth = Math.abs(item.x - item.x2);
|
||||
let lineMinX = Math.min(item.x, item.x2);
|
||||
x = Math.min(lineMinX, x);
|
||||
width = Math.max(lineWidth + lineMinX, width);
|
||||
} else {
|
||||
x = Math.min(item.x, x);
|
||||
width = Math.max(item.width + item.x, width);
|
||||
}
|
||||
|
||||
if (item.y2 !== undefined) {
|
||||
let lineHeight = Math.abs(item.y - item.y2);
|
||||
let lineMinY = Math.min(item.y, item.y2);
|
||||
y = Math.min(lineMinY, y);
|
||||
height = Math.max(lineHeight + lineMinY, height);
|
||||
} else {
|
||||
y = Math.min(item.y, y);
|
||||
height = Math.max(item.height + item.y, height);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.dragPosition) {
|
||||
[x, y] = this.dragPosition.position;
|
||||
[width, height] = this.dragPosition.dimensions;
|
||||
this.selectedLayoutItems.forEach(item => {
|
||||
if (item.x2 !== undefined) {
|
||||
let lineWidth = Math.abs(item.x - item.x2);
|
||||
let lineMinX = Math.min(item.x, item.x2);
|
||||
x = Math.min(lineMinX, x);
|
||||
width = Math.max(lineWidth + lineMinX, width);
|
||||
} else {
|
||||
width = width - x;
|
||||
height = height - y;
|
||||
x = Math.min(item.x, x);
|
||||
width = Math.max(item.width + item.x, width);
|
||||
}
|
||||
|
||||
this.marqueePosition = {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height
|
||||
if (item.y2 !== undefined) {
|
||||
let lineHeight = Math.abs(item.y - item.y2);
|
||||
let lineMinY = Math.min(item.y, item.y2);
|
||||
y = Math.min(lineMinY, y);
|
||||
height = Math.max(lineHeight + lineMinY, height);
|
||||
} else {
|
||||
y = Math.min(item.y, y);
|
||||
height = Math.max(item.height + item.y, height);
|
||||
}
|
||||
return this.getMarqueeStyle(x, y, width, height);
|
||||
});
|
||||
|
||||
if (this.dragPosition) {
|
||||
[x, y] = this.dragPosition.position;
|
||||
[width, height] = this.dragPosition.dimensions;
|
||||
} else {
|
||||
width = width - x;
|
||||
height = height - y;
|
||||
}
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height
|
||||
}
|
||||
},
|
||||
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;
|
||||
this.delta = currentPosition.map(function (value, index) {
|
||||
return value - this.initialPosition[index];
|
||||
}.bind(this));
|
||||
},
|
||||
startResize(posFactor, dimFactor, event) {
|
||||
document.body.addEventListener('mousemove', this.continueResize);
|
||||
document.body.addEventListener('mouseup', this.endResize);
|
||||
this.marqueeStartPosition = {
|
||||
position: [this.marqueePosition.x, this.marqueePosition.y],
|
||||
dimensions: [this.marqueePosition.width, this.marqueePosition.height]
|
||||
};
|
||||
this.updatePosition(event);
|
||||
this.activeDrag = new LayoutDrag(this.marqueeStartPosition, posFactor, dimFactor, this.gridSize);
|
||||
event.preventDefault();
|
||||
},
|
||||
continueResize(event) {
|
||||
event.preventDefault();
|
||||
this.updatePosition(event);
|
||||
this.dragPosition = this.activeDrag.getAdjustedPositionAndDimensions(this.delta);
|
||||
},
|
||||
endResize(event) {
|
||||
document.body.removeEventListener('mousemove', this.continueResize);
|
||||
document.body.removeEventListener('mouseup', this.endResize);
|
||||
this.continueResize(event);
|
||||
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: {
|
||||
updatePosition(event) {
|
||||
let currentPosition = [event.pageX, event.pageY];
|
||||
this.initialPosition = this.initialPosition || currentPosition;
|
||||
this.delta = currentPosition.map(function (value, index) {
|
||||
return value - this.initialPosition[index];
|
||||
}.bind(this));
|
||||
},
|
||||
startResize(posFactor, dimFactor, event) {
|
||||
document.body.addEventListener('mousemove', this.continueResize);
|
||||
document.body.addEventListener('mouseup', this.endResize);
|
||||
this.marqueeStartPosition = {
|
||||
position: [this.marqueePosition.x, this.marqueePosition.y],
|
||||
dimensions: [this.marqueePosition.width, this.marqueePosition.height]
|
||||
};
|
||||
this.updatePosition(event);
|
||||
this.activeDrag = new LayoutDrag(this.marqueeStartPosition, posFactor, dimFactor, this.gridSize);
|
||||
event.preventDefault();
|
||||
},
|
||||
continueResize(event) {
|
||||
event.preventDefault();
|
||||
this.updatePosition(event);
|
||||
this.dragPosition = this.activeDrag.getAdjustedPositionAndDimensions(this.delta);
|
||||
},
|
||||
endResize(event) {
|
||||
document.body.removeEventListener('mousemove', this.continueResize);
|
||||
document.body.removeEventListener('mouseup', this.endResize);
|
||||
this.continueResize(event);
|
||||
|
||||
let marqueeStartWidth = this.marqueeStartPosition.dimensions[0];
|
||||
let marqueeStartHeight = this.marqueeStartPosition.dimensions[1];
|
||||
let marqueeStartX = this.marqueeStartPosition.position[0];
|
||||
let marqueeStartY = this.marqueeStartPosition.position[1];
|
||||
let marqueeStartWidth = this.marqueeStartPosition.dimensions[0];
|
||||
let marqueeStartHeight = this.marqueeStartPosition.dimensions[1];
|
||||
let marqueeStartX = this.marqueeStartPosition.position[0];
|
||||
let marqueeStartY = this.marqueeStartPosition.position[1];
|
||||
|
||||
let marqueeEndX = this.dragPosition.position[0];
|
||||
let marqueeEndY = this.dragPosition.position[1];
|
||||
let marqueeEndWidth = this.dragPosition.dimensions[0];
|
||||
let marqueeEndHeight = this.dragPosition.dimensions[1];
|
||||
let marqueeEndX = this.dragPosition.position[0];
|
||||
let marqueeEndY = this.dragPosition.position[1];
|
||||
let marqueeEndWidth = this.dragPosition.dimensions[0];
|
||||
let marqueeEndHeight = this.dragPosition.dimensions[1];
|
||||
|
||||
let scaleWidth = marqueeEndWidth / marqueeStartWidth;
|
||||
let scaleHeight = marqueeEndHeight / marqueeStartHeight;
|
||||
let scaleWidth = marqueeEndWidth / marqueeStartWidth;
|
||||
let scaleHeight = marqueeEndHeight / marqueeStartHeight;
|
||||
|
||||
let marqueeStart = {
|
||||
x: marqueeStartX,
|
||||
y: marqueeStartY,
|
||||
height: marqueeStartWidth,
|
||||
width: marqueeStartHeight
|
||||
};
|
||||
let marqueeEnd = {
|
||||
x: marqueeEndX,
|
||||
y: marqueeEndY,
|
||||
width: marqueeEndWidth,
|
||||
height: marqueeEndHeight
|
||||
};
|
||||
let marqueeOffset = {
|
||||
x: marqueeEnd.x - marqueeStart.x,
|
||||
y: marqueeEnd.y - marqueeStart.y
|
||||
};
|
||||
let marqueeStart = {
|
||||
x: marqueeStartX,
|
||||
y: marqueeStartY,
|
||||
height: marqueeStartWidth,
|
||||
width: marqueeStartHeight
|
||||
};
|
||||
let marqueeEnd = {
|
||||
x: marqueeEndX,
|
||||
y: marqueeEndY,
|
||||
width: marqueeEndWidth,
|
||||
height: marqueeEndHeight
|
||||
};
|
||||
let marqueeOffset = {
|
||||
x: marqueeEnd.x - marqueeStart.x,
|
||||
y: marqueeEnd.y - marqueeStart.y
|
||||
};
|
||||
|
||||
this.$emit('endResize', scaleWidth, scaleHeight, marqueeStart, marqueeOffset);
|
||||
this.dragPosition = undefined;
|
||||
this.initialPosition = undefined;
|
||||
this.marqueeStartPosition = undefined;
|
||||
this.delta = undefined;
|
||||
event.preventDefault();
|
||||
}
|
||||
this.$emit('endResize', scaleWidth, scaleHeight, marqueeStart, marqueeOffset);
|
||||
this.dragPosition = undefined;
|
||||
this.initialPosition = undefined;
|
||||
this.marqueeStartPosition = undefined;
|
||||
this.delta = undefined;
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,15 +21,18 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -46,59 +49,70 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
stroke: 'transparent',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
url: element.url
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
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 {
|
||||
stroke: 'transparent',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
url: element.url
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
index: Number,
|
||||
initSelect: Boolean
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
backgroundImage: 'url(' + this.item.url + ')',
|
||||
border: '1px solid ' + this.item.stroke
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
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();
|
||||
backgroundImage: 'url(' + this.item.url + ')',
|
||||
border: '1px solid ' + this.item.stroke
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
|
@ -21,19 +21,21 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout__frame c-frame"
|
||||
:class="{
|
||||
'no-frame': !item.hasFrame,
|
||||
'u-inspectable': inspectable
|
||||
}"
|
||||
:style="style">
|
||||
<div
|
||||
class="l-layout__frame c-frame"
|
||||
:class="{
|
||||
'no-frame': !item.hasFrame,
|
||||
'u-inspectable': inspectable
|
||||
}"
|
||||
:style="style"
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
<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,73 +175,81 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let {x, y, width, height} = this.item;
|
||||
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',
|
||||
minWidth: (this.gridSize[0] * width) + 'px',
|
||||
minHeight: (this.gridSize[1] * height) + 'px'
|
||||
};
|
||||
},
|
||||
inspectable() {
|
||||
return this.item.type === 'subobject-view' || this.item.type === 'telemetry-view';
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let {x, y, width, height} = this.item;
|
||||
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',
|
||||
minWidth: (this.gridSize[0] * width) + 'px',
|
||||
minHeight: (this.gridSize[1] * height) + 'px'
|
||||
};
|
||||
},
|
||||
inspectable() {
|
||||
return this.item.type === 'subobject-view' || this.item.type === 'telemetry-view';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updatePosition(event) {
|
||||
let currentPosition = [event.pageX, event.pageY];
|
||||
this.initialPosition = this.initialPosition || currentPosition;
|
||||
this.delta = currentPosition.map(function (value, index) {
|
||||
return value - this.initialPosition[index];
|
||||
}.bind(this));
|
||||
},
|
||||
startMove(posFactor, dimFactor, event) {
|
||||
document.body.addEventListener('mousemove', this.continueMove);
|
||||
document.body.addEventListener('mouseup', this.endMove);
|
||||
this.dragPosition = {
|
||||
position: [this.item.x, this.item.y]
|
||||
};
|
||||
this.updatePosition(event);
|
||||
this.activeDrag = new LayoutDrag(this.dragPosition, posFactor, dimFactor, this.gridSize);
|
||||
event.preventDefault();
|
||||
},
|
||||
continueMove(event) {
|
||||
event.preventDefault();
|
||||
this.updatePosition(event);
|
||||
let newPosition = this.activeDrag.getAdjustedPosition(this.delta);
|
||||
|
||||
if (!_.isEqual(newPosition, this.dragPosition)) {
|
||||
this.dragPosition = newPosition;
|
||||
this.$emit('move', this.toGridDelta(this.delta));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updatePosition(event) {
|
||||
let currentPosition = [event.pageX, event.pageY];
|
||||
this.initialPosition = this.initialPosition || currentPosition;
|
||||
this.delta = currentPosition.map(function (value, index) {
|
||||
return value - this.initialPosition[index];
|
||||
}.bind(this));
|
||||
},
|
||||
startMove(posFactor, dimFactor, event) {
|
||||
document.body.addEventListener('mousemove', this.continueMove);
|
||||
document.body.addEventListener('mouseup', this.endMove);
|
||||
this.dragPosition = {
|
||||
position: [this.item.x, this.item.y]
|
||||
};
|
||||
this.updatePosition(event);
|
||||
this.activeDrag = new LayoutDrag(this.dragPosition, posFactor, dimFactor, this.gridSize);
|
||||
event.preventDefault();
|
||||
},
|
||||
continueMove(event) {
|
||||
event.preventDefault();
|
||||
this.updatePosition(event);
|
||||
let newPosition = this.activeDrag.getAdjustedPosition(this.delta);
|
||||
|
||||
if (!_.isEqual(newPosition, this.dragPosition)) {
|
||||
this.dragPosition = newPosition;
|
||||
this.$emit('move', this.toGridDelta(this.delta));
|
||||
}
|
||||
},
|
||||
endMove(event) {
|
||||
document.body.removeEventListener('mousemove', this.continueMove);
|
||||
document.body.removeEventListener('mouseup', this.endMove);
|
||||
this.continueMove(event);
|
||||
this.$emit('endMove');
|
||||
this.dragPosition = undefined;
|
||||
this.initialPosition = undefined;
|
||||
this.delta = undefined;
|
||||
event.preventDefault();
|
||||
},
|
||||
toGridDelta(pixelDelta) {
|
||||
return pixelDelta.map((v, i) => {
|
||||
return Math.round(v / this.gridSize[i]);
|
||||
});
|
||||
}
|
||||
endMove(event) {
|
||||
document.body.removeEventListener('mousemove', this.continueMove);
|
||||
document.body.removeEventListener('mouseup', this.endMove);
|
||||
this.continueMove(event);
|
||||
this.$emit('endMove');
|
||||
this.dragPosition = undefined;
|
||||
this.initialPosition = undefined;
|
||||
this.delta = undefined;
|
||||
event.preventDefault();
|
||||
},
|
||||
toGridDelta(pixelDelta) {
|
||||
return pixelDelta.map((v, i) => {
|
||||
return Math.round(v / this.gridSize[i]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -21,244 +21,253 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<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>
|
||||
</svg>
|
||||
<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"
|
||||
/>
|
||||
</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"
|
||||
:class="startHandleClass"
|
||||
@mousedown="startDrag($event, 'start')"></div>
|
||||
<div class="c-frame-edit__handle"
|
||||
:class="endHandleClass"
|
||||
@mousedown="startDrag($event, 'end')"></div>
|
||||
</div>
|
||||
<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"
|
||||
:class="endHandleClass"
|
||||
@mousedown="startDrag($event, 'end')"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
|
||||
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 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 = {
|
||||
1: 'c-frame-edit__handle--ne',
|
||||
2: 'c-frame-edit__handle--nw',
|
||||
3: 'c-frame-edit__handle--sw',
|
||||
4: 'c-frame-edit__handle--se'
|
||||
};
|
||||
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 {
|
||||
makeDefinition() {
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
x: 5,
|
||||
y: 10,
|
||||
x2: 10,
|
||||
y2: 5,
|
||||
stroke: '#717171'
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
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
|
||||
},
|
||||
multiSelect: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dragPosition: undefined,
|
||||
dragging: undefined,
|
||||
selection: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
showFrameEdit() {
|
||||
let layoutItem = this.selection.length > 0 && this.selection[0][0].context.layoutItem;
|
||||
return !this.multiSelect && layoutItem && layoutItem.id === this.item.id;
|
||||
},
|
||||
position() {
|
||||
let {x, y, x2, y2} = this.item;
|
||||
if (this.dragging && this.dragPosition) {
|
||||
({x, y, x2, y2} = this.dragPosition);
|
||||
}
|
||||
return {x, y, x2, y2};
|
||||
},
|
||||
style() {
|
||||
let {x, y, x2, y2} = this.position;
|
||||
let width = Math.max(this.gridSize[0] * Math.abs(x - x2), 1);
|
||||
let height = Math.max(this.gridSize[1] * Math.abs(y - y2), 1);
|
||||
let left = this.gridSize[0] * Math.min(x, x2);
|
||||
let top = this.gridSize[1] * Math.min(y, y2);
|
||||
return {
|
||||
x: 5,
|
||||
y: 10,
|
||||
x2: 10,
|
||||
y2: 5,
|
||||
stroke: '#717171'
|
||||
left: `${left}px`,
|
||||
top: `${top}px`,
|
||||
width: `${width}px`,
|
||||
height: `${height}px`
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
initSelect: Boolean,
|
||||
index: Number,
|
||||
multiSelect: Boolean
|
||||
startHandleClass() {
|
||||
return START_HANDLE_QUADRANTS[this.vectorQuadrant];
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dragPosition: undefined,
|
||||
dragging: undefined,
|
||||
selection: []
|
||||
};
|
||||
endHandleClass() {
|
||||
return END_HANDLE_QUADRANTS[this.vectorQuadrant];
|
||||
},
|
||||
computed: {
|
||||
showFrameEdit() {
|
||||
let layoutItem = this.selection.length > 0 && this.selection[0][0].context.layoutItem;
|
||||
return !this.multiSelect && layoutItem && layoutItem.id === this.item.id;
|
||||
},
|
||||
position() {
|
||||
let {x, y, x2, y2} = this.item;
|
||||
if (this.dragging && this.dragPosition) {
|
||||
({x, y, x2, y2} = this.dragPosition);
|
||||
}
|
||||
return {x, y, x2, y2};
|
||||
},
|
||||
style() {
|
||||
let {x, y, x2, y2} = this.position;
|
||||
let width = Math.max(this.gridSize[0] * Math.abs(x - x2), 1);
|
||||
let height = Math.max(this.gridSize[1] * Math.abs(y - y2), 1);
|
||||
let left = this.gridSize[0] * Math.min(x, x2);
|
||||
let top = this.gridSize[1] * Math.min(y, y2);
|
||||
return {
|
||||
left: `${left}px`,
|
||||
top: `${top}px`,
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
};
|
||||
},
|
||||
startHandleClass() {
|
||||
return START_HANDLE_QUADRANTS[this.vectorQuadrant];
|
||||
},
|
||||
endHandleClass() {
|
||||
return END_HANDLE_QUADRANTS[this.vectorQuadrant];
|
||||
},
|
||||
vectorQuadrant() {
|
||||
let {x, y, x2, y2} = this.position;
|
||||
if (x2 > x) {
|
||||
if (y2 < y) {
|
||||
return 1;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
vectorQuadrant() {
|
||||
let {x, y, x2, y2} = this.position;
|
||||
if (x2 > x) {
|
||||
if (y2 < y) {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
},
|
||||
linePosition() {
|
||||
if (this.vectorQuadrant === 1) {
|
||||
return {
|
||||
x1: '0%',
|
||||
y1: '100%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
};
|
||||
}
|
||||
if (this.vectorQuadrant === 4) {
|
||||
return {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
};
|
||||
}
|
||||
if (this.vectorQuadrant === 2) {
|
||||
return {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
};
|
||||
}
|
||||
if (this.vectorQuadrant === 3) {
|
||||
return {
|
||||
x1: '100%',
|
||||
y1: '0%',
|
||||
x2: '0%',
|
||||
y2: '100%'
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
if (y2 < y) {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
},
|
||||
methods: {
|
||||
startDrag(event, position) {
|
||||
this.dragging = position;
|
||||
document.body.addEventListener('mousemove', this.continueDrag);
|
||||
document.body.addEventListener('mouseup', this.endDrag);
|
||||
this.startPosition = [event.pageX, event.pageY];
|
||||
this.dragPosition = {
|
||||
x: this.item.x,
|
||||
y: this.item.y,
|
||||
x2: this.item.x2,
|
||||
y2: this.item.y2
|
||||
linePosition() {
|
||||
return this.vectorQuadrant % 2 !== 0
|
||||
// odd vectorQuadrant slopes up
|
||||
? {
|
||||
x1: '0%',
|
||||
y1: '100%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
}
|
||||
// even vectorQuadrant slopes down
|
||||
: {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
};
|
||||
event.preventDefault();
|
||||
},
|
||||
continueDrag(event) {
|
||||
event.preventDefault();
|
||||
let pxDeltaX = this.startPosition[0] - event.pageX;
|
||||
let pxDeltaY = this.startPosition[1] - event.pageY;
|
||||
let newPosition = this.calculateDragPosition(pxDeltaX, pxDeltaY);
|
||||
|
||||
if (!this.dragging) {
|
||||
if (!_.isEqual(newPosition, this.dragPosition)) {
|
||||
let gridDelta = [event.pageX - this.startPosition[0], event.pageY - this.startPosition[1]];
|
||||
this.dragPosition = newPosition;
|
||||
this.$emit('move', this.toGridDelta(gridDelta));
|
||||
}
|
||||
} else {
|
||||
this.dragPosition = newPosition;
|
||||
}
|
||||
},
|
||||
endDrag(event) {
|
||||
document.body.removeEventListener('mousemove', this.continueDrag);
|
||||
document.body.removeEventListener('mouseup', this.endDrag);
|
||||
let {x, y, x2, y2} = this.dragPosition;
|
||||
if (!this.dragging) {
|
||||
this.$emit('endMove');
|
||||
} else {
|
||||
this.$emit('endLineResize', this.item, {x, y, x2, y2});
|
||||
}
|
||||
this.dragPosition = undefined;
|
||||
this.dragging = undefined;
|
||||
event.preventDefault();
|
||||
},
|
||||
calculateDragPosition(pxDeltaX, pxDeltaY) {
|
||||
let gridDeltaX = Math.round(pxDeltaX / this.gridSize[0]);
|
||||
let gridDeltaY = Math.round(pxDeltaY / this.gridSize[0]); // TODO: should this be gridSize[1]?
|
||||
let {x, y, x2, y2} = this.item;
|
||||
let dragPosition = {x, y, x2, y2};
|
||||
|
||||
if (this.dragging === 'start') {
|
||||
dragPosition.x -= gridDeltaX;
|
||||
dragPosition.y -= gridDeltaY;
|
||||
} else if (this.dragging === 'end') {
|
||||
dragPosition.x2 -= gridDeltaX;
|
||||
dragPosition.y2 -= gridDeltaY;
|
||||
} else {
|
||||
// dragging entire line.
|
||||
dragPosition.x -= gridDeltaX;
|
||||
dragPosition.y -= gridDeltaY;
|
||||
dragPosition.x2 -= gridDeltaX;
|
||||
dragPosition.y2 -= gridDeltaY;
|
||||
}
|
||||
return dragPosition;
|
||||
},
|
||||
setSelection(selection) {
|
||||
this.selection = selection;
|
||||
},
|
||||
toGridDelta(pixelDelta) {
|
||||
return pixelDelta.map((v, i) => {
|
||||
return Math.round(v / this.gridSize[i]);
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
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.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);
|
||||
},
|
||||
methods: {
|
||||
startDrag(event, position) {
|
||||
this.dragging = position;
|
||||
document.body.addEventListener('mousemove', this.continueDrag);
|
||||
document.body.addEventListener('mouseup', this.endDrag);
|
||||
this.startPosition = [event.pageX, event.pageY];
|
||||
this.dragPosition = {
|
||||
x: this.item.x,
|
||||
y: this.item.y,
|
||||
x2: this.item.x2,
|
||||
y2: this.item.y2
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
event.preventDefault();
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
continueDrag(event) {
|
||||
event.preventDefault();
|
||||
let pxDeltaX = this.startPosition[0] - event.pageX;
|
||||
let pxDeltaY = this.startPosition[1] - event.pageY;
|
||||
let newPosition = this.calculateDragPosition(pxDeltaX, pxDeltaY);
|
||||
|
||||
if (!this.dragging) {
|
||||
if (!_.isEqual(newPosition, this.dragPosition)) {
|
||||
let gridDelta = [event.pageX - this.startPosition[0], event.pageY - this.startPosition[1]];
|
||||
this.dragPosition = newPosition;
|
||||
this.$emit('move', this.toGridDelta(gridDelta));
|
||||
}
|
||||
} else {
|
||||
this.dragPosition = newPosition;
|
||||
}
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
},
|
||||
endDrag(event) {
|
||||
document.body.removeEventListener('mousemove', this.continueDrag);
|
||||
document.body.removeEventListener('mouseup', this.endDrag);
|
||||
let {x, y, x2, y2} = this.dragPosition;
|
||||
if (!this.dragging) {
|
||||
this.$emit('endMove');
|
||||
} else {
|
||||
this.$emit('endLineResize', this.item, {x, y, x2, y2});
|
||||
}
|
||||
this.dragPosition = undefined;
|
||||
this.dragging = undefined;
|
||||
event.preventDefault();
|
||||
},
|
||||
calculateDragPosition(pxDeltaX, pxDeltaY) {
|
||||
let gridDeltaX = Math.round(pxDeltaX / this.gridSize[0]);
|
||||
let gridDeltaY = Math.round(pxDeltaY / this.gridSize[0]); // TODO: should this be gridSize[1]?
|
||||
let {x, y, x2, y2} = this.item;
|
||||
let dragPosition = {x, y, x2, y2};
|
||||
|
||||
if (this.dragging === 'start') {
|
||||
dragPosition.x -= gridDeltaX;
|
||||
dragPosition.y -= gridDeltaY;
|
||||
} else if (this.dragging === 'end') {
|
||||
dragPosition.x2 -= gridDeltaX;
|
||||
dragPosition.y2 -= gridDeltaY;
|
||||
} else {
|
||||
// dragging entire line.
|
||||
dragPosition.x -= gridDeltaX;
|
||||
dragPosition.y -= gridDeltaY;
|
||||
dragPosition.x2 -= gridDeltaX;
|
||||
dragPosition.y2 -= gridDeltaY;
|
||||
}
|
||||
return dragPosition;
|
||||
},
|
||||
setSelection(selection) {
|
||||
this.selection = selection;
|
||||
},
|
||||
toGridDelta(pixelDelta) {
|
||||
return pixelDelta.map((v, i) => {
|
||||
return Math.round(v / this.gridSize[i]);
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
|
@ -20,106 +20,120 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
:grid-size="gridSize"
|
||||
:title="domainObject && domainObject.name"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<object-frame v-if="domainObject"
|
||||
:domain-object="domainObject"
|
||||
:object-path="currentObjectPath"
|
||||
:has-frame="item.hasFrame"
|
||||
:show-edit-view="false"
|
||||
ref="objectFrame">
|
||||
</object-frame>
|
||||
</layout-frame>
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:title="domainObject && domainObject.name"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<object-frame
|
||||
v-if="domainObject"
|
||||
ref="objectFrame"
|
||||
:domain-object="domainObject"
|
||||
:object-path="currentObjectPath"
|
||||
:has-frame="item.hasFrame"
|
||||
:show-edit-view="false"
|
||||
/>
|
||||
</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],
|
||||
DEFAULT_DIMENSIONS = [10, 10],
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
DEFAULT_HIDDEN_FRAME_TYPES = ['hyperlink', 'summary-widget'];
|
||||
const MINIMUM_FRAME_SIZE = [320, 180],
|
||||
DEFAULT_DIMENSIONS = [10, 10],
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
DEFAULT_HIDDEN_FRAME_TYPES = ['hyperlink', 'summary-widget'];
|
||||
|
||||
function getDefaultDimensions(gridSize) {
|
||||
return MINIMUM_FRAME_SIZE.map((min, index) => {
|
||||
return Math.max(
|
||||
Math.ceil(min / gridSize[index]),
|
||||
DEFAULT_DIMENSIONS[index]
|
||||
);
|
||||
});
|
||||
}
|
||||
function getDefaultDimensions(gridSize) {
|
||||
return MINIMUM_FRAME_SIZE.map((min, index) => {
|
||||
return Math.max(
|
||||
Math.ceil(min / gridSize[index]),
|
||||
DEFAULT_DIMENSIONS[index]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function hasFrameByDefault(type) {
|
||||
return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
|
||||
}
|
||||
function hasFrameByDefault(type) {
|
||||
return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
|
||||
}
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let defaultDimensions = getDefaultDimensions(gridSize);
|
||||
position = position || DEFAULT_POSITION;
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let defaultDimensions = getDefaultDimensions(gridSize);
|
||||
position = position || DEFAULT_POSITION;
|
||||
|
||||
return {
|
||||
width: defaultDimensions[0],
|
||||
height: defaultDimensions[1],
|
||||
x: position[0],
|
||||
y: position[1],
|
||||
identifier: domainObject.identifier,
|
||||
hasFrame: hasFrameByDefault(domainObject.type)
|
||||
};
|
||||
return {
|
||||
width: defaultDimensions[0],
|
||||
height: defaultDimensions[1],
|
||||
x: position[0],
|
||||
y: position[1],
|
||||
identifier: domainObject.identifier,
|
||||
hasFrame: hasFrameByDefault(domainObject.type)
|
||||
};
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
components: {
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
initSelect: Boolean,
|
||||
index: Number
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
currentObjectPath: []
|
||||
initSelect: Boolean,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
currentObjectPath: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.currentObjectPath = [this.domainObject].concat(this.objectPath.slice());
|
||||
this.$nextTick(function () {
|
||||
let childContext = this.$refs.objectFrame.getSelectionContext();
|
||||
childContext.item = domainObject;
|
||||
childContext.layoutItem = this.item;
|
||||
childContext.index = this.index;
|
||||
this.context = childContext;
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
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;
|
||||
this.currentObjectPath = [this.domainObject].concat(this.objectPath.slice());
|
||||
this.$nextTick(function () {
|
||||
let childContext = this.$refs.objectFrame.getSelectionContext();
|
||||
childContext.item = domainObject;
|
||||
childContext.layoutItem = this.item;
|
||||
childContext.index = this.index;
|
||||
this.context = childContext;
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -20,29 +20,41 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-telemetry-view"
|
||||
:style="styleObject"
|
||||
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>
|
||||
</div>
|
||||
|
||||
<div v-if="showValue"
|
||||
:title="fieldName"
|
||||
class="c-telemetry-view__value"
|
||||
:class="[telemetryClass]">
|
||||
<div class="c-telemetry-view__value-text">{{ telemetryValue }}</div>
|
||||
<template>
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
v-if="domainObject"
|
||||
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>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-if="showValue"
|
||||
:title="fieldName"
|
||||
class="c-telemetry-view__value"
|
||||
:class="[telemetryClass]"
|
||||
>
|
||||
<div class="c-telemetry-view__value-text">
|
||||
{{ telemetryValue }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -78,189 +90,200 @@
|
||||
}
|
||||
</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],
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
CONTEXT_MENU_ACTIONS = ['viewHistoricalData'];
|
||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
CONTEXT_MENU_ACTIONS = ['viewHistoricalData'];
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||
position = position || DEFAULT_POSITION;
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||
position = position || DEFAULT_POSITION;
|
||||
|
||||
return {
|
||||
identifier: domainObject.identifier,
|
||||
x: position[0],
|
||||
y: position[1],
|
||||
width: DEFAULT_TELEMETRY_DIMENSIONS[0],
|
||||
height: DEFAULT_TELEMETRY_DIMENSIONS[1],
|
||||
displayMode: 'all',
|
||||
value: metadata.getDefaultDisplayValue(),
|
||||
stroke: "transparent",
|
||||
fill: "transparent",
|
||||
color: "",
|
||||
size: "13px"
|
||||
};
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
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;
|
||||
return displayMode === 'all' || displayMode === 'label';
|
||||
},
|
||||
showValue() {
|
||||
let displayMode = this.item.displayMode;
|
||||
return displayMode === 'all' || displayMode === 'value';
|
||||
},
|
||||
styleObject() {
|
||||
return {
|
||||
identifier: domainObject.identifier,
|
||||
x: position[0],
|
||||
y: position[1],
|
||||
width: DEFAULT_TELEMETRY_DIMENSIONS[0],
|
||||
height: DEFAULT_TELEMETRY_DIMENSIONS[1],
|
||||
displayMode: 'all',
|
||||
value: metadata.getDefaultDisplayValue(),
|
||||
stroke: "transparent",
|
||||
fill: "transparent",
|
||||
color: "",
|
||||
size: "13px"
|
||||
backgroundColor: this.item.fill,
|
||||
borderColor: this.item.stroke,
|
||||
color: this.item.color,
|
||||
fontSize: this.item.size
|
||||
}
|
||||
},
|
||||
fieldName() {
|
||||
return this.valueMetadata && this.valueMetadata.name;
|
||||
},
|
||||
valueMetadata() {
|
||||
return this.datum && this.metadata.value(this.item.value);
|
||||
},
|
||||
valueFormatter() {
|
||||
return this.formats[this.item.value];
|
||||
},
|
||||
telemetryValue() {
|
||||
if (!this.datum) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.item.format) {
|
||||
return printj.sprintf(this.item.format, this.datum[this.valueMetadata.key]);
|
||||
}
|
||||
|
||||
return this.valueFormatter && this.valueFormatter.format(this.datum);
|
||||
},
|
||||
telemetryClass() {
|
||||
if (!this.datum) {
|
||||
return;
|
||||
}
|
||||
|
||||
let alarm = this.limitEvaluator && this.limitEvaluator.evaluate(this.datum, this.valueMetadata);
|
||||
return alarm && alarm.cssClass;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
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();
|
||||
let options = {
|
||||
start: bounds.start,
|
||||
end: bounds.end,
|
||||
size: 1,
|
||||
strategy: 'latest'
|
||||
};
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
initSelect: Boolean,
|
||||
index: Number
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
computed: {
|
||||
showLabel() {
|
||||
let displayMode = this.item.displayMode;
|
||||
return displayMode === 'all' || displayMode === 'label';
|
||||
},
|
||||
showValue() {
|
||||
let displayMode = this.item.displayMode;
|
||||
return displayMode === 'all' || displayMode === 'value';
|
||||
},
|
||||
styleObject() {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
borderColor: this.item.stroke,
|
||||
color: this.item.color,
|
||||
fontSize: this.item.size
|
||||
}
|
||||
},
|
||||
fieldName() {
|
||||
return this.valueMetadata && this.valueMetadata.name;
|
||||
},
|
||||
valueMetadata() {
|
||||
return this.datum && this.metadata.value(this.item.value);
|
||||
},
|
||||
valueFormatter() {
|
||||
return this.formats[this.item.value];
|
||||
},
|
||||
telemetryValue() {
|
||||
if (!this.datum) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.item.format) {
|
||||
return printj.sprintf(this.item.format, this.datum[this.valueMetadata.key]);
|
||||
}
|
||||
|
||||
return this.valueFormatter && this.valueFormatter.format(this.datum);
|
||||
},
|
||||
telemetryClass() {
|
||||
if (!this.datum) {
|
||||
return;
|
||||
}
|
||||
|
||||
let alarm = this.limitEvaluator && this.limitEvaluator.evaluate(this.datum, this.valueMetadata);
|
||||
return alarm && alarm.cssClass;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
datum: undefined,
|
||||
formats: undefined,
|
||||
domainObject: undefined,
|
||||
currentObjectPath: undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
requestHistoricalData() {
|
||||
let bounds = this.openmct.time.bounds();
|
||||
let options = {
|
||||
start: bounds.start,
|
||||
end: bounds.end,
|
||||
size: 1,
|
||||
strategy: 'latest'
|
||||
};
|
||||
this.openmct.telemetry.request(this.domainObject, options)
|
||||
.then(data => {
|
||||
if (data.length > 0) {
|
||||
this.updateView(data[data.length - 1]);
|
||||
}
|
||||
});
|
||||
},
|
||||
subscribeToObject() {
|
||||
this.subscription = this.openmct.telemetry.subscribe(this.domainObject, function (datum) {
|
||||
if (this.openmct.time.clock() !== undefined) {
|
||||
this.updateView(datum);
|
||||
this.openmct.telemetry.request(this.domainObject, options)
|
||||
.then(data => {
|
||||
if (data.length > 0) {
|
||||
this.updateView(data[data.length - 1]);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
updateView(datum) {
|
||||
this.datum = datum;
|
||||
},
|
||||
removeSubscription() {
|
||||
if (this.subscription) {
|
||||
this.subscription();
|
||||
this.subscription = undefined;
|
||||
});
|
||||
},
|
||||
subscribeToObject() {
|
||||
this.subscription = this.openmct.telemetry.subscribe(this.domainObject, function (datum) {
|
||||
if (this.openmct.time.clock() !== undefined) {
|
||||
this.updateView(datum);
|
||||
}
|
||||
},
|
||||
refreshData(bounds, isTick) {
|
||||
if (!isTick) {
|
||||
this.datum = undefined;
|
||||
this.requestHistoricalData(this.domainObject);
|
||||
}
|
||||
},
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
this.requestHistoricalData();
|
||||
this.subscribeToObject();
|
||||
|
||||
this.currentObjectPath = this.objectPath.slice();
|
||||
this.currentObjectPath.unshift(this.domainObject);
|
||||
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index,
|
||||
updateTelemetryFormat: this.updateTelemetryFormat
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
updateTelemetryFormat(format) {
|
||||
this.$emit('formatChanged', this.item, format);
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}.bind(this));
|
||||
},
|
||||
updateView(datum) {
|
||||
this.datum = datum;
|
||||
},
|
||||
removeSubscription() {
|
||||
if (this.subscription) {
|
||||
this.subscription();
|
||||
this.subscription = undefined;
|
||||
}
|
||||
},
|
||||
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();
|
||||
refreshData(bounds, isTick) {
|
||||
if (!isTick) {
|
||||
this.datum = undefined;
|
||||
this.requestHistoricalData(this.domainObject);
|
||||
}
|
||||
},
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
this.requestHistoricalData();
|
||||
this.subscribeToObject();
|
||||
|
||||
this.openmct.time.off("bounds", this.refreshData);
|
||||
this.currentObjectPath = this.objectPath.slice();
|
||||
this.currentObjectPath.unshift(this.domainObject);
|
||||
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index,
|
||||
updateTelemetryFormat: this.updateTelemetryFormat
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
updateTelemetryFormat(format) {
|
||||
this.$emit('formatChanged', this.item, format);
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
@ -20,17 +20,21 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<layout-frame :item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-text-view"
|
||||
:style="style">
|
||||
{{ item.text }}
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
<template>
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
class="c-text-view"
|
||||
:style="style"
|
||||
>
|
||||
{{ item.text }}
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~styles/sass-base';
|
||||
@ -46,65 +50,75 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
fill: 'transparent',
|
||||
stroke: 'transparent',
|
||||
size: '13px',
|
||||
color: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
text: element.text
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
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 {
|
||||
fill: 'transparent',
|
||||
stroke: 'transparent',
|
||||
size: '13px',
|
||||
color: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
text: element.text
|
||||
backgroundColor: this.item.fill,
|
||||
borderColor: this.item.stroke,
|
||||
color: this.item.color,
|
||||
fontSize: this.item.size
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
index: Number,
|
||||
initSelect: Boolean
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
borderColor: this.item.stroke,
|
||||
color: this.item.color,
|
||||
fontSize: this.item.size
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
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.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
}
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user