mirror of
https://github.com/nasa/openmct.git
synced 2025-06-15 05:38:12 +00:00
chore: add prettier
(2/3): apply formatting, re-enable lint ci step (#6682)
* style: apply prettier formatting * fix: re-enable lint ci check
This commit is contained in:
@ -25,74 +25,76 @@ import AlphanumericFormat from './components/AlphanumericFormat.vue';
|
||||
import Vue from 'vue';
|
||||
|
||||
class AlphanumericFormatView {
|
||||
constructor(openmct, domainObject, objectPath) {
|
||||
this.openmct = openmct;
|
||||
this.domainObject = domainObject;
|
||||
this.objectPath = objectPath;
|
||||
this.component = undefined;
|
||||
constructor(openmct, domainObject, objectPath) {
|
||||
this.openmct = openmct;
|
||||
this.domainObject = domainObject;
|
||||
this.objectPath = objectPath;
|
||||
this.component = undefined;
|
||||
}
|
||||
|
||||
show(element) {
|
||||
this.component = new Vue({
|
||||
el: element,
|
||||
name: 'AlphanumericFormat',
|
||||
components: {
|
||||
AlphanumericFormat
|
||||
},
|
||||
provide: {
|
||||
openmct: this.openmct,
|
||||
objectPath: this.objectPath,
|
||||
currentView: this
|
||||
},
|
||||
template: '<alphanumeric-format ref="alphanumericFormat"></alphanumeric-format>'
|
||||
});
|
||||
}
|
||||
|
||||
getViewContext() {
|
||||
if (this.component) {
|
||||
return {};
|
||||
}
|
||||
|
||||
show(element) {
|
||||
this.component = new Vue({
|
||||
el: element,
|
||||
name: 'AlphanumericFormat',
|
||||
components: {
|
||||
AlphanumericFormat
|
||||
},
|
||||
provide: {
|
||||
openmct: this.openmct,
|
||||
objectPath: this.objectPath,
|
||||
currentView: this
|
||||
},
|
||||
template: '<alphanumeric-format ref="alphanumericFormat"></alphanumeric-format>'
|
||||
});
|
||||
}
|
||||
return this.component.$refs.alphanumericFormat.getViewContext();
|
||||
}
|
||||
|
||||
getViewContext() {
|
||||
if (this.component) {
|
||||
return {};
|
||||
}
|
||||
priority() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return this.component.$refs.alphanumericFormat.getViewContext();
|
||||
}
|
||||
|
||||
priority() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.component.$destroy();
|
||||
this.component = undefined;
|
||||
}
|
||||
destroy() {
|
||||
this.component.$destroy();
|
||||
this.component = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export default function AlphanumericFormatViewProvider(openmct, options) {
|
||||
function isTelemetryObject(selectionPath) {
|
||||
let selectedObject = selectionPath[0].context.item;
|
||||
let parentObject = selectionPath[1].context.item;
|
||||
let selectedLayoutItem = selectionPath[0].context.layoutItem;
|
||||
function isTelemetryObject(selectionPath) {
|
||||
let selectedObject = selectionPath[0].context.item;
|
||||
let parentObject = selectionPath[1].context.item;
|
||||
let selectedLayoutItem = selectionPath[0].context.layoutItem;
|
||||
|
||||
return parentObject
|
||||
&& parentObject.type === 'layout'
|
||||
&& selectedObject
|
||||
&& selectedLayoutItem
|
||||
&& selectedLayoutItem.type === 'telemetry-view'
|
||||
&& openmct.telemetry.isTelemetryObject(selectedObject)
|
||||
&& !options.showAsView.includes(selectedObject.type);
|
||||
return (
|
||||
parentObject &&
|
||||
parentObject.type === 'layout' &&
|
||||
selectedObject &&
|
||||
selectedLayoutItem &&
|
||||
selectedLayoutItem.type === 'telemetry-view' &&
|
||||
openmct.telemetry.isTelemetryObject(selectedObject) &&
|
||||
!options.showAsView.includes(selectedObject.type)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
key: 'alphanumeric-format',
|
||||
name: 'Format',
|
||||
canView: function (selection) {
|
||||
if (selection.length === 0 || selection[0].length === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return selection.every(isTelemetryObject);
|
||||
},
|
||||
view: function (domainObject, objectPath) {
|
||||
return new AlphanumericFormatView(openmct, domainObject, objectPath);
|
||||
}
|
||||
|
||||
return {
|
||||
key: 'alphanumeric-format',
|
||||
name: 'Format',
|
||||
canView: function (selection) {
|
||||
if (selection.length === 0 || selection[0].length === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return selection.every(isTelemetryObject);
|
||||
},
|
||||
view: function (domainObject, objectPath) {
|
||||
return new AlphanumericFormatView(openmct, domainObject, objectPath);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
import printj from 'printj';
|
||||
|
||||
export default class CustomStringFormatter {
|
||||
constructor(openmct, valueMetadata, itemFormat) {
|
||||
this.openmct = openmct;
|
||||
constructor(openmct, valueMetadata, itemFormat) {
|
||||
this.openmct = openmct;
|
||||
|
||||
this.itemFormat = itemFormat;
|
||||
this.valueMetadata = valueMetadata;
|
||||
this.itemFormat = itemFormat;
|
||||
this.valueMetadata = valueMetadata;
|
||||
}
|
||||
|
||||
format(datum) {
|
||||
if (!this.itemFormat) {
|
||||
return;
|
||||
}
|
||||
|
||||
format(datum) {
|
||||
if (!this.itemFormat) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.itemFormat.startsWith('&')) {
|
||||
return printj.sprintf(this.itemFormat, datum[this.valueMetadata.key]);
|
||||
}
|
||||
|
||||
try {
|
||||
const key = this.itemFormat.slice(1);
|
||||
const customFormatter = this.openmct.telemetry.getFormatter(key);
|
||||
if (!customFormatter) {
|
||||
throw new Error('Custom Formatter not found');
|
||||
}
|
||||
|
||||
return customFormatter.format(datum[this.valueMetadata.key]);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
return datum[this.valueMetadata.key];
|
||||
}
|
||||
if (!this.itemFormat.startsWith('&')) {
|
||||
return printj.sprintf(this.itemFormat, datum[this.valueMetadata.key]);
|
||||
}
|
||||
|
||||
setFormat(itemFormat) {
|
||||
this.itemFormat = itemFormat;
|
||||
try {
|
||||
const key = this.itemFormat.slice(1);
|
||||
const customFormatter = this.openmct.telemetry.getFormatter(key);
|
||||
if (!customFormatter) {
|
||||
throw new Error('Custom Formatter not found');
|
||||
}
|
||||
|
||||
return customFormatter.format(datum[this.valueMetadata.key]);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
return datum[this.valueMetadata.key];
|
||||
}
|
||||
}
|
||||
|
||||
setFormat(itemFormat) {
|
||||
this.itemFormat = itemFormat;
|
||||
}
|
||||
}
|
||||
|
@ -2,80 +2,80 @@ import CustomStringFormatter from './CustomStringFormatter';
|
||||
import { createOpenMct, resetApplicationState } from 'utils/testing';
|
||||
|
||||
const CUSTOM_FORMATS = [
|
||||
{
|
||||
key: 'sclk',
|
||||
format: (value) => 2 * value
|
||||
},
|
||||
{
|
||||
key: 'lts',
|
||||
format: (value) => 3 * value
|
||||
}
|
||||
{
|
||||
key: 'sclk',
|
||||
format: (value) => 2 * value
|
||||
},
|
||||
{
|
||||
key: 'lts',
|
||||
format: (value) => 3 * value
|
||||
}
|
||||
];
|
||||
|
||||
const valueMetadata = {
|
||||
key: "sin",
|
||||
name: "Sine",
|
||||
unit: "Hz",
|
||||
formatString: "%0.2f",
|
||||
hints: {
|
||||
range: 1,
|
||||
priority: 3
|
||||
},
|
||||
source: "sin"
|
||||
key: 'sin',
|
||||
name: 'Sine',
|
||||
unit: 'Hz',
|
||||
formatString: '%0.2f',
|
||||
hints: {
|
||||
range: 1,
|
||||
priority: 3
|
||||
},
|
||||
source: 'sin'
|
||||
};
|
||||
|
||||
const datum = {
|
||||
name: "1 Sine Wave Generator",
|
||||
utc: 1603930354000,
|
||||
yesterday: 1603843954000,
|
||||
sin: 0.587785209686822,
|
||||
cos: -0.8090170253297632
|
||||
name: '1 Sine Wave Generator',
|
||||
utc: 1603930354000,
|
||||
yesterday: 1603843954000,
|
||||
sin: 0.587785209686822,
|
||||
cos: -0.8090170253297632
|
||||
};
|
||||
|
||||
describe('CustomStringFormatter', function () {
|
||||
let element;
|
||||
let child;
|
||||
let openmct;
|
||||
let customStringFormatter;
|
||||
let element;
|
||||
let child;
|
||||
let openmct;
|
||||
let customStringFormatter;
|
||||
|
||||
beforeEach((done) => {
|
||||
openmct = createOpenMct();
|
||||
beforeEach((done) => {
|
||||
openmct = createOpenMct();
|
||||
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
CUSTOM_FORMATS.forEach((formatter) => {
|
||||
openmct.telemetry.addFormat(formatter);
|
||||
});
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless();
|
||||
|
||||
customStringFormatter = new CustomStringFormatter(openmct, valueMetadata);
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
CUSTOM_FORMATS.forEach((formatter) => {
|
||||
openmct.telemetry.addFormat(formatter);
|
||||
});
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless();
|
||||
|
||||
afterEach(() => {
|
||||
return resetApplicationState(openmct);
|
||||
});
|
||||
customStringFormatter = new CustomStringFormatter(openmct, valueMetadata);
|
||||
});
|
||||
|
||||
it('adds custom format sclk', () => {
|
||||
const format = openmct.telemetry.getFormatter('sclk');
|
||||
expect(format.key).toEqual('sclk');
|
||||
});
|
||||
afterEach(() => {
|
||||
return resetApplicationState(openmct);
|
||||
});
|
||||
|
||||
it('adds custom format lts', () => {
|
||||
const format = openmct.telemetry.getFormatter('lts');
|
||||
expect(format.key).toEqual('lts');
|
||||
});
|
||||
it('adds custom format sclk', () => {
|
||||
const format = openmct.telemetry.getFormatter('sclk');
|
||||
expect(format.key).toEqual('sclk');
|
||||
});
|
||||
|
||||
it('returns correct value for custom format sclk', () => {
|
||||
customStringFormatter.setFormat('&sclk');
|
||||
const value = customStringFormatter.format(datum, valueMetadata);
|
||||
expect(datum.sin * 2).toEqual(value);
|
||||
});
|
||||
it('adds custom format lts', () => {
|
||||
const format = openmct.telemetry.getFormatter('lts');
|
||||
expect(format.key).toEqual('lts');
|
||||
});
|
||||
|
||||
it('returns correct value for custom format lts', () => {
|
||||
customStringFormatter.setFormat('<s');
|
||||
const value = customStringFormatter.format(datum, valueMetadata);
|
||||
expect(datum.sin * 3).toEqual(value);
|
||||
});
|
||||
it('returns correct value for custom format sclk', () => {
|
||||
customStringFormatter.setFormat('&sclk');
|
||||
const value = customStringFormatter.format(datum, valueMetadata);
|
||||
expect(datum.sin * 2).toEqual(value);
|
||||
});
|
||||
|
||||
it('returns correct value for custom format lts', () => {
|
||||
customStringFormatter.setFormat('<s');
|
||||
const value = customStringFormatter.format(datum, valueMetadata);
|
||||
expect(datum.sin * 3).toEqual(value);
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,67 +21,52 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(function () {
|
||||
function DisplayLayoutType() {
|
||||
return {
|
||||
name: "Display Layout",
|
||||
creatable: true,
|
||||
description: 'Assemble other objects and components together into a reusable screen layout. Simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.',
|
||||
cssClass: 'icon-layout',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
domainObject.configuration = {
|
||||
items: [],
|
||||
layoutGrid: [10, 10]
|
||||
};
|
||||
},
|
||||
form: [
|
||||
{
|
||||
name: "Horizontal grid (px)",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
property: [
|
||||
"configuration",
|
||||
"layoutGrid",
|
||||
0
|
||||
],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "Vertical grid (px)",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
property: [
|
||||
"configuration",
|
||||
"layoutGrid",
|
||||
1
|
||||
],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "Horizontal size (px)",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
property: [
|
||||
"configuration",
|
||||
"layoutDimensions",
|
||||
0
|
||||
],
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: "Vertical size (px)",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
property: [
|
||||
"configuration",
|
||||
"layoutDimensions",
|
||||
1
|
||||
],
|
||||
required: false
|
||||
}
|
||||
]
|
||||
function DisplayLayoutType() {
|
||||
return {
|
||||
name: 'Display Layout',
|
||||
creatable: true,
|
||||
description:
|
||||
'Assemble other objects and components together into a reusable screen layout. Simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.',
|
||||
cssClass: 'icon-layout',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
domainObject.configuration = {
|
||||
items: [],
|
||||
layoutGrid: [10, 10]
|
||||
};
|
||||
}
|
||||
},
|
||||
form: [
|
||||
{
|
||||
name: 'Horizontal grid (px)',
|
||||
control: 'numberfield',
|
||||
cssClass: 'l-input-sm l-numeric',
|
||||
property: ['configuration', 'layoutGrid', 0],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'Vertical grid (px)',
|
||||
control: 'numberfield',
|
||||
cssClass: 'l-input-sm l-numeric',
|
||||
property: ['configuration', 'layoutGrid', 1],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: 'Horizontal size (px)',
|
||||
control: 'numberfield',
|
||||
cssClass: 'l-input-sm l-numeric',
|
||||
property: ['configuration', 'layoutDimensions', 0],
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'Vertical size (px)',
|
||||
control: 'numberfield',
|
||||
cssClass: 'l-input-sm l-numeric',
|
||||
property: ['configuration', 'layoutDimensions', 1],
|
||||
required: false
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
return DisplayLayoutType;
|
||||
return DisplayLayoutType;
|
||||
});
|
||||
|
@ -1,34 +1,34 @@
|
||||
const displayLayoutDrawingObjectTypes = {
|
||||
'box-view': {
|
||||
name: "Box",
|
||||
creatable: false,
|
||||
description: 'A rectangle shape.',
|
||||
cssClass: 'icon-box-round-corners'
|
||||
},
|
||||
'ellipse-view': {
|
||||
name: "Ellipse",
|
||||
creatable: false,
|
||||
description: 'A ellipse shape.',
|
||||
cssClass: 'icon-circle'
|
||||
},
|
||||
'line-view': {
|
||||
name: "Line",
|
||||
creatable: false,
|
||||
description: 'A line.',
|
||||
cssClass: 'icon-line-horz'
|
||||
},
|
||||
'text-view': {
|
||||
name: "Text",
|
||||
creatable: false,
|
||||
description: 'An editable text box.',
|
||||
cssClass: 'icon-font'
|
||||
},
|
||||
'image-view': {
|
||||
name: "Image",
|
||||
creatable: false,
|
||||
description: 'An image.',
|
||||
cssClass: 'icon-image'
|
||||
}
|
||||
'box-view': {
|
||||
name: 'Box',
|
||||
creatable: false,
|
||||
description: 'A rectangle shape.',
|
||||
cssClass: 'icon-box-round-corners'
|
||||
},
|
||||
'ellipse-view': {
|
||||
name: 'Ellipse',
|
||||
creatable: false,
|
||||
description: 'A ellipse shape.',
|
||||
cssClass: 'icon-circle'
|
||||
},
|
||||
'line-view': {
|
||||
name: 'Line',
|
||||
creatable: false,
|
||||
description: 'A line.',
|
||||
cssClass: 'icon-line-horz'
|
||||
},
|
||||
'text-view': {
|
||||
name: 'Text',
|
||||
creatable: false,
|
||||
description: 'An editable text box.',
|
||||
cssClass: 'icon-font'
|
||||
},
|
||||
'image-view': {
|
||||
name: 'Image',
|
||||
creatable: false,
|
||||
description: 'An image.',
|
||||
cssClass: 'icon-image'
|
||||
}
|
||||
};
|
||||
|
||||
export default displayLayoutDrawingObjectTypes;
|
||||
|
@ -20,107 +20,93 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
define([], function () {
|
||||
/**
|
||||
* Handles drag interactions on frames in layouts. This will
|
||||
* provides new positions/dimensions for frames based on
|
||||
* relative pixel positions provided; these will take into account
|
||||
* the grid size (in a snap-to sense) and will enforce some minimums
|
||||
* on both position and dimensions.
|
||||
*
|
||||
* The provided position and dimensions factors will determine
|
||||
* whether this is a move or a resize, and what type of resize it
|
||||
* will be. For instance, a position factor of [1, 1]
|
||||
* will move a frame along with the mouse as the drag
|
||||
* proceeds, while a dimension factor of [0, 0] will leave
|
||||
* dimensions unchanged. Combining these in different
|
||||
* ways results in different handles; a position factor of
|
||||
* [1, 0] and a dimensions factor of [-1, 0] will implement
|
||||
* a left-edge resize, as the horizontal position will move
|
||||
* with the mouse while the horizontal dimensions shrink in
|
||||
* kind (and vertical properties remain unmodified.)
|
||||
*
|
||||
* @param {object} rawPosition the initial position/dimensions
|
||||
* of the frame being interacted with
|
||||
* @param {number[]} posFactor the position factor
|
||||
* @param {number[]} dimFactor the dimensions factor
|
||||
* @param {number[]} the size of each grid element, in pixels
|
||||
* @constructor
|
||||
* @memberof platform/features/layout
|
||||
*/
|
||||
function LayoutDrag(rawPosition, posFactor, dimFactor, gridSize) {
|
||||
this.rawPosition = rawPosition;
|
||||
this.posFactor = posFactor;
|
||||
this.dimFactor = dimFactor;
|
||||
this.gridSize = gridSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles drag interactions on frames in layouts. This will
|
||||
* provides new positions/dimensions for frames based on
|
||||
* relative pixel positions provided; these will take into account
|
||||
* the grid size (in a snap-to sense) and will enforce some minimums
|
||||
* on both position and dimensions.
|
||||
*
|
||||
* The provided position and dimensions factors will determine
|
||||
* whether this is a move or a resize, and what type of resize it
|
||||
* will be. For instance, a position factor of [1, 1]
|
||||
* will move a frame along with the mouse as the drag
|
||||
* proceeds, while a dimension factor of [0, 0] will leave
|
||||
* dimensions unchanged. Combining these in different
|
||||
* ways results in different handles; a position factor of
|
||||
* [1, 0] and a dimensions factor of [-1, 0] will implement
|
||||
* a left-edge resize, as the horizontal position will move
|
||||
* with the mouse while the horizontal dimensions shrink in
|
||||
* kind (and vertical properties remain unmodified.)
|
||||
*
|
||||
* @param {object} rawPosition the initial position/dimensions
|
||||
* of the frame being interacted with
|
||||
* @param {number[]} posFactor the position factor
|
||||
* @param {number[]} dimFactor the dimensions factor
|
||||
* @param {number[]} the size of each grid element, in pixels
|
||||
* @constructor
|
||||
* @memberof platform/features/layout
|
||||
*/
|
||||
function LayoutDrag(rawPosition, posFactor, dimFactor, gridSize) {
|
||||
this.rawPosition = rawPosition;
|
||||
this.posFactor = posFactor;
|
||||
this.dimFactor = dimFactor;
|
||||
this.gridSize = gridSize;
|
||||
}
|
||||
// Convert a delta from pixel coordinates to grid coordinates,
|
||||
// rounding to whole-number grid coordinates.
|
||||
function toGridDelta(gridSize, pixelDelta) {
|
||||
return pixelDelta.map(function (v, i) {
|
||||
return Math.round(v / gridSize[i]);
|
||||
});
|
||||
}
|
||||
|
||||
// Convert a delta from pixel coordinates to grid coordinates,
|
||||
// rounding to whole-number grid coordinates.
|
||||
function toGridDelta(gridSize, pixelDelta) {
|
||||
return pixelDelta.map(function (v, i) {
|
||||
return Math.round(v / gridSize[i]);
|
||||
});
|
||||
}
|
||||
// Utility function to perform element-by-element multiplication
|
||||
function multiply(array, factors) {
|
||||
return array.map(function (v, i) {
|
||||
return v * factors[i];
|
||||
});
|
||||
}
|
||||
|
||||
// Utility function to perform element-by-element multiplication
|
||||
function multiply(array, factors) {
|
||||
return array.map(function (v, i) {
|
||||
return v * factors[i];
|
||||
});
|
||||
}
|
||||
// Utility function to perform element-by-element addition
|
||||
function add(array, other) {
|
||||
return array.map(function (v, i) {
|
||||
return v + other[i];
|
||||
});
|
||||
}
|
||||
|
||||
// Utility function to perform element-by-element addition
|
||||
function add(array, other) {
|
||||
return array.map(function (v, i) {
|
||||
return v + other[i];
|
||||
});
|
||||
}
|
||||
// Utility function to perform element-by-element max-choosing
|
||||
function max(array, other) {
|
||||
return array.map(function (v, i) {
|
||||
return Math.max(v, other[i]);
|
||||
});
|
||||
}
|
||||
|
||||
// Utility function to perform element-by-element max-choosing
|
||||
function max(array, other) {
|
||||
return array.map(function (v, i) {
|
||||
return Math.max(v, other[i]);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get a new position object in grid coordinates, with
|
||||
* position and dimensions both offset appropriately
|
||||
* according to the factors supplied in the constructor.
|
||||
* @param {number[]} pixelDelta the offset from the
|
||||
* original position, in pixels
|
||||
*/
|
||||
LayoutDrag.prototype.getAdjustedPositionAndDimensions = function (pixelDelta) {
|
||||
const gridDelta = toGridDelta(this.gridSize, pixelDelta);
|
||||
|
||||
/**
|
||||
* Get a new position object in grid coordinates, with
|
||||
* position and dimensions both offset appropriately
|
||||
* according to the factors supplied in the constructor.
|
||||
* @param {number[]} pixelDelta the offset from the
|
||||
* original position, in pixels
|
||||
*/
|
||||
LayoutDrag.prototype.getAdjustedPositionAndDimensions = function (pixelDelta) {
|
||||
const gridDelta = toGridDelta(this.gridSize, pixelDelta);
|
||||
return {
|
||||
position: max(add(this.rawPosition.position, multiply(gridDelta, this.posFactor)), [0, 0]),
|
||||
dimensions: max(add(this.rawPosition.dimensions, multiply(gridDelta, this.dimFactor)), [1, 1])
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
position: max(add(
|
||||
this.rawPosition.position,
|
||||
multiply(gridDelta, this.posFactor)
|
||||
), [0, 0]),
|
||||
dimensions: max(add(
|
||||
this.rawPosition.dimensions,
|
||||
multiply(gridDelta, this.dimFactor)
|
||||
), [1, 1])
|
||||
};
|
||||
};
|
||||
LayoutDrag.prototype.getAdjustedPosition = function (pixelDelta) {
|
||||
const gridDelta = toGridDelta(this.gridSize, pixelDelta);
|
||||
|
||||
LayoutDrag.prototype.getAdjustedPosition = function (pixelDelta) {
|
||||
const gridDelta = toGridDelta(this.gridSize, pixelDelta);
|
||||
return {
|
||||
position: max(add(this.rawPosition.position, multiply(gridDelta, this.posFactor)), [0, 0])
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
position: max(add(
|
||||
this.rawPosition.position,
|
||||
multiply(gridDelta, this.posFactor)
|
||||
), [0, 0])
|
||||
};
|
||||
};
|
||||
|
||||
return LayoutDrag;
|
||||
|
||||
}
|
||||
);
|
||||
return LayoutDrag;
|
||||
});
|
||||
|
@ -1,38 +1,38 @@
|
||||
import clipboard from '@/utils/clipboard';
|
||||
|
||||
export default class CopyToClipboardAction {
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
|
||||
this.cssClass = 'icon-duplicate';
|
||||
this.description = 'Copy value to clipboard';
|
||||
this.group = "action";
|
||||
this.key = 'copyToClipboard';
|
||||
this.name = 'Copy to Clipboard';
|
||||
this.priority = 1;
|
||||
this.cssClass = 'icon-duplicate';
|
||||
this.description = 'Copy value to clipboard';
|
||||
this.group = 'action';
|
||||
this.key = 'copyToClipboard';
|
||||
this.name = 'Copy to Clipboard';
|
||||
this.priority = 1;
|
||||
}
|
||||
|
||||
invoke(objectPath, view = {}) {
|
||||
const viewContext = view.getViewContext && view.getViewContext();
|
||||
const formattedValue = viewContext.row.formattedValueForCopy();
|
||||
|
||||
clipboard
|
||||
.updateClipboard(formattedValue)
|
||||
.then(() => {
|
||||
this.openmct.notifications.info(`Success : copied '${formattedValue}' to clipboard `);
|
||||
})
|
||||
.catch(() => {
|
||||
this.openmct.notifications.error(`Failed : to copy '${formattedValue}' to clipboard `);
|
||||
});
|
||||
}
|
||||
|
||||
appliesTo(objectPath, view = {}) {
|
||||
const viewContext = view.getViewContext && view.getViewContext();
|
||||
const row = viewContext && viewContext.row;
|
||||
if (!row) {
|
||||
return false;
|
||||
}
|
||||
|
||||
invoke(objectPath, view = {}) {
|
||||
const viewContext = view.getViewContext && view.getViewContext();
|
||||
const formattedValue = viewContext.row.formattedValueForCopy();
|
||||
|
||||
clipboard.updateClipboard(formattedValue)
|
||||
.then(() => {
|
||||
this.openmct.notifications.info(`Success : copied '${formattedValue}' to clipboard `);
|
||||
})
|
||||
.catch(() => {
|
||||
this.openmct.notifications.error(`Failed : to copy '${formattedValue}' to clipboard `);
|
||||
});
|
||||
}
|
||||
|
||||
appliesTo(objectPath, view = {}) {
|
||||
const viewContext = view.getViewContext && view.getViewContext();
|
||||
const row = viewContext && viewContext.row;
|
||||
if (!row) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return row.formattedValueForCopy
|
||||
&& typeof row.formattedValueForCopy === 'function';
|
||||
}
|
||||
return row.formattedValueForCopy && typeof row.formattedValueForCopy === 'function';
|
||||
}
|
||||
}
|
||||
|
@ -21,82 +21,79 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="c-inspect-properties"
|
||||
>
|
||||
<div class="c-inspect-properties">
|
||||
<ul class="c-inspect-properties__section">
|
||||
<li class="c-inspect-properties__row">
|
||||
<div
|
||||
class="c-inspect-properties__label"
|
||||
title="Printf formatting for the selected telemetry"
|
||||
>
|
||||
<label for="telemetryPrintfFormat">Format</label>
|
||||
</div>
|
||||
<div class="c-inspect-properties__value">
|
||||
<input
|
||||
id="telemetryPrintfFormat"
|
||||
type="text"
|
||||
:disabled="!isEditing"
|
||||
:value="telemetryFormat"
|
||||
:placeholder="nonMixedFormat ? '' : 'Mixed'"
|
||||
@change="formatTelemetry"
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
<li class="c-inspect-properties__row">
|
||||
<div
|
||||
class="c-inspect-properties__label"
|
||||
title="Printf formatting for the selected telemetry"
|
||||
>
|
||||
<label for="telemetryPrintfFormat">Format</label>
|
||||
</div>
|
||||
<div class="c-inspect-properties__value">
|
||||
<input
|
||||
id="telemetryPrintfFormat"
|
||||
type="text"
|
||||
:disabled="!isEditing"
|
||||
:value="telemetryFormat"
|
||||
:placeholder="nonMixedFormat ? '' : 'Mixed'"
|
||||
@change="formatTelemetry"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AlphanumericFormat',
|
||||
inject: ['openmct', 'objectPath'],
|
||||
data() {
|
||||
return {
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
telemetryFormat: undefined,
|
||||
nonMixedFormat: false
|
||||
};
|
||||
name: 'AlphanumericFormat',
|
||||
inject: ['openmct', 'objectPath'],
|
||||
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;
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', this.toggleEdit);
|
||||
this.openmct.selection.on('change', this.handleSelection);
|
||||
this.handleSelection(this.openmct.selection.get());
|
||||
formatTelemetry(event) {
|
||||
const newFormat = event.currentTarget.value;
|
||||
this.openmct.selection.get().forEach((selectionPath) => {
|
||||
selectionPath[0].context.updateTelemetryFormat(newFormat);
|
||||
});
|
||||
this.telemetryFormat = newFormat;
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.editor.off('isEditing', this.toggleEdit);
|
||||
this.openmct.selection.off('change', this.handleSelection);
|
||||
},
|
||||
methods: {
|
||||
toggleEdit(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
},
|
||||
formatTelemetry(event) {
|
||||
const 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;
|
||||
}
|
||||
handleSelection(selection) {
|
||||
if (selection.length === 0 || selection[0].length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
let layoutItem = selection[0][0].context.layoutItem;
|
||||
let layoutItem = selection[0][0].context.layoutItem;
|
||||
|
||||
if (!layoutItem) {
|
||||
return;
|
||||
}
|
||||
if (!layoutItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
let format = layoutItem.format;
|
||||
this.nonMixedFormat = selection.every(selectionPath => {
|
||||
return selectionPath[0].context.layoutItem.format === format;
|
||||
});
|
||||
let format = layoutItem.format;
|
||||
this.nonMixedFormat = selection.every((selectionPath) => {
|
||||
return selectionPath[0].context.layoutItem.format === format;
|
||||
});
|
||||
|
||||
this.telemetryFormat = this.nonMixedFormat ? format : '';
|
||||
}
|
||||
this.telemetryFormat = this.nonMixedFormat ? format : '';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
@ -21,19 +21,19 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<layout-frame
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:is-editing="isEditing"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
>
|
||||
<div
|
||||
class="c-box-view u-style-receiver js-style-receiver"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
class="c-box-view u-style-receiver js-style-receiver"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
></div>
|
||||
</layout-frame>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -41,82 +41,84 @@ import LayoutFrame from './LayoutFrame.vue';
|
||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#666666',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5
|
||||
};
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#666666',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
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')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
if (this.itemStyle) {
|
||||
return this.itemStyle;
|
||||
} else {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
border: this.item.stroke ? '1px solid ' + this.item.stroke : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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();
|
||||
}
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
if (this.itemStyle) {
|
||||
return this.itemStyle;
|
||||
} else {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
border: this.item.stroke ? '1px solid ' + this.item.stroke : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,42 +20,49 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
class="l-layout__grid-holder"
|
||||
:class="{ 'c-grid': showGrid }"
|
||||
>
|
||||
<div class="l-layout__grid-holder" :class="{ 'c-grid': showGrid }">
|
||||
<div
|
||||
v-if="gridSize[0] >= 3"
|
||||
class="c-grid__x l-grid l-grid-x"
|
||||
:style="[{ backgroundSize: gridSize[0] + 'px 100%', width: gridDimensions[0] +'px', height: gridDimensions[1] +'px' }]"
|
||||
v-if="gridSize[0] >= 3"
|
||||
class="c-grid__x l-grid l-grid-x"
|
||||
:style="[
|
||||
{
|
||||
backgroundSize: gridSize[0] + 'px 100%',
|
||||
width: gridDimensions[0] + 'px',
|
||||
height: gridDimensions[1] + 'px'
|
||||
}
|
||||
]"
|
||||
></div>
|
||||
<div
|
||||
v-if="gridSize[1] >= 3"
|
||||
class="c-grid__y l-grid l-grid-y"
|
||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px', width: gridDimensions[0] +'px', height: gridDimensions[1] +'px' }]"
|
||||
v-if="gridSize[1] >= 3"
|
||||
class="c-grid__y l-grid l-grid-y"
|
||||
:style="[
|
||||
{
|
||||
backgroundSize: '100%' + gridSize[1] + 'px',
|
||||
width: gridDimensions[0] + 'px',
|
||||
height: gridDimensions[1] + 'px'
|
||||
}
|
||||
]"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
},
|
||||
showGrid: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
gridDimensions: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
}
|
||||
props: {
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
showGrid: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
gridDimensions: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -21,171 +21,174 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<!-- Resize handles -->
|
||||
<div
|
||||
class="c-frame-edit"
|
||||
:style="marqueeStyle"
|
||||
>
|
||||
<!-- Resize handles -->
|
||||
<div class="c-frame-edit" :style="marqueeStyle">
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--nw"
|
||||
@mousedown.left="startResize([1,1], [-1,-1], $event)"
|
||||
class="c-frame-edit__handle c-frame-edit__handle--nw"
|
||||
@mousedown.left="startResize([1, 1], [-1, -1], $event)"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--ne"
|
||||
@mousedown.left="startResize([0,1], [1,-1], $event)"
|
||||
class="c-frame-edit__handle c-frame-edit__handle--ne"
|
||||
@mousedown.left="startResize([0, 1], [1, -1], $event)"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--sw"
|
||||
@mousedown.left="startResize([1,0], [-1,1], $event)"
|
||||
class="c-frame-edit__handle c-frame-edit__handle--sw"
|
||||
@mousedown.left="startResize([1, 0], [-1, 1], $event)"
|
||||
></div>
|
||||
<div
|
||||
class="c-frame-edit__handle c-frame-edit__handle--se"
|
||||
@mousedown.left="startResize([0,0], [1,1], $event)"
|
||||
class="c-frame-edit__handle c-frame-edit__handle--se"
|
||||
@mousedown.left="startResize([0, 0], [1, 1], $event)"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutDrag from './../LayoutDrag';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
selectedLayoutItems: {
|
||||
type: Array,
|
||||
default: undefined
|
||||
},
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2
|
||||
&& arr.every(el => typeof el === 'number')
|
||||
}
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
selectedLayoutItems: {
|
||||
type: Array,
|
||||
default: undefined
|
||||
},
|
||||
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;
|
||||
} else {
|
||||
width = width - x;
|
||||
height = height - y;
|
||||
}
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
},
|
||||
marqueeStyle() {
|
||||
return {
|
||||
left: (this.gridSize[0] * this.marqueePosition.x) + 'px',
|
||||
top: (this.gridSize[1] * this.marqueePosition.y) + 'px',
|
||||
width: (this.gridSize[0] * this.marqueePosition.width) + 'px',
|
||||
height: (this.gridSize[1] * this.marqueePosition.height) + 'px'
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
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 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 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();
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
width = width - x;
|
||||
height = height - y;
|
||||
}
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
},
|
||||
marqueeStyle() {
|
||||
return {
|
||||
left: this.gridSize[0] * this.marqueePosition.x + 'px',
|
||||
top: this.gridSize[1] * this.marqueePosition.y + 'px',
|
||||
width: this.gridSize[0] * this.marqueePosition.width + 'px',
|
||||
height: this.gridSize[1] * this.marqueePosition.height + 'px'
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
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 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 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();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -21,19 +21,19 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<layout-frame
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:is-editing="isEditing"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
>
|
||||
<div
|
||||
class="c-ellipse-view u-style-receiver js-style-receiver"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
class="c-ellipse-view u-style-receiver js-style-receiver"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
></div>
|
||||
</layout-frame>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -41,82 +41,84 @@ import LayoutFrame from './LayoutFrame.vue';
|
||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#666666',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 10
|
||||
};
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#666666',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 10
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
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')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
if (this.itemStyle) {
|
||||
return this.itemStyle;
|
||||
} else {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
border: this.item.stroke ? '1px solid ' + this.item.stroke : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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();
|
||||
}
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
if (this.itemStyle) {
|
||||
return this.itemStyle;
|
||||
} else {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
border: this.item.stroke ? '1px solid ' + this.item.stroke : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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>
|
||||
|
@ -21,109 +21,107 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<layout-frame
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:is-editing="isEditing"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
<div
|
||||
class="c-image-view"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
></div>
|
||||
</layout-frame>
|
||||
>
|
||||
<div class="c-image-view" :class="[styleClass]" :style="style"></div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue';
|
||||
import conditionalStylesMixin from "../mixins/objectStyles-mixin";
|
||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
stroke: 'transparent',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
url: element.url
|
||||
};
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
stroke: 'transparent',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
url: element.url
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
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')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let backgroundImage = 'url(' + this.item.url + ')';
|
||||
let border = '1px solid ' + this.item.stroke;
|
||||
|
||||
if (this.itemStyle) {
|
||||
if (this.itemStyle.imageUrl !== undefined) {
|
||||
backgroundImage = 'url(' + this.itemStyle.imageUrl + ')';
|
||||
}
|
||||
|
||||
border = this.itemStyle.border;
|
||||
}
|
||||
|
||||
return {
|
||||
backgroundImage,
|
||||
border
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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();
|
||||
}
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let backgroundImage = 'url(' + this.item.url + ')';
|
||||
let border = '1px solid ' + this.item.stroke;
|
||||
|
||||
if (this.itemStyle) {
|
||||
if (this.itemStyle.imageUrl !== undefined) {
|
||||
backgroundImage = 'url(' + this.itemStyle.imageUrl + ')';
|
||||
}
|
||||
|
||||
border = this.itemStyle.border;
|
||||
}
|
||||
|
||||
return {
|
||||
backgroundImage,
|
||||
border
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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>
|
||||
|
@ -21,20 +21,17 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
<div
|
||||
class="l-layout__frame c-frame"
|
||||
:class="{
|
||||
'no-frame': !item.hasFrame,
|
||||
'u-inspectable': inspectable
|
||||
'no-frame': !item.hasFrame,
|
||||
'u-inspectable': inspectable
|
||||
}"
|
||||
:style="style"
|
||||
>
|
||||
>
|
||||
<slot></slot>
|
||||
<div
|
||||
class="c-frame__move-bar"
|
||||
@mousedown.left="startMove($event)"
|
||||
></div>
|
||||
</div>
|
||||
<div class="c-frame__move-bar" @mousedown.left="startMove($event)"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -42,95 +39,96 @@ import LayoutDrag from './../LayoutDrag';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default {
|
||||
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')
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
size() {
|
||||
let {width, height} = this.item;
|
||||
|
||||
return {
|
||||
width: (this.gridSize[0] * width),
|
||||
height: (this.gridSize[1] * height)
|
||||
};
|
||||
},
|
||||
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')
|
||||
},
|
||||
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(event, posFactor = [1, 1], dimFactor = [0, 0]) {
|
||||
if (!this.isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
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]);
|
||||
});
|
||||
}
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
size() {
|
||||
let { width, height } = this.item;
|
||||
|
||||
return {
|
||||
width: this.gridSize[0] * width,
|
||||
height: this.gridSize[1] * height
|
||||
};
|
||||
},
|
||||
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(event, posFactor = [1, 1], dimFactor = [0, 0]) {
|
||||
if (!this.isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
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]);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -21,356 +21,347 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="l-layout__frame c-frame no-frame c-line-view"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
>
|
||||
<line
|
||||
class="c-line-view__hover-indicator"
|
||||
v-bind="linePosition"
|
||||
vector-effect="non-scaling-stroke"
|
||||
/>
|
||||
<line
|
||||
class="c-line-view__line"
|
||||
v-bind="linePosition"
|
||||
:stroke="stroke"
|
||||
vector-effect="non-scaling-stroke"
|
||||
/>
|
||||
<div class="l-layout__frame c-frame no-frame c-line-view" :class="[styleClass]" :style="style">
|
||||
<svg width="100%" height="100%">
|
||||
<line
|
||||
class="c-line-view__hover-indicator"
|
||||
v-bind="linePosition"
|
||||
vector-effect="non-scaling-stroke"
|
||||
/>
|
||||
<line
|
||||
class="c-line-view__line"
|
||||
v-bind="linePosition"
|
||||
:stroke="stroke"
|
||||
vector-effect="non-scaling-stroke"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<div
|
||||
class="c-frame__move-bar"
|
||||
@mousedown.left="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 class="c-frame__move-bar" @mousedown.left="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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import conditionalStylesMixin from "../mixins/objectStyles-mixin";
|
||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||
import _ from 'lodash';
|
||||
|
||||
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',
|
||||
5: 'c-frame-edit__handle--nw',
|
||||
6: 'c-frame-edit__handle--ne'
|
||||
1: 'c-frame-edit__handle--sw',
|
||||
2: 'c-frame-edit__handle--se',
|
||||
3: 'c-frame-edit__handle--ne',
|
||||
4: 'c-frame-edit__handle--nw',
|
||||
5: 'c-frame-edit__handle--nw',
|
||||
6: 'c-frame-edit__handle--ne'
|
||||
};
|
||||
|
||||
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',
|
||||
5: 'c-frame-edit__handle--sw',
|
||||
6: 'c-frame-edit__handle--nw'
|
||||
1: 'c-frame-edit__handle--ne',
|
||||
2: 'c-frame-edit__handle--nw',
|
||||
3: 'c-frame-edit__handle--sw',
|
||||
4: 'c-frame-edit__handle--se',
|
||||
5: 'c-frame-edit__handle--sw',
|
||||
6: 'c-frame-edit__handle--nw'
|
||||
};
|
||||
|
||||
export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
x: 5,
|
||||
y: 10,
|
||||
x2: 10,
|
||||
y2: 5,
|
||||
stroke: '#666666'
|
||||
};
|
||||
makeDefinition() {
|
||||
return {
|
||||
x: 5,
|
||||
y: 10,
|
||||
x2: 10,
|
||||
y2: 5,
|
||||
stroke: '#666666'
|
||||
};
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
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
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dragPosition: undefined,
|
||||
dragging: undefined,
|
||||
selection: []
|
||||
};
|
||||
initSelect: Boolean,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
showFrameEdit() {
|
||||
let layoutItem = this.selection.length > 0 && this.selection[0][0].context.layoutItem;
|
||||
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
|
||||
};
|
||||
},
|
||||
stroke() {
|
||||
if (this.itemStyle) {
|
||||
if (this.itemStyle.border) {
|
||||
return this.itemStyle.border.replace('1px solid ', '');
|
||||
}
|
||||
|
||||
return '';
|
||||
} else {
|
||||
return this.item.stroke;
|
||||
}
|
||||
},
|
||||
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) {
|
||||
return 5; // Vertical line
|
||||
}
|
||||
|
||||
if (y2 === y) {
|
||||
return 6; // Horizontal line
|
||||
}
|
||||
|
||||
if (x2 > x) {
|
||||
if (y2 < y) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (y2 < y) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
},
|
||||
linePosition() {
|
||||
let pos = {};
|
||||
switch (this.vectorQuadrant) {
|
||||
case 1:
|
||||
case 3:
|
||||
// slopes up
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '100%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
};
|
||||
break;
|
||||
case 5:
|
||||
// vertical
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '0%',
|
||||
y2: '100%'
|
||||
};
|
||||
break;
|
||||
case 6:
|
||||
// horizontal
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
};
|
||||
break;
|
||||
default:
|
||||
// slopes down
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
return !this.multiSelect && layoutItem && layoutItem.id === this.item.id;
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
position() {
|
||||
let { x, y, x2, y2 } = this.item;
|
||||
if (this.dragging && this.dragPosition) {
|
||||
({ x, y, x2, y2 } = this.dragPosition);
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
x2,
|
||||
y2
|
||||
};
|
||||
},
|
||||
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();
|
||||
stroke() {
|
||||
if (this.itemStyle) {
|
||||
if (this.itemStyle.border) {
|
||||
return this.itemStyle.border.replace('1px solid ', '');
|
||||
}
|
||||
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
return '';
|
||||
} else {
|
||||
return this.item.stroke;
|
||||
}
|
||||
},
|
||||
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];
|
||||
let {x, y, x2, y2} = this.item;
|
||||
this.dragPosition = {
|
||||
x,
|
||||
y,
|
||||
x2,
|
||||
y2
|
||||
};
|
||||
if (x === x2 || y === y2) {
|
||||
if (y > y2 || x < x2) {
|
||||
if (this.dragging === 'start') {
|
||||
this.dragging = 'end';
|
||||
} else if (this.dragging === 'end') {
|
||||
this.dragging = 'start';
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
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) {
|
||||
return 5; // Vertical line
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
if (y2 === y) {
|
||||
return 6; // Horizontal line
|
||||
}
|
||||
|
||||
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[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]);
|
||||
});
|
||||
if (x2 > x) {
|
||||
if (y2 < y) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (y2 < y) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
},
|
||||
linePosition() {
|
||||
let pos = {};
|
||||
switch (this.vectorQuadrant) {
|
||||
case 1:
|
||||
case 3:
|
||||
// slopes up
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '100%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
};
|
||||
break;
|
||||
case 5:
|
||||
// vertical
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '0%',
|
||||
y2: '100%'
|
||||
};
|
||||
break;
|
||||
case 6:
|
||||
// horizontal
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '0%'
|
||||
};
|
||||
break;
|
||||
default:
|
||||
// slopes down
|
||||
pos = {
|
||||
x1: '0%',
|
||||
y1: '0%',
|
||||
x2: '100%',
|
||||
y2: '100%'
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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];
|
||||
let { x, y, x2, y2 } = this.item;
|
||||
this.dragPosition = {
|
||||
x,
|
||||
y,
|
||||
x2,
|
||||
y2
|
||||
};
|
||||
if (x === x2 || y === y2) {
|
||||
if (y > y2 || x < x2) {
|
||||
if (this.dragging === 'start') {
|
||||
this.dragging = 'end';
|
||||
} else if (this.dragging === 'end') {
|
||||
this.dragging = 'start';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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[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>
|
||||
|
@ -20,25 +20,25 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<layout-frame
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:title="domainObject && domainObject.name"
|
||||
:is-editing="isEditing"
|
||||
@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-font-size="item.fontSize"
|
||||
:layout-font="item.font"
|
||||
v-if="domainObject"
|
||||
ref="objectFrame"
|
||||
:domain-object="domainObject"
|
||||
:object-path="currentObjectPath"
|
||||
:has-frame="item.hasFrame"
|
||||
:show-edit-view="false"
|
||||
:layout-font-size="item.fontSize"
|
||||
:layout-font="item.font"
|
||||
/>
|
||||
</layout-frame>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -51,126 +51,125 @@ const DEFAULT_POSITION = [1, 1];
|
||||
const DEFAULT_HIDDEN_FRAME_TYPES = ['hyperlink', 'summary-widget', 'conditionWidget'];
|
||||
|
||||
function getDefaultDimensions(gridSize) {
|
||||
return MINIMUM_FRAME_SIZE.map((min, index) => {
|
||||
return Math.max(
|
||||
Math.ceil(min / gridSize[index]),
|
||||
DEFAULT_DIMENSIONS[index]
|
||||
);
|
||||
});
|
||||
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;
|
||||
return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
|
||||
}
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position, viewKey) {
|
||||
let defaultDimensions = getDefaultDimensions(gridSize);
|
||||
position = position || DEFAULT_POSITION;
|
||||
makeDefinition(openmct, gridSize, domainObject, position, viewKey) {
|
||||
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),
|
||||
fontSize: 'default',
|
||||
font: 'default',
|
||||
viewKey
|
||||
};
|
||||
return {
|
||||
width: defaultDimensions[0],
|
||||
height: defaultDimensions[1],
|
||||
x: position[0],
|
||||
y: position[1],
|
||||
identifier: domainObject.identifier,
|
||||
hasFrame: hasFrameByDefault(domainObject.type),
|
||||
fontSize: 'default',
|
||||
font: 'default',
|
||||
viewKey
|
||||
};
|
||||
},
|
||||
components: {
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
components: {
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
inject: ['openmct', 'objectPath'],
|
||||
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
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
initSelect: Boolean,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
currentObjectPath: [],
|
||||
mutablePromise: undefined
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.openmct.objects.supportsMutation(this.item.identifier)) {
|
||||
this.mutablePromise = this.openmct.objects.getMutable(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
} else {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
if (this.mutablePromise) {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.mutablePromise = undefined;
|
||||
this.currentObjectPath = [this.domainObject].concat(this.objectPath.slice());
|
||||
this.$nextTick(() => {
|
||||
let reference = this.$refs.objectFrame;
|
||||
|
||||
if (reference) {
|
||||
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.immediatelySelect || this.initSelect);
|
||||
delete this.immediatelySelect;
|
||||
}
|
||||
});
|
||||
}
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
currentObjectPath: [],
|
||||
mutablePromise: undefined
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.openmct.objects.supportsMutation(this.item.identifier)) {
|
||||
this.mutablePromise = this.openmct.objects
|
||||
.getMutable(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
} else {
|
||||
this.openmct.objects.get(this.item.identifier).then(this.setObject);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
if (this.mutablePromise) {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.mutablePromise = undefined;
|
||||
this.currentObjectPath = [this.domainObject].concat(this.objectPath.slice());
|
||||
this.$nextTick(() => {
|
||||
let reference = this.$refs.objectFrame;
|
||||
|
||||
if (reference) {
|
||||
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.immediatelySelect || this.initSelect
|
||||
);
|
||||
delete this.immediatelySelect;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -21,353 +21,365 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<layout-frame
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:is-editing="isEditing"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
>
|
||||
<div
|
||||
v-if="domainObject"
|
||||
class="c-telemetry-view u-style-receiver"
|
||||
:class="[itemClasses]"
|
||||
:style="styleObject"
|
||||
:data-font-size="item.fontSize"
|
||||
:data-font="item.font"
|
||||
@contextmenu.prevent="showContextMenu"
|
||||
v-if="domainObject"
|
||||
class="c-telemetry-view u-style-receiver"
|
||||
:class="[itemClasses]"
|
||||
:style="styleObject"
|
||||
:data-font-size="item.fontSize"
|
||||
:data-font="item.font"
|
||||
@contextmenu.prevent="showContextMenu"
|
||||
>
|
||||
<div
|
||||
class="is-status__indicator"
|
||||
:title="`This item is ${status}`"
|
||||
></div>
|
||||
<div
|
||||
v-if="showLabel"
|
||||
class="c-telemetry-view__label"
|
||||
>
|
||||
<div class="c-telemetry-view__label-text">
|
||||
{{ domainObject.name }}
|
||||
</div>
|
||||
<div class="is-status__indicator" :title="`This item is ${status}`"></div>
|
||||
<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 }}
|
||||
<span
|
||||
v-if="unit && item.showUnits"
|
||||
class="c-telemetry-view__value-text__unit"
|
||||
>
|
||||
{{ unit }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="showValue"
|
||||
:title="fieldName"
|
||||
class="c-telemetry-view__value"
|
||||
:class="[telemetryClass]"
|
||||
>
|
||||
<div class="c-telemetry-view__value-text">
|
||||
{{ telemetryValue }}
|
||||
<span v-if="unit && item.showUnits" class="c-telemetry-view__value-text__unit">
|
||||
{{ unit }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</layout-frame>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue';
|
||||
import conditionalStylesMixin from "../mixins/objectStyles-mixin";
|
||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||
import { getDefaultNotebook, getNotebookSectionAndPage } from '@/plugins/notebook/utils/notebook-storage.js';
|
||||
import {
|
||||
getDefaultNotebook,
|
||||
getNotebookSectionAndPage
|
||||
} from '@/plugins/notebook/utils/notebook-storage.js';
|
||||
|
||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5];
|
||||
const DEFAULT_POSITION = [1, 1];
|
||||
const CONTEXT_MENU_ACTIONS = ['copyToClipboard', 'copyToNotebook', 'viewHistoricalData'];
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||
position = position || DEFAULT_POSITION;
|
||||
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()?.key,
|
||||
stroke: "",
|
||||
fill: "",
|
||||
color: "",
|
||||
fontSize: 'default',
|
||||
font: 'default'
|
||||
};
|
||||
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()?.key,
|
||||
stroke: '',
|
||||
fill: '',
|
||||
color: '',
|
||||
fontSize: 'default',
|
||||
font: 'default'
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
mixins: [conditionalStylesMixin, stalenessMixin],
|
||||
inject: ['openmct', 'objectPath', 'currentView'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
mixins: [conditionalStylesMixin, stalenessMixin],
|
||||
inject: ['openmct', 'objectPath', 'currentView'],
|
||||
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
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
initSelect: Boolean,
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentObjectPath: undefined,
|
||||
datum: undefined,
|
||||
domainObject: undefined,
|
||||
formats: undefined,
|
||||
viewKey: `alphanumeric-format-${Math.random()}`,
|
||||
status: '',
|
||||
mutablePromise: undefined
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
itemClasses() {
|
||||
let classes = [];
|
||||
|
||||
if (this.status) {
|
||||
classes.push(`is-status--${this.status}`);
|
||||
}
|
||||
|
||||
if (this.isStale) {
|
||||
classes.push('is-stale');
|
||||
}
|
||||
|
||||
return classes;
|
||||
},
|
||||
showLabel() {
|
||||
let displayMode = this.item.displayMode;
|
||||
|
||||
return displayMode === 'all' || displayMode === 'label';
|
||||
},
|
||||
showValue() {
|
||||
let displayMode = this.item.displayMode;
|
||||
|
||||
return displayMode === 'all' || displayMode === 'value';
|
||||
},
|
||||
unit() {
|
||||
let value = this.item.value;
|
||||
let unit = this.metadata ? this.metadata.value(value).unit : '';
|
||||
|
||||
return unit;
|
||||
},
|
||||
styleObject() {
|
||||
let size;
|
||||
//for legacy size support
|
||||
if (!this.item.fontSize) {
|
||||
size = this.item.size;
|
||||
}
|
||||
|
||||
return Object.assign({}, {
|
||||
size
|
||||
}, this.itemStyle);
|
||||
},
|
||||
fieldName() {
|
||||
return this.valueMetadata && this.valueMetadata.name;
|
||||
},
|
||||
valueMetadata() {
|
||||
return this.datum && this.metadata.value(this.item.value);
|
||||
},
|
||||
formatter() {
|
||||
if (this.item.format) {
|
||||
return this.customStringformatter;
|
||||
}
|
||||
|
||||
return this.formats[this.item.value];
|
||||
},
|
||||
telemetryValue() {
|
||||
if (!this.datum) {
|
||||
return '---';
|
||||
}
|
||||
|
||||
return this.formatter && this.formatter.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) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.openmct.objects.supportsMutation(this.item.identifier)) {
|
||||
this.mutablePromise = this.openmct.objects.getMutable(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
} else {
|
||||
this.openmct.objects.get(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
}
|
||||
|
||||
this.status = this.openmct.status.get(this.item.identifier);
|
||||
this.removeStatusListener = this.openmct.status.observe(this.item.identifier, this.setStatus);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.removeStatusListener();
|
||||
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
if (this.telemetryCollection) {
|
||||
this.telemetryCollection.off('add', this.setLatestValues);
|
||||
this.telemetryCollection.off('clear', this.refreshData);
|
||||
|
||||
this.telemetryCollection.destroy();
|
||||
}
|
||||
|
||||
if (this.mutablePromise) {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formattedValueForCopy() {
|
||||
const timeFormatterKey = this.openmct.time.timeSystem().key;
|
||||
const timeFormatter = this.formats[timeFormatterKey];
|
||||
const unit = this.unit ? ` ${this.unit}` : '';
|
||||
|
||||
return `At ${timeFormatter.format(this.datum)} ${this.domainObject.name} had a value of ${this.telemetryValue}${unit}`;
|
||||
},
|
||||
setLatestValues(data) {
|
||||
this.latestDatum = data[data.length - 1];
|
||||
this.updateView();
|
||||
},
|
||||
updateView() {
|
||||
if (!this.updatingView) {
|
||||
this.updatingView = true;
|
||||
requestAnimationFrame(() => {
|
||||
this.datum = this.latestDatum;
|
||||
this.updatingView = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
refreshData(bounds, isTick) {
|
||||
if (!isTick) {
|
||||
this.latestDatum = undefined;
|
||||
this.updateView();
|
||||
}
|
||||
},
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.mutablePromise = undefined;
|
||||
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.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
||||
|
||||
const valueMetadata = this.metadata ? this.metadata.value(this.item.value) : {};
|
||||
this.customStringformatter = this.openmct.telemetry.customStringFormatter(valueMetadata, this.item.format);
|
||||
|
||||
this.telemetryCollection = this.openmct.telemetry.requestCollection(this.domainObject, {
|
||||
size: 1,
|
||||
strategy: 'latest',
|
||||
timeContext: this.timeContext
|
||||
});
|
||||
this.telemetryCollection.on('add', this.setLatestValues);
|
||||
this.telemetryCollection.on('clear', this.refreshData);
|
||||
this.telemetryCollection.load();
|
||||
|
||||
this.currentObjectPath = this.objectPath.slice();
|
||||
this.currentObjectPath.unshift(this.domainObject);
|
||||
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index,
|
||||
updateTelemetryFormat: this.updateTelemetryFormat,
|
||||
toggleUnits: this.toggleUnits,
|
||||
showUnits: this.showUnits
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.immediatelySelect || this.initSelect);
|
||||
delete this.immediatelySelect;
|
||||
this.subscribeToStaleness(this.domainObject);
|
||||
},
|
||||
updateTelemetryFormat(format) {
|
||||
this.customStringformatter.setFormat(format);
|
||||
|
||||
this.$emit('formatChanged', this.item, format);
|
||||
},
|
||||
updateViewContext() {
|
||||
this.$emit('contextClick', {
|
||||
viewHistoricalData: true,
|
||||
formattedValueForCopy: this.formattedValueForCopy
|
||||
});
|
||||
},
|
||||
async getContextMenuActions() {
|
||||
const defaultNotebook = getDefaultNotebook();
|
||||
|
||||
let defaultNotebookName;
|
||||
if (defaultNotebook) {
|
||||
const domainObject = await this.openmct.objects.get(defaultNotebook.identifier);
|
||||
const { section, page } = getNotebookSectionAndPage(domainObject, defaultNotebook.defaultSectionId, defaultNotebook.defaultPageId);
|
||||
if (section && page) {
|
||||
const defaultPath = domainObject && `${domainObject.name} - ${section.name} - ${page.name}`;
|
||||
defaultNotebookName = `Copy to Notebook ${defaultPath}`;
|
||||
}
|
||||
}
|
||||
|
||||
return CONTEXT_MENU_ACTIONS
|
||||
.map(actionKey => {
|
||||
const action = this.openmct.actions.getAction(actionKey);
|
||||
if (action.key === 'copyToNotebook') {
|
||||
action.name = defaultNotebookName;
|
||||
}
|
||||
|
||||
return action;
|
||||
})
|
||||
.filter(action => action.name !== undefined);
|
||||
},
|
||||
async showContextMenu(event) {
|
||||
this.updateViewContext();
|
||||
const contextMenuActions = await this.getContextMenuActions();
|
||||
const menuItems = this.openmct.menus.actionsToMenuItems(contextMenuActions, this.currentObjectPath, this.currentView);
|
||||
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
||||
},
|
||||
setStatus(status) {
|
||||
this.status = status;
|
||||
}
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentObjectPath: undefined,
|
||||
datum: undefined,
|
||||
domainObject: undefined,
|
||||
formats: undefined,
|
||||
viewKey: `alphanumeric-format-${Math.random()}`,
|
||||
status: '',
|
||||
mutablePromise: undefined
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
itemClasses() {
|
||||
let classes = [];
|
||||
|
||||
if (this.status) {
|
||||
classes.push(`is-status--${this.status}`);
|
||||
}
|
||||
|
||||
if (this.isStale) {
|
||||
classes.push('is-stale');
|
||||
}
|
||||
|
||||
return classes;
|
||||
},
|
||||
showLabel() {
|
||||
let displayMode = this.item.displayMode;
|
||||
|
||||
return displayMode === 'all' || displayMode === 'label';
|
||||
},
|
||||
showValue() {
|
||||
let displayMode = this.item.displayMode;
|
||||
|
||||
return displayMode === 'all' || displayMode === 'value';
|
||||
},
|
||||
unit() {
|
||||
let value = this.item.value;
|
||||
let unit = this.metadata ? this.metadata.value(value).unit : '';
|
||||
|
||||
return unit;
|
||||
},
|
||||
styleObject() {
|
||||
let size;
|
||||
//for legacy size support
|
||||
if (!this.item.fontSize) {
|
||||
size = this.item.size;
|
||||
}
|
||||
|
||||
return Object.assign(
|
||||
{},
|
||||
{
|
||||
size
|
||||
},
|
||||
this.itemStyle
|
||||
);
|
||||
},
|
||||
fieldName() {
|
||||
return this.valueMetadata && this.valueMetadata.name;
|
||||
},
|
||||
valueMetadata() {
|
||||
return this.datum && this.metadata.value(this.item.value);
|
||||
},
|
||||
formatter() {
|
||||
if (this.item.format) {
|
||||
return this.customStringformatter;
|
||||
}
|
||||
|
||||
return this.formats[this.item.value];
|
||||
},
|
||||
telemetryValue() {
|
||||
if (!this.datum) {
|
||||
return '---';
|
||||
}
|
||||
|
||||
return this.formatter && this.formatter.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) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.openmct.objects.supportsMutation(this.item.identifier)) {
|
||||
this.mutablePromise = this.openmct.objects
|
||||
.getMutable(this.item.identifier)
|
||||
.then(this.setObject);
|
||||
} else {
|
||||
this.openmct.objects.get(this.item.identifier).then(this.setObject);
|
||||
}
|
||||
|
||||
this.status = this.openmct.status.get(this.item.identifier);
|
||||
this.removeStatusListener = this.openmct.status.observe(this.item.identifier, this.setStatus);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.removeStatusListener();
|
||||
|
||||
if (this.removeSelectable) {
|
||||
this.removeSelectable();
|
||||
}
|
||||
|
||||
if (this.telemetryCollection) {
|
||||
this.telemetryCollection.off('add', this.setLatestValues);
|
||||
this.telemetryCollection.off('clear', this.refreshData);
|
||||
|
||||
this.telemetryCollection.destroy();
|
||||
}
|
||||
|
||||
if (this.mutablePromise) {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formattedValueForCopy() {
|
||||
const timeFormatterKey = this.openmct.time.timeSystem().key;
|
||||
const timeFormatter = this.formats[timeFormatterKey];
|
||||
const unit = this.unit ? ` ${this.unit}` : '';
|
||||
|
||||
return `At ${timeFormatter.format(this.datum)} ${this.domainObject.name} had a value of ${
|
||||
this.telemetryValue
|
||||
}${unit}`;
|
||||
},
|
||||
setLatestValues(data) {
|
||||
this.latestDatum = data[data.length - 1];
|
||||
this.updateView();
|
||||
},
|
||||
updateView() {
|
||||
if (!this.updatingView) {
|
||||
this.updatingView = true;
|
||||
requestAnimationFrame(() => {
|
||||
this.datum = this.latestDatum;
|
||||
this.updatingView = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
refreshData(bounds, isTick) {
|
||||
if (!isTick) {
|
||||
this.latestDatum = undefined;
|
||||
this.updateView();
|
||||
}
|
||||
},
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.mutablePromise = undefined;
|
||||
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.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
||||
|
||||
const valueMetadata = this.metadata ? this.metadata.value(this.item.value) : {};
|
||||
this.customStringformatter = this.openmct.telemetry.customStringFormatter(
|
||||
valueMetadata,
|
||||
this.item.format
|
||||
);
|
||||
|
||||
this.telemetryCollection = this.openmct.telemetry.requestCollection(this.domainObject, {
|
||||
size: 1,
|
||||
strategy: 'latest',
|
||||
timeContext: this.timeContext
|
||||
});
|
||||
this.telemetryCollection.on('add', this.setLatestValues);
|
||||
this.telemetryCollection.on('clear', this.refreshData);
|
||||
this.telemetryCollection.load();
|
||||
|
||||
this.currentObjectPath = this.objectPath.slice();
|
||||
this.currentObjectPath.unshift(this.domainObject);
|
||||
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index,
|
||||
updateTelemetryFormat: this.updateTelemetryFormat,
|
||||
toggleUnits: this.toggleUnits,
|
||||
showUnits: this.showUnits
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el,
|
||||
this.context,
|
||||
this.immediatelySelect || this.initSelect
|
||||
);
|
||||
delete this.immediatelySelect;
|
||||
this.subscribeToStaleness(this.domainObject);
|
||||
},
|
||||
updateTelemetryFormat(format) {
|
||||
this.customStringformatter.setFormat(format);
|
||||
|
||||
this.$emit('formatChanged', this.item, format);
|
||||
},
|
||||
updateViewContext() {
|
||||
this.$emit('contextClick', {
|
||||
viewHistoricalData: true,
|
||||
formattedValueForCopy: this.formattedValueForCopy
|
||||
});
|
||||
},
|
||||
async getContextMenuActions() {
|
||||
const defaultNotebook = getDefaultNotebook();
|
||||
|
||||
let defaultNotebookName;
|
||||
if (defaultNotebook) {
|
||||
const domainObject = await this.openmct.objects.get(defaultNotebook.identifier);
|
||||
const { section, page } = getNotebookSectionAndPage(
|
||||
domainObject,
|
||||
defaultNotebook.defaultSectionId,
|
||||
defaultNotebook.defaultPageId
|
||||
);
|
||||
if (section && page) {
|
||||
const defaultPath =
|
||||
domainObject && `${domainObject.name} - ${section.name} - ${page.name}`;
|
||||
defaultNotebookName = `Copy to Notebook ${defaultPath}`;
|
||||
}
|
||||
}
|
||||
|
||||
return CONTEXT_MENU_ACTIONS.map((actionKey) => {
|
||||
const action = this.openmct.actions.getAction(actionKey);
|
||||
if (action.key === 'copyToNotebook') {
|
||||
action.name = defaultNotebookName;
|
||||
}
|
||||
|
||||
return action;
|
||||
}).filter((action) => action.name !== undefined);
|
||||
},
|
||||
async showContextMenu(event) {
|
||||
this.updateViewContext();
|
||||
const contextMenuActions = await this.getContextMenuActions();
|
||||
const menuItems = this.openmct.menus.actionsToMenuItems(
|
||||
contextMenuActions,
|
||||
this.currentObjectPath,
|
||||
this.currentView
|
||||
);
|
||||
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
||||
},
|
||||
setStatus(status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -21,111 +21,116 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<layout-frame
|
||||
<layout-frame
|
||||
:item="item"
|
||||
:grid-size="gridSize"
|
||||
:is-editing="isEditing"
|
||||
@move="(gridDelta) => $emit('move', gridDelta)"
|
||||
@endMove="() => $emit('endMove')"
|
||||
>
|
||||
>
|
||||
<div
|
||||
class="c-text-view u-style-receiver js-style-receiver"
|
||||
:data-font-size="item.fontSize"
|
||||
:data-font="item.font"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
class="c-text-view u-style-receiver js-style-receiver"
|
||||
:data-font-size="item.fontSize"
|
||||
:data-font="item.font"
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
>
|
||||
<div class="c-text-view__text">{{ item.text }}</div>
|
||||
<div class="c-text-view__text">{{ item.text }}</div>
|
||||
</div>
|
||||
</layout-frame>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue';
|
||||
import conditionalStylesMixin from "../mixins/objectStyles-mixin";
|
||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
fill: '',
|
||||
stroke: '',
|
||||
color: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
text: element.text,
|
||||
fontSize: 'default',
|
||||
font: 'default'
|
||||
};
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
fill: '',
|
||||
stroke: '',
|
||||
color: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
text: element.text,
|
||||
fontSize: 'default',
|
||||
font: 'default'
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
components: {
|
||||
LayoutFrame
|
||||
gridSize: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
|
||||
},
|
||||
mixins: [conditionalStylesMixin],
|
||||
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')
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
index: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let size;
|
||||
//legacy size support
|
||||
if (!this.item.fontSize) {
|
||||
size = this.item.size;
|
||||
}
|
||||
|
||||
return Object.assign({
|
||||
size
|
||||
}, this.itemStyle);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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();
|
||||
}
|
||||
initSelect: Boolean,
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let size;
|
||||
//legacy size support
|
||||
if (!this.item.fontSize) {
|
||||
size = this.item.size;
|
||||
}
|
||||
|
||||
return Object.assign(
|
||||
{
|
||||
size
|
||||
},
|
||||
this.itemStyle
|
||||
);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
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>
|
||||
|
@ -1,65 +1,66 @@
|
||||
.c-box-view,
|
||||
.c-ellipse-view {
|
||||
border-width: $drawingObjBorderW !important;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
border-width: $drawingObjBorderW !important;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
}
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
}
|
||||
}
|
||||
|
||||
.c-ellipse-view {
|
||||
border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.c-line-view {
|
||||
&.c-frame {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
&.c-frame {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.c-frame-edit {
|
||||
border: none;
|
||||
}
|
||||
.c-frame-edit {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.c-handle-info {
|
||||
background: rgba(#999, 0.2);
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
top: 5px; left: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.c-handle-info {
|
||||
background: rgba(#999, 0.2);
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
svg {
|
||||
// Prevent clipping when line is horizontal and vertical
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
// Must use !important to counteract setting in normalize.min.css
|
||||
overflow: visible;
|
||||
}
|
||||
svg {
|
||||
// Prevent clipping when line is horizontal and vertical
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
// Must use !important to counteract setting in normalize.min.css
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
&__line {
|
||||
stroke-linecap: round;
|
||||
stroke-width: $drawingObjBorderW;
|
||||
}
|
||||
&__line {
|
||||
stroke-linecap: round;
|
||||
stroke-width: $drawingObjBorderW;
|
||||
}
|
||||
|
||||
&__hover-indicator {
|
||||
display: none;
|
||||
opacity: 0.5;
|
||||
stroke: $editFrameColorHov;
|
||||
stroke-width: $drawingObjBorderW + 4;
|
||||
}
|
||||
&__hover-indicator {
|
||||
display: none;
|
||||
opacity: 0.5;
|
||||
stroke: $editFrameColorHov;
|
||||
stroke-width: $drawingObjBorderW + 4;
|
||||
}
|
||||
|
||||
.is-editing & {
|
||||
// Needed to allow line to be moved
|
||||
$w: 4px;
|
||||
min-width: $w;
|
||||
min-height: $w;
|
||||
.is-editing & {
|
||||
// Needed to allow line to be moved
|
||||
$w: 4px;
|
||||
min-width: $w;
|
||||
min-height: $w;
|
||||
|
||||
&:hover {
|
||||
[class*='__hover-indicator'] {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
[class*='__hover-indicator'] {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,96 +1,97 @@
|
||||
@mixin displayMarquee($c) {
|
||||
> .c-frame-edit {
|
||||
// All other frames
|
||||
//@include test($c, 0.4);
|
||||
display: block;
|
||||
}
|
||||
> .c-frame > .c-frame-edit {
|
||||
// Line object frame
|
||||
//@include test($c, 0.4);
|
||||
display: block;
|
||||
}
|
||||
> .c-frame-edit {
|
||||
// All other frames
|
||||
//@include test($c, 0.4);
|
||||
display: block;
|
||||
}
|
||||
> .c-frame > .c-frame-edit {
|
||||
// Line object frame
|
||||
//@include test($c, 0.4);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.l-layout {
|
||||
@include abs();
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
@include abs();
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
|
||||
&__grid-holder,
|
||||
&__dimensions {
|
||||
display: none;
|
||||
&__grid-holder,
|
||||
&__dimensions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__dimensions {
|
||||
$b: 1px dashed $editDimensionsColor;
|
||||
border-right: $b;
|
||||
border-bottom: $b;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
|
||||
&-vals {
|
||||
$p: 2px;
|
||||
color: $editDimensionsColor;
|
||||
display: inline-block;
|
||||
font-style: italic;
|
||||
position: absolute;
|
||||
bottom: $p;
|
||||
right: $p;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
&__dimensions {
|
||||
$b: 1px dashed $editDimensionsColor;
|
||||
border-right: $b;
|
||||
border-bottom: $b;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
|
||||
&-vals {
|
||||
$p: 2px;
|
||||
color: $editDimensionsColor;
|
||||
display: inline-block;
|
||||
font-style: italic;
|
||||
position: absolute;
|
||||
bottom: $p; right: $p;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
&__frame {
|
||||
position: absolute;
|
||||
}
|
||||
&__frame {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.is-editing {
|
||||
.l-shell__main-container {
|
||||
[s-selected],
|
||||
[s-selected-parent] {
|
||||
// Display grid and allow edit marquee to display in main layout holder when editing
|
||||
> .l-layout {
|
||||
background: $editUIGridColorBg;
|
||||
.l-shell__main-container {
|
||||
[s-selected],
|
||||
[s-selected-parent] {
|
||||
// Display grid and allow edit marquee to display in main layout holder when editing
|
||||
> .l-layout {
|
||||
background: $editUIGridColorBg;
|
||||
|
||||
> [class*="__dimensions"] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> [class*="__grid-holder"] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
> [class*='__dimensions'] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> [class*='__grid-holder'] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-layout__frame {
|
||||
&[s-selected]:not([multi-select="true"]),
|
||||
&[s-selected-parent] {
|
||||
// Display grid and allow edit marquee to display in nested layouts when editing
|
||||
> * > * > .l-layout.allow-editing {
|
||||
box-shadow: inset $editUIGridColorFg 0 0 2px 1px;
|
||||
.l-layout__frame {
|
||||
&[s-selected]:not([multi-select='true']),
|
||||
&[s-selected-parent] {
|
||||
// Display grid and allow edit marquee to display in nested layouts when editing
|
||||
> * > * > .l-layout.allow-editing {
|
||||
box-shadow: inset $editUIGridColorFg 0 0 2px 1px;
|
||||
|
||||
> [class*="__dimensions"] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> [class*='grid-holder'] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
> [class*='__dimensions'] {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> [class*='grid-holder'] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************** EDIT MARQUEE CONTROL */
|
||||
*[s-selected-parent] {
|
||||
> .l-layout {
|
||||
// When main shell layout is the parent
|
||||
@include displayMarquee(deeppink); // TEMP
|
||||
}
|
||||
> * > * > * {
|
||||
// When a sub-layout is the parent
|
||||
@include displayMarquee(blue);
|
||||
}
|
||||
/*********************** EDIT MARQUEE CONTROL */
|
||||
*[s-selected-parent] {
|
||||
> .l-layout {
|
||||
// When main shell layout is the parent
|
||||
@include displayMarquee(deeppink); // TEMP
|
||||
}
|
||||
> * > * > * {
|
||||
// When a sub-layout is the parent
|
||||
@include displayMarquee(blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +1,62 @@
|
||||
.c-frame-edit {
|
||||
// In Layouts, this is the editing rect and handles
|
||||
display: none; // Set to display: block in DisplayLayout.vue
|
||||
pointer-events: none;
|
||||
@include abs();
|
||||
border: $editMarqueeBorder;
|
||||
// In Layouts, this is the editing rect and handles
|
||||
display: none; // Set to display: block in DisplayLayout.vue
|
||||
pointer-events: none;
|
||||
@include abs();
|
||||
border: $editMarqueeBorder;
|
||||
|
||||
&__handle {
|
||||
$d: 6px;
|
||||
$o: floor($d * -0.5);
|
||||
background: $editFrameColorHandleFg;
|
||||
box-shadow: $editFrameColorHandleBg 0 0 0 2px;
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
width: $d; height: $d;
|
||||
top: auto; right: auto; bottom: auto; left: auto;
|
||||
&__handle {
|
||||
$d: 6px;
|
||||
$o: floor($d * -0.5);
|
||||
background: $editFrameColorHandleFg;
|
||||
box-shadow: $editFrameColorHandleBg 0 0 0 2px;
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
width: $d;
|
||||
height: $d;
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
|
||||
&:before {
|
||||
// Extended hit area
|
||||
@include abs(-10px);
|
||||
content: '';
|
||||
display: block;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $editUIColor;
|
||||
}
|
||||
|
||||
&--nwse {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
|
||||
&--nw {
|
||||
cursor: nw-resize;
|
||||
left: $o; top: $o;
|
||||
}
|
||||
|
||||
&--ne {
|
||||
cursor: ne-resize;
|
||||
right: $o; top: $o;
|
||||
}
|
||||
|
||||
&--se {
|
||||
cursor: se-resize;
|
||||
right: $o; bottom: $o;
|
||||
}
|
||||
|
||||
&--sw {
|
||||
cursor: sw-resize;
|
||||
left: $o; bottom: $o;
|
||||
}
|
||||
&:before {
|
||||
// Extended hit area
|
||||
@include abs(-10px);
|
||||
content: '';
|
||||
display: block;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $editUIColor;
|
||||
}
|
||||
|
||||
&--nwse {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
|
||||
&--nw {
|
||||
cursor: nw-resize;
|
||||
left: $o;
|
||||
top: $o;
|
||||
}
|
||||
|
||||
&--ne {
|
||||
cursor: ne-resize;
|
||||
right: $o;
|
||||
top: $o;
|
||||
}
|
||||
|
||||
&--se {
|
||||
cursor: se-resize;
|
||||
right: $o;
|
||||
bottom: $o;
|
||||
}
|
||||
|
||||
&--sw {
|
||||
cursor: sw-resize;
|
||||
left: $o;
|
||||
bottom: $o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
.c-image-view {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
|
@ -2,134 +2,134 @@
|
||||
|
||||
/******************* FRAME */
|
||||
.c-frame {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// Whatever is placed into the slot, make it fill the entirety of the space, obeying padding
|
||||
> *:first-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
// Whatever is placed into the slot, make it fill the entirety of the space, obeying padding
|
||||
> *:first-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.c-frame__move-bar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.is-editing {
|
||||
/******************* STYLES FOR C-FRAME WHILE EDITING */
|
||||
.c-frame {
|
||||
border: 1px solid rgba($editFrameColorHov, 0.3);
|
||||
/******************* STYLES FOR C-FRAME WHILE EDITING */
|
||||
.c-frame {
|
||||
border: 1px solid rgba($editFrameColorHov, 0.3);
|
||||
|
||||
&:not([s-selected]) {
|
||||
&:hover {
|
||||
border: $editFrameBorderHov;
|
||||
}
|
||||
}
|
||||
|
||||
&[s-selected] {
|
||||
// All frames selected while editing
|
||||
box-shadow: $editFrameSelectedShdw;
|
||||
|
||||
.c-frame__move-bar {
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
&:not([s-selected]) {
|
||||
&:hover {
|
||||
border: $editFrameBorderHov;
|
||||
}
|
||||
}
|
||||
|
||||
/******************* DEFAULT STYLES FOR -EDIT__MOVE */
|
||||
// All object types
|
||||
.c-frame__move-bar {
|
||||
@include abs();
|
||||
display: block;
|
||||
&[s-selected] {
|
||||
// All frames selected while editing
|
||||
box-shadow: $editFrameSelectedShdw;
|
||||
|
||||
.c-frame__move-bar {
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************* DEFAULT STYLES FOR -EDIT__MOVE */
|
||||
// All object types
|
||||
.c-frame__move-bar {
|
||||
@include abs();
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Has-complex-content objects
|
||||
.c-so-view.has-complex-content {
|
||||
@include transition($prop: transform, $dur: $transOutTime, $delay: $moveBarOutDelay);
|
||||
|
||||
> .c-so-view__local-controls {
|
||||
@include transition($prop: transform, $dur: 250ms, $delay: $moveBarOutDelay);
|
||||
}
|
||||
|
||||
// Has-complex-content objects
|
||||
.c-so-view.has-complex-content {
|
||||
@include transition($prop: transform, $dur: $transOutTime, $delay: $moveBarOutDelay);
|
||||
+ .c-frame__move-bar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
> .c-so-view__local-controls {
|
||||
@include transition($prop: transform, $dur: 250ms, $delay: $moveBarOutDelay);
|
||||
.l-layout {
|
||||
/******************* 0 - 1 ITEM SELECTED */
|
||||
&:not(.is-multi-selected) {
|
||||
> .l-layout__frame {
|
||||
> .c-so-view.has-complex-content {
|
||||
> .c-so-view__local-controls {
|
||||
@include transition($prop: transform, $dur: $transOutTime, $delay: $moveBarOutDelay);
|
||||
}
|
||||
|
||||
+ .c-frame__move-bar {
|
||||
@include transition($prop: height, $delay: $moveBarOutDelay);
|
||||
@include userSelectNone();
|
||||
background: $editFrameMovebarColorBg;
|
||||
box-shadow: rgba(black, 0.3) 0 2px;
|
||||
bottom: auto;
|
||||
display: block;
|
||||
height: 0; // Height is set on hover below
|
||||
opacity: 0.9;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
z-index: 10;
|
||||
|
||||
&:before {
|
||||
// Grippy
|
||||
$h: 4px;
|
||||
$tbOffset: math.div($editFrameMovebarH - $h, 2);
|
||||
$lrOffset: 25%;
|
||||
@include grippy($editFrameMovebarColorFg);
|
||||
content: '';
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: $tbOffset;
|
||||
right: $lrOffset;
|
||||
bottom: $tbOffset;
|
||||
left: $lrOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ .c-frame__move-bar {
|
||||
display: none;
|
||||
&:hover {
|
||||
> .c-so-view.has-complex-content {
|
||||
transition: $transInTransform;
|
||||
transition-delay: 0s;
|
||||
|
||||
> .c-so-view__local-controls {
|
||||
transform: translateY($editFrameMovebarH);
|
||||
@include transition(height, $transOutTime);
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
+ .c-frame__move-bar {
|
||||
@include transition(height);
|
||||
height: $editFrameMovebarH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .l-layout__frame[s-selected] {
|
||||
> .c-so-view.has-complex-content {
|
||||
+ .c-frame__move-bar:before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-layout {
|
||||
/******************* 0 - 1 ITEM SELECTED */
|
||||
&:not(.is-multi-selected) {
|
||||
> .l-layout__frame {
|
||||
> .c-so-view.has-complex-content {
|
||||
> .c-so-view__local-controls {
|
||||
@include transition($prop: transform, $dur: $transOutTime, $delay: $moveBarOutDelay);
|
||||
}
|
||||
|
||||
+ .c-frame__move-bar {
|
||||
@include transition($prop: height, $delay: $moveBarOutDelay);
|
||||
@include userSelectNone();
|
||||
background: $editFrameMovebarColorBg;
|
||||
box-shadow: rgba(black, 0.3) 0 2px;
|
||||
bottom: auto;
|
||||
display: block;
|
||||
height: 0; // Height is set on hover below
|
||||
opacity: 0.9;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
z-index: 10;
|
||||
|
||||
&:before {
|
||||
// Grippy
|
||||
$h: 4px;
|
||||
$tbOffset: math.div($editFrameMovebarH - $h, 2);
|
||||
$lrOffset: 25%;
|
||||
@include grippy($editFrameMovebarColorFg);
|
||||
content: '';
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: $tbOffset;
|
||||
right: $lrOffset;
|
||||
bottom: $tbOffset;
|
||||
left: $lrOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> .c-so-view.has-complex-content {
|
||||
transition: $transInTransform;
|
||||
transition-delay: 0s;
|
||||
|
||||
> .c-so-view__local-controls {
|
||||
transform: translateY($editFrameMovebarH);
|
||||
@include transition(height, $transOutTime);
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
+ .c-frame__move-bar {
|
||||
@include transition(height);
|
||||
height: $editFrameMovebarH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .l-layout__frame[s-selected] {
|
||||
> .c-so-view.has-complex-content {
|
||||
+ .c-frame__move-bar:before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************* > 1 ITEMS SELECTED */
|
||||
&.is-multi-selected {
|
||||
.l-layout__frame[s-selected] {
|
||||
> .c-so-view.has-complex-content + .c-frame__move-bar {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
/******************* > 1 ITEMS SELECTED */
|
||||
&.is-multi-selected {
|
||||
.l-layout__frame[s-selected] {
|
||||
> .c-so-view.has-complex-content + .c-frame__move-bar {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,48 @@
|
||||
.c-telemetry-view {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
|
||||
> * {
|
||||
// Label and value holders
|
||||
flex: 1 1 50%;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
padding: $interiorMargin;
|
||||
|
||||
> * {
|
||||
// Label and value holders
|
||||
flex: 1 1 50%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
padding: $interiorMargin;
|
||||
|
||||
> * {
|
||||
// Text elements
|
||||
@include ellipsize();
|
||||
}
|
||||
// Text elements
|
||||
@include ellipsize();
|
||||
}
|
||||
}
|
||||
|
||||
&__value {
|
||||
@include isLimit();
|
||||
}
|
||||
&__value {
|
||||
@include isLimit();
|
||||
}
|
||||
|
||||
&__label {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
&__label {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
|
||||
&.is-stale {
|
||||
.c-telemetry-view__value {
|
||||
@include isStaleElement();
|
||||
}
|
||||
&.is-stale {
|
||||
.c-telemetry-view__value {
|
||||
@include isStaleElement();
|
||||
}
|
||||
}
|
||||
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.is-status__indicator {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.is-status__indicator {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&[class*='is-status'] {
|
||||
border: $borderMissing;
|
||||
}
|
||||
&[class*='is-status'] {
|
||||
border: $borderMissing;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
.c-text-view {
|
||||
display: flex;
|
||||
align-items: center; // Vertically center text
|
||||
overflow: hidden;
|
||||
padding: $interiorMargin;
|
||||
display: flex;
|
||||
align-items: center; // Vertically center text
|
||||
overflow: hidden;
|
||||
padding: $interiorMargin;
|
||||
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
|
@ -20,64 +20,75 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
|
||||
import {getStylesWithoutNoneValue} from "@/plugins/condition/utils/styleUtils";
|
||||
import StyleRuleManager from '@/plugins/condition/StyleRuleManager';
|
||||
import { getStylesWithoutNoneValue } from '@/plugins/condition/utils/styleUtils';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
return {
|
||||
objectStyle: undefined,
|
||||
itemStyle: undefined,
|
||||
styleClass: ''
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.parentDomainObject = this.$parent.domainObject;
|
||||
this.itemId = this.item.id;
|
||||
this.objectStyle = this.getObjectStyleForItem(this.parentDomainObject.configuration.objectStyles);
|
||||
this.initObjectStyles();
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.stopListeningObjectStyles) {
|
||||
this.stopListeningObjectStyles();
|
||||
}
|
||||
|
||||
if (this.styleRuleManager) {
|
||||
this.styleRuleManager.destroy();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getObjectStyleForItem(objectStyle) {
|
||||
if (objectStyle) {
|
||||
return objectStyle[this.itemId] ? Object.assign({}, objectStyle[this.itemId]) : undefined;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
initObjectStyles() {
|
||||
if (!this.styleRuleManager) {
|
||||
this.styleRuleManager = new StyleRuleManager(this.objectStyle, this.openmct, this.updateStyle.bind(this), true);
|
||||
} else {
|
||||
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||
}
|
||||
|
||||
if (this.stopListeningObjectStyles) {
|
||||
this.stopListeningObjectStyles();
|
||||
}
|
||||
|
||||
this.stopListeningObjectStyles = this.openmct.objects.observe(this.parentDomainObject, 'configuration.objectStyles', (newObjectStyle) => {
|
||||
//Updating object styles in the inspector view will trigger this so that the changes are reflected immediately
|
||||
let newItemObjectStyle = this.getObjectStyleForItem(newObjectStyle);
|
||||
if (this.objectStyle !== newItemObjectStyle) {
|
||||
this.objectStyle = newItemObjectStyle;
|
||||
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||
}
|
||||
});
|
||||
},
|
||||
updateStyle(style) {
|
||||
this.itemStyle = getStylesWithoutNoneValue(style);
|
||||
this.styleClass = this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
}
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
return {
|
||||
objectStyle: undefined,
|
||||
itemStyle: undefined,
|
||||
styleClass: ''
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.parentDomainObject = this.$parent.domainObject;
|
||||
this.itemId = this.item.id;
|
||||
this.objectStyle = this.getObjectStyleForItem(
|
||||
this.parentDomainObject.configuration.objectStyles
|
||||
);
|
||||
this.initObjectStyles();
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.stopListeningObjectStyles) {
|
||||
this.stopListeningObjectStyles();
|
||||
}
|
||||
|
||||
if (this.styleRuleManager) {
|
||||
this.styleRuleManager.destroy();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getObjectStyleForItem(objectStyle) {
|
||||
if (objectStyle) {
|
||||
return objectStyle[this.itemId] ? Object.assign({}, objectStyle[this.itemId]) : undefined;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
initObjectStyles() {
|
||||
if (!this.styleRuleManager) {
|
||||
this.styleRuleManager = new StyleRuleManager(
|
||||
this.objectStyle,
|
||||
this.openmct,
|
||||
this.updateStyle.bind(this),
|
||||
true
|
||||
);
|
||||
} else {
|
||||
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||
}
|
||||
|
||||
if (this.stopListeningObjectStyles) {
|
||||
this.stopListeningObjectStyles();
|
||||
}
|
||||
|
||||
this.stopListeningObjectStyles = this.openmct.objects.observe(
|
||||
this.parentDomainObject,
|
||||
'configuration.objectStyles',
|
||||
(newObjectStyle) => {
|
||||
//Updating object styles in the inspector view will trigger this so that the changes are reflected immediately
|
||||
let newItemObjectStyle = this.getObjectStyleForItem(newObjectStyle);
|
||||
if (this.objectStyle !== newItemObjectStyle) {
|
||||
this.objectStyle = newItemObjectStyle;
|
||||
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
updateStyle(style) {
|
||||
this.itemStyle = getStylesWithoutNoneValue(style);
|
||||
this.styleClass = this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -32,105 +32,108 @@ import objectUtils from 'objectUtils';
|
||||
import Vue from 'vue';
|
||||
|
||||
class DisplayLayoutView {
|
||||
constructor(openmct, domainObject, objectPath, options) {
|
||||
this.openmct = openmct;
|
||||
this.domainObject = domainObject;
|
||||
this.objectPath = objectPath;
|
||||
this.options = options;
|
||||
constructor(openmct, domainObject, objectPath, options) {
|
||||
this.openmct = openmct;
|
||||
this.domainObject = domainObject;
|
||||
this.objectPath = objectPath;
|
||||
this.options = options;
|
||||
|
||||
this.component = undefined;
|
||||
}
|
||||
this.component = undefined;
|
||||
}
|
||||
|
||||
show(container, isEditing) {
|
||||
this.component = new Vue({
|
||||
el: container,
|
||||
components: {
|
||||
DisplayLayout
|
||||
},
|
||||
provide: {
|
||||
openmct: this.openmct,
|
||||
objectPath: this.objectPath,
|
||||
options: this.options,
|
||||
objectUtils,
|
||||
currentView: this
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
domainObject: this.domainObject,
|
||||
isEditing
|
||||
};
|
||||
},
|
||||
template: '<display-layout ref="displayLayout" :domain-object="domainObject" :is-editing="isEditing"></display-layout>'
|
||||
});
|
||||
}
|
||||
|
||||
getViewContext() {
|
||||
if (!this.component) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return this.component.$refs.displayLayout.getViewContext();
|
||||
}
|
||||
|
||||
getSelectionContext() {
|
||||
show(container, isEditing) {
|
||||
this.component = new Vue({
|
||||
el: container,
|
||||
components: {
|
||||
DisplayLayout
|
||||
},
|
||||
provide: {
|
||||
openmct: this.openmct,
|
||||
objectPath: this.objectPath,
|
||||
options: this.options,
|
||||
objectUtils,
|
||||
currentView: this
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
item: this.domainObject,
|
||||
supportsMultiSelect: true,
|
||||
addElement: this.component && this.component.$refs.displayLayout.addElement,
|
||||
removeItem: this.component && this.component.$refs.displayLayout.removeItem,
|
||||
orderItem: this.component && this.component.$refs.displayLayout.orderItem,
|
||||
duplicateItem: this.component && this.component.$refs.displayLayout.duplicateItem,
|
||||
switchViewType: this.component && this.component.$refs.displayLayout.switchViewType,
|
||||
mergeMultipleTelemetryViews: this.component && this.component.$refs.displayLayout.mergeMultipleTelemetryViews,
|
||||
mergeMultipleOverlayPlots: this.component && this.component.$refs.displayLayout.mergeMultipleOverlayPlots,
|
||||
toggleGrid: this.component && this.component.$refs.displayLayout.toggleGrid
|
||||
domainObject: this.domainObject,
|
||||
isEditing
|
||||
};
|
||||
},
|
||||
template:
|
||||
'<display-layout ref="displayLayout" :domain-object="domainObject" :is-editing="isEditing"></display-layout>'
|
||||
});
|
||||
}
|
||||
|
||||
getViewContext() {
|
||||
if (!this.component) {
|
||||
return {};
|
||||
}
|
||||
|
||||
onEditModeChange(isEditing) {
|
||||
this.component.isEditing = isEditing;
|
||||
}
|
||||
return this.component.$refs.displayLayout.getViewContext();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.component.$destroy();
|
||||
this.component = undefined;
|
||||
}
|
||||
getSelectionContext() {
|
||||
return {
|
||||
item: this.domainObject,
|
||||
supportsMultiSelect: true,
|
||||
addElement: this.component && this.component.$refs.displayLayout.addElement,
|
||||
removeItem: this.component && this.component.$refs.displayLayout.removeItem,
|
||||
orderItem: this.component && this.component.$refs.displayLayout.orderItem,
|
||||
duplicateItem: this.component && this.component.$refs.displayLayout.duplicateItem,
|
||||
switchViewType: this.component && this.component.$refs.displayLayout.switchViewType,
|
||||
mergeMultipleTelemetryViews:
|
||||
this.component && this.component.$refs.displayLayout.mergeMultipleTelemetryViews,
|
||||
mergeMultipleOverlayPlots:
|
||||
this.component && this.component.$refs.displayLayout.mergeMultipleOverlayPlots,
|
||||
toggleGrid: this.component && this.component.$refs.displayLayout.toggleGrid
|
||||
};
|
||||
}
|
||||
|
||||
onEditModeChange(isEditing) {
|
||||
this.component.isEditing = isEditing;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.component.$destroy();
|
||||
this.component = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export default function DisplayLayoutPlugin(options) {
|
||||
return function (openmct) {
|
||||
openmct.actions.register(new CopyToClipboardAction(openmct));
|
||||
return function (openmct) {
|
||||
openmct.actions.register(new CopyToClipboardAction(openmct));
|
||||
|
||||
openmct.objectViews.addProvider({
|
||||
key: 'layout.view',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
view: function (domainObject, objectPath) {
|
||||
return new DisplayLayoutView(openmct, domainObject, objectPath, options);
|
||||
},
|
||||
priority() {
|
||||
return 100;
|
||||
}
|
||||
});
|
||||
openmct.types.addType('layout', DisplayLayoutType());
|
||||
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct));
|
||||
openmct.inspectorViews.addProvider(new AlphaNumericFormatViewProvider(openmct, options));
|
||||
openmct.composition.addPolicy((parent, child) => {
|
||||
if (parent.type === 'layout' && child.type === 'folder') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
openmct.objectViews.addProvider({
|
||||
key: 'layout.view',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
view: function (domainObject, objectPath) {
|
||||
return new DisplayLayoutView(openmct, domainObject, objectPath, options);
|
||||
},
|
||||
priority() {
|
||||
return 100;
|
||||
}
|
||||
});
|
||||
openmct.types.addType('layout', DisplayLayoutType());
|
||||
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct));
|
||||
openmct.inspectorViews.addProvider(new AlphaNumericFormatViewProvider(openmct, options));
|
||||
openmct.composition.addPolicy((parent, child) => {
|
||||
if (parent.type === 'layout' && child.type === 'folder') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
for (const [type, definition] of Object.entries(DisplayLayoutDrawingObjectTypes)) {
|
||||
openmct.types.addType(type, definition);
|
||||
}
|
||||
for (const [type, definition] of Object.entries(DisplayLayoutDrawingObjectTypes)) {
|
||||
openmct.types.addType(type, definition);
|
||||
}
|
||||
|
||||
DisplayLayoutPlugin._installed = true;
|
||||
};
|
||||
DisplayLayoutPlugin._installed = true;
|
||||
};
|
||||
}
|
||||
|
@ -25,416 +25,407 @@ import Vue from 'vue';
|
||||
import DisplayLayoutPlugin from './plugin';
|
||||
|
||||
describe('the plugin', function () {
|
||||
let element;
|
||||
let child;
|
||||
let openmct;
|
||||
let displayLayoutDefinition;
|
||||
let element;
|
||||
let child;
|
||||
let openmct;
|
||||
let displayLayoutDefinition;
|
||||
|
||||
beforeEach((done) => {
|
||||
openmct = createOpenMct();
|
||||
openmct.install(
|
||||
new DisplayLayoutPlugin({
|
||||
showAsView: []
|
||||
})
|
||||
);
|
||||
displayLayoutDefinition = openmct.types.get('layout');
|
||||
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.start(child);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
return resetApplicationState(openmct);
|
||||
});
|
||||
|
||||
it('defines a display layout object type with the correct key', () => {
|
||||
expect(displayLayoutDefinition.definition.name).toEqual('Display Layout');
|
||||
});
|
||||
|
||||
it('provides a view', () => {
|
||||
const testViewObject = {
|
||||
id: 'test-object',
|
||||
type: 'layout',
|
||||
configuration: {
|
||||
items: [
|
||||
{
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
},
|
||||
x: 8,
|
||||
y: 3,
|
||||
width: 10,
|
||||
height: 5,
|
||||
displayMode: 'all',
|
||||
value: 'sin',
|
||||
stroke: '',
|
||||
fill: '',
|
||||
color: '',
|
||||
size: '13px',
|
||||
type: 'telemetry-view',
|
||||
id: 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
|
||||
}
|
||||
],
|
||||
layoutGrid: [10, 10]
|
||||
}
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject, []);
|
||||
let displayLayoutViewProvider = applicableViews.find(
|
||||
(viewProvider) => viewProvider.key === 'layout.view'
|
||||
);
|
||||
expect(displayLayoutViewProvider).toBeDefined();
|
||||
});
|
||||
|
||||
it('renders a display layout view without errors', () => {
|
||||
const testViewObject = {
|
||||
identifier: {
|
||||
namespace: 'test-namespace',
|
||||
key: 'test-key'
|
||||
},
|
||||
type: 'layout',
|
||||
configuration: {
|
||||
items: [],
|
||||
layoutGrid: [10, 10]
|
||||
},
|
||||
composition: []
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject, []);
|
||||
let displayLayoutViewProvider = applicableViews.find(
|
||||
(viewProvider) => viewProvider.key === 'layout.view'
|
||||
);
|
||||
let view = displayLayoutViewProvider.view(testViewObject);
|
||||
let error;
|
||||
|
||||
try {
|
||||
view.show(child, false);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
|
||||
describe('on load', () => {
|
||||
let displayLayoutItem;
|
||||
let item;
|
||||
|
||||
beforeEach((done) => {
|
||||
openmct = createOpenMct();
|
||||
openmct.install(new DisplayLayoutPlugin({
|
||||
showAsView: []
|
||||
}));
|
||||
displayLayoutDefinition = openmct.types.get('layout');
|
||||
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.start(child);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
return resetApplicationState(openmct);
|
||||
});
|
||||
|
||||
it('defines a display layout object type with the correct key', () => {
|
||||
expect(displayLayoutDefinition.definition.name).toEqual('Display Layout');
|
||||
});
|
||||
|
||||
it('provides a view', () => {
|
||||
const testViewObject = {
|
||||
id: 'test-object',
|
||||
type: 'layout',
|
||||
configuration: {
|
||||
items: [
|
||||
{
|
||||
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
},
|
||||
'x': 8,
|
||||
'y': 3,
|
||||
'width': 10,
|
||||
'height': 5,
|
||||
'displayMode': 'all',
|
||||
'value': 'sin',
|
||||
'stroke': '',
|
||||
'fill': '',
|
||||
'color': '',
|
||||
'size': '13px',
|
||||
'type': 'telemetry-view',
|
||||
'id': 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
|
||||
|
||||
}
|
||||
],
|
||||
layoutGrid: [10, 10]
|
||||
}
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject, []);
|
||||
let displayLayoutViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'layout.view');
|
||||
expect(displayLayoutViewProvider).toBeDefined();
|
||||
});
|
||||
|
||||
it('renders a display layout view without errors', () => {
|
||||
const testViewObject = {
|
||||
identifier: {
|
||||
namespace: 'test-namespace',
|
||||
key: 'test-key'
|
||||
},
|
||||
type: 'layout',
|
||||
configuration: {
|
||||
items: [],
|
||||
layoutGrid: [10, 10]
|
||||
},
|
||||
composition: []
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject, []);
|
||||
let displayLayoutViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'layout.view');
|
||||
let view = displayLayoutViewProvider.view(testViewObject);
|
||||
let error;
|
||||
|
||||
try {
|
||||
view.show(child, false);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
item = {
|
||||
width: 32,
|
||||
height: 18,
|
||||
x: 78,
|
||||
y: 8,
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
|
||||
},
|
||||
hasFrame: true,
|
||||
type: 'line-view', // so no telemetry functionality is triggered, just want to test the sync
|
||||
id: 'c0ff485a-344c-4e70-8d83-a9d9998a69fc'
|
||||
};
|
||||
displayLayoutItem = {
|
||||
composition: [
|
||||
// no item in compostion, but item in configuration items
|
||||
],
|
||||
configuration: {
|
||||
items: [item],
|
||||
layoutGrid: [10, 10]
|
||||
},
|
||||
name: 'Display Layout',
|
||||
type: 'layout',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'c5e636c1-6771-4c9c-b933-8665cab189b3'
|
||||
}
|
||||
};
|
||||
|
||||
expect(error).toBeUndefined();
|
||||
const applicableViews = openmct.objectViews.get(displayLayoutItem, []);
|
||||
const displayLayoutViewProvider = applicableViews.find(
|
||||
(viewProvider) => viewProvider.key === 'layout.view'
|
||||
);
|
||||
const view = displayLayoutViewProvider.view(displayLayoutItem);
|
||||
view.show(child, false);
|
||||
|
||||
Vue.nextTick(done);
|
||||
});
|
||||
|
||||
describe('on load', () => {
|
||||
let displayLayoutItem;
|
||||
let item;
|
||||
it('will sync compostion and layout items', () => {
|
||||
expect(displayLayoutItem.configuration.items.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach((done) => {
|
||||
item = {
|
||||
'width': 32,
|
||||
'height': 18,
|
||||
'x': 78,
|
||||
'y': 8,
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
|
||||
},
|
||||
'hasFrame': true,
|
||||
'type': 'line-view', // so no telemetry functionality is triggered, just want to test the sync
|
||||
'id': 'c0ff485a-344c-4e70-8d83-a9d9998a69fc'
|
||||
describe('the alpha numeric format view', () => {
|
||||
let displayLayoutItem;
|
||||
let telemetryItem;
|
||||
let selection;
|
||||
|
||||
};
|
||||
displayLayoutItem = {
|
||||
'composition': [
|
||||
// no item in compostion, but item in configuration items
|
||||
beforeEach(() => {
|
||||
displayLayoutItem = {
|
||||
composition: [],
|
||||
configuration: {
|
||||
items: [
|
||||
{
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
},
|
||||
x: 8,
|
||||
y: 3,
|
||||
width: 10,
|
||||
height: 5,
|
||||
displayMode: 'all',
|
||||
value: 'sin',
|
||||
stroke: '',
|
||||
fill: '',
|
||||
color: '',
|
||||
size: '13px',
|
||||
type: 'telemetry-view',
|
||||
id: 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
|
||||
}
|
||||
],
|
||||
layoutGrid: [10, 10]
|
||||
},
|
||||
name: 'Display Layout',
|
||||
type: 'layout',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'c5e636c1-6771-4c9c-b933-8665cab189b3'
|
||||
}
|
||||
};
|
||||
telemetryItem = {
|
||||
telemetry: {
|
||||
period: 5,
|
||||
amplitude: 5,
|
||||
offset: 5,
|
||||
dataRateInHz: 5,
|
||||
phase: 5,
|
||||
randomness: 0
|
||||
},
|
||||
name: 'Sine Wave Generator',
|
||||
type: 'generator',
|
||||
modified: 1592851063871,
|
||||
location: 'mine',
|
||||
persisted: 1592851063871,
|
||||
id: '55122607-e65e-44d5-9c9d-9c31a914ca89',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
}
|
||||
};
|
||||
selection = [
|
||||
[
|
||||
{
|
||||
context: {
|
||||
layoutItem: displayLayoutItem.configuration.items[0],
|
||||
item: telemetryItem,
|
||||
index: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
supportsMultiSelect: true
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
});
|
||||
|
||||
it('provides an alphanumeric format view', () => {
|
||||
const displayLayoutAlphaNumFormatView = openmct.inspectorViews.get(selection);
|
||||
expect(displayLayoutAlphaNumFormatView.length).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('the toolbar', () => {
|
||||
let displayLayoutItem;
|
||||
let selection;
|
||||
|
||||
beforeEach(() => {
|
||||
displayLayoutItem = {
|
||||
composition: [],
|
||||
configuration: {
|
||||
items: [
|
||||
{
|
||||
fill: '#666666',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 5,
|
||||
type: 'box-view',
|
||||
id: '89b88746-d325-487b-aec4-11b79afff9e8'
|
||||
},
|
||||
{
|
||||
fill: '#666666',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
height: 10,
|
||||
type: 'ellipse-view',
|
||||
id: '19b88746-d325-487b-aec4-11b79afff9z8'
|
||||
},
|
||||
{
|
||||
x: 18,
|
||||
y: 9,
|
||||
x2: 23,
|
||||
y2: 4,
|
||||
stroke: '#666666',
|
||||
type: 'line-view',
|
||||
id: '57d49a28-7863-43bd-9593-6570758916f0'
|
||||
},
|
||||
{
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
},
|
||||
x: 8,
|
||||
y: 3,
|
||||
width: 10,
|
||||
height: 5,
|
||||
displayMode: 'all',
|
||||
value: 'sin',
|
||||
stroke: '',
|
||||
fill: '',
|
||||
color: '',
|
||||
size: '13px',
|
||||
type: 'telemetry-view',
|
||||
id: 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
|
||||
},
|
||||
{
|
||||
width: 32,
|
||||
height: 18,
|
||||
x: 78,
|
||||
y: 8,
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
|
||||
},
|
||||
hasFrame: true,
|
||||
type: 'subobject-view',
|
||||
id: 'c0ff485a-344c-4e70-8d83-a9d9998a69fc'
|
||||
}
|
||||
],
|
||||
layoutGrid: [10, 10]
|
||||
},
|
||||
name: 'Display Layout',
|
||||
type: 'layout',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'c5e636c1-6771-4c9c-b933-8665cab189b3'
|
||||
}
|
||||
};
|
||||
selection = [
|
||||
[
|
||||
{
|
||||
context: {
|
||||
layoutItem: displayLayoutItem.configuration.items[1],
|
||||
index: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
supportsMultiSelect: true
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
context: {
|
||||
layoutItem: displayLayoutItem.configuration.items[0],
|
||||
index: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
supportsMultiSelect: true
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
context: {
|
||||
layoutItem: displayLayoutItem.configuration.items[2],
|
||||
item: displayLayoutItem.configuration.items[2],
|
||||
index: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
supportsMultiSelect: true
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
context: {
|
||||
item: {
|
||||
composition: [
|
||||
{
|
||||
namespace: '',
|
||||
key: '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
}
|
||||
],
|
||||
'configuration': {
|
||||
'items': [
|
||||
item
|
||||
],
|
||||
'layoutGrid': [
|
||||
10,
|
||||
10
|
||||
]
|
||||
configuration: {
|
||||
series: [
|
||||
{
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: {},
|
||||
xAxis: {}
|
||||
},
|
||||
'name': 'Display Layout',
|
||||
'type': 'layout',
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': 'c5e636c1-6771-4c9c-b933-8665cab189b3'
|
||||
}
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(displayLayoutItem, []);
|
||||
const displayLayoutViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'layout.view');
|
||||
const view = displayLayoutViewProvider.view(displayLayoutItem);
|
||||
view.show(child, false);
|
||||
|
||||
Vue.nextTick(done);
|
||||
});
|
||||
|
||||
it('will sync compostion and layout items', () => {
|
||||
expect(displayLayoutItem.configuration.items.length).toBe(0);
|
||||
});
|
||||
name: 'Unnamed Overlay Plot',
|
||||
type: 'telemetry.plot.overlay',
|
||||
modified: 1594142141929,
|
||||
location: 'mine',
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
|
||||
},
|
||||
persisted: 1594142141929
|
||||
},
|
||||
layoutItem: displayLayoutItem.configuration.items[3],
|
||||
index: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
supportsMultiSelect: true
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
});
|
||||
|
||||
describe('the alpha numeric format view', () => {
|
||||
let displayLayoutItem;
|
||||
let telemetryItem;
|
||||
let selection;
|
||||
it('provides controls including separators', () => {
|
||||
const displayLayoutToolbar = openmct.toolbars.get(selection);
|
||||
|
||||
beforeEach(() => {
|
||||
displayLayoutItem = {
|
||||
'composition': [
|
||||
],
|
||||
'configuration': {
|
||||
'items': [
|
||||
{
|
||||
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
},
|
||||
'x': 8,
|
||||
'y': 3,
|
||||
'width': 10,
|
||||
'height': 5,
|
||||
'displayMode': 'all',
|
||||
'value': 'sin',
|
||||
'stroke': '',
|
||||
'fill': '',
|
||||
'color': '',
|
||||
'size': '13px',
|
||||
'type': 'telemetry-view',
|
||||
'id': 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
|
||||
|
||||
}
|
||||
],
|
||||
'layoutGrid': [
|
||||
10,
|
||||
10
|
||||
]
|
||||
},
|
||||
'name': 'Display Layout',
|
||||
'type': 'layout',
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': 'c5e636c1-6771-4c9c-b933-8665cab189b3'
|
||||
}
|
||||
};
|
||||
telemetryItem = {
|
||||
'telemetry': {
|
||||
'period': 5,
|
||||
'amplitude': 5,
|
||||
'offset': 5,
|
||||
'dataRateInHz': 5,
|
||||
'phase': 5,
|
||||
'randomness': 0
|
||||
},
|
||||
'name': 'Sine Wave Generator',
|
||||
'type': 'generator',
|
||||
'modified': 1592851063871,
|
||||
'location': 'mine',
|
||||
'persisted': 1592851063871,
|
||||
'id': '55122607-e65e-44d5-9c9d-9c31a914ca89',
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
}
|
||||
};
|
||||
selection = [
|
||||
[{
|
||||
context: {
|
||||
'layoutItem': displayLayoutItem.configuration.items[0],
|
||||
'item': telemetryItem,
|
||||
'index': 1
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
'item': displayLayoutItem,
|
||||
'supportsMultiSelect': true
|
||||
}
|
||||
}]
|
||||
];
|
||||
});
|
||||
|
||||
it('provides an alphanumeric format view', () => {
|
||||
const displayLayoutAlphaNumFormatView = openmct.inspectorViews.get(selection);
|
||||
expect(displayLayoutAlphaNumFormatView.length).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('the toolbar', () => {
|
||||
let displayLayoutItem;
|
||||
let selection;
|
||||
|
||||
beforeEach(() => {
|
||||
displayLayoutItem = {
|
||||
'composition': [
|
||||
],
|
||||
'configuration': {
|
||||
'items': [
|
||||
{
|
||||
'fill': '#666666',
|
||||
'stroke': '',
|
||||
'x': 1,
|
||||
'y': 1,
|
||||
'width': 10,
|
||||
'height': 5,
|
||||
'type': 'box-view',
|
||||
'id': '89b88746-d325-487b-aec4-11b79afff9e8'
|
||||
},
|
||||
{
|
||||
'fill': '#666666',
|
||||
'stroke': '',
|
||||
'x': 1,
|
||||
'y': 1,
|
||||
'width': 10,
|
||||
'height': 10,
|
||||
'type': 'ellipse-view',
|
||||
'id': '19b88746-d325-487b-aec4-11b79afff9z8'
|
||||
},
|
||||
{
|
||||
'x': 18,
|
||||
'y': 9,
|
||||
'x2': 23,
|
||||
'y2': 4,
|
||||
'stroke': '#666666',
|
||||
'type': 'line-view',
|
||||
'id': '57d49a28-7863-43bd-9593-6570758916f0'
|
||||
},
|
||||
{
|
||||
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
},
|
||||
'x': 8,
|
||||
'y': 3,
|
||||
'width': 10,
|
||||
'height': 5,
|
||||
'displayMode': 'all',
|
||||
'value': 'sin',
|
||||
'stroke': '',
|
||||
'fill': '',
|
||||
'color': '',
|
||||
'size': '13px',
|
||||
'type': 'telemetry-view',
|
||||
'id': 'deb9f839-80ad-4ccf-a152-5c763ceb7d7e'
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
'width': 32,
|
||||
'height': 18,
|
||||
'x': 78,
|
||||
'y': 8,
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
|
||||
},
|
||||
'hasFrame': true,
|
||||
'type': 'subobject-view',
|
||||
'id': 'c0ff485a-344c-4e70-8d83-a9d9998a69fc'
|
||||
|
||||
}
|
||||
],
|
||||
'layoutGrid': [
|
||||
10,
|
||||
10
|
||||
]
|
||||
},
|
||||
'name': 'Display Layout',
|
||||
'type': 'layout',
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': 'c5e636c1-6771-4c9c-b933-8665cab189b3'
|
||||
}
|
||||
};
|
||||
selection = [
|
||||
[{
|
||||
context: {
|
||||
'layoutItem': displayLayoutItem.configuration.items[1],
|
||||
'index': 1
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
'item': displayLayoutItem,
|
||||
'supportsMultiSelect': true
|
||||
}
|
||||
}],
|
||||
[{
|
||||
context: {
|
||||
'layoutItem': displayLayoutItem.configuration.items[0],
|
||||
'index': 0
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
'supportsMultiSelect': true
|
||||
}
|
||||
}],
|
||||
[{
|
||||
context: {
|
||||
'layoutItem': displayLayoutItem.configuration.items[2],
|
||||
'item': displayLayoutItem.configuration.items[2],
|
||||
'index': 2
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
'supportsMultiSelect': true
|
||||
}
|
||||
}],
|
||||
[{
|
||||
context: {
|
||||
'item': {
|
||||
|
||||
'composition': [
|
||||
{
|
||||
'namespace': '',
|
||||
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
}
|
||||
],
|
||||
'configuration': {
|
||||
'series': [
|
||||
{
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': '55122607-e65e-44d5-9c9d-9c31a914ca89'
|
||||
}
|
||||
}
|
||||
],
|
||||
'yAxis': {
|
||||
},
|
||||
'xAxis': {
|
||||
}
|
||||
},
|
||||
'name': 'Unnamed Overlay Plot',
|
||||
'type': 'telemetry.plot.overlay',
|
||||
'modified': 1594142141929,
|
||||
'location': 'mine',
|
||||
'identifier': {
|
||||
'namespace': '',
|
||||
'key': 'bdeb91ab-3a7e-4a71-9dd2-39d73644e136'
|
||||
},
|
||||
'persisted': 1594142141929
|
||||
|
||||
},
|
||||
'layoutItem': displayLayoutItem.configuration.items[3],
|
||||
'index': 3
|
||||
}
|
||||
},
|
||||
{
|
||||
context: {
|
||||
item: displayLayoutItem,
|
||||
'supportsMultiSelect': true
|
||||
}
|
||||
}]
|
||||
];
|
||||
});
|
||||
|
||||
it('provides controls including separators', () => {
|
||||
const displayLayoutToolbar = openmct.toolbars.get(selection);
|
||||
|
||||
expect(displayLayoutToolbar.length).toBe(8);
|
||||
});
|
||||
expect(displayLayoutToolbar.length).toBe(8);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user