openmct/src/plugins/displayLayout/DisplayLayoutToolbar.js
Joel McKinnon 6d526eaf42 Fix lint errors (#2520)
* Fixed linting errors
* Disabled broken test
2019-10-29 15:49:55 -07:00

682 lines
32 KiB
JavaScript

/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(['lodash'], function (_) {
function DisplayLayoutToolbar(openmct) {
return {
name: "Display Layout Toolbar",
key: "layout",
description: "A toolbar for objects inside a display layout.",
forSelection: function (selection) {
if (!selection || selection.length === 0) {
return false;
}
let selectionPath = selection[0];
let selectedObject = selectionPath[0];
let selectedParent = selectionPath[1];
// Apply the layout toolbar if the selected object is inside a layout, or the main layout is selected.
return (selectedParent && selectedParent.context.item && selectedParent.context.item.type === 'layout') ||
(selectedObject.context.item && selectedObject.context.item.type === 'layout');
},
toolbar: function (selectedObjects) {
const DIALOG_FORM = {
'text': {
name: "Text Element Properties",
sections: [
{
rows: [
{
key: "text",
control: "textfield",
name: "Text",
required: true
}
]
}
]
},
'image': {
name: "Image Properties",
sections: [
{
rows: [
{
key: "url",
control: "textfield",
name: "Image URL",
"cssClass": "l-input-lg",
required: true
}
]
}
]
}
};
function getUserInput(form) {
return openmct.$injector.get('dialogService').getUserInput(form, {});
}
function getPath(selectionPath) {
return `configuration.items[${selectionPath[0].context.index}]`;
}
function getAllTypes(selection) {
return selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
return type === 'text-view' ||
type === 'telemetry-view' ||
type === 'box-view' ||
type === 'image-view' ||
type === 'line-view' ||
type === 'subobject-view';
});
}
function getAddButton(selection, selectionPath) {
if (selection.length === 1) {
selectionPath = selectionPath || selection[0];
return {
control: "menu",
domainObject: selectionPath[0].context.item,
method: function (option) {
let name = option.name.toLowerCase();
let form = DIALOG_FORM[name];
if (form) {
getUserInput(form)
.then(element => selectionPath[0].context.addElement(name, element));
} else {
selectionPath[0].context.addElement(name);
}
},
key: "add",
icon: "icon-plus",
label: "Add",
options: [
{
"name": "Box",
"class": "icon-box-round-corners"
},
{
"name": "Line",
"class": "icon-line-horz"
},
{
"name": "Text",
"class": "icon-font"
},
{
"name": "Image",
"class": "icon-image"
}
]
};
}
}
function getToggleFrameButton(selectedParent, selection) {
return {
control: "toggle-button",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath =>
selectionPath[0].context.layoutItem.type === 'subobject-view'
),
property: function (selectionPath) {
return getPath(selectionPath) + ".hasFrame";
},
options: [
{
value: false,
icon: 'icon-frame-show',
title: "Frame visible"
},
{
value: true,
icon: 'icon-frame-hide',
title: "Frame hidden"
}
]
};
}
function getRemoveButton(selectedParent, selectionPath, selection) {
return {
control: "button",
domainObject: selectedParent,
icon: "icon-trash",
title: "Delete the selected object",
method: function () {
let removeItem = selectionPath[1].context.removeItem;
let prompt = openmct.overlays.dialog({
iconClass: 'alert',
message: `Warning! This action will remove this item from the Display Layout. Do you want to continue?`,
buttons: [
{
label: 'Ok',
emphasis: 'true',
callback: function () {
removeItem(getAllTypes(selection));
prompt.dismiss();
}
},
{
label: 'Cancel',
callback: function () {
prompt.dismiss();
}
}
]
});
}
};
}
function getStackOrder(selectedParent, selectionPath) {
return {
control: "menu",
domainObject: selectedParent,
icon: "icon-layers",
title: "Move the selected object above or below other objects",
options: [
{
name: "Move to Top",
value: "top",
class: "icon-arrow-double-up"
},
{
name: "Move Up",
value: "up",
class: "icon-arrow-up"
},
{
name: "Move Down",
value: "down",
class: "icon-arrow-down"
},
{
name: "Move to Bottom",
value: "bottom",
class: "icon-arrow-double-down"
}
],
method: function (option) {
selectionPath[1].context.orderItem(option.value, getAllTypes(selectedObjects));
}
};
}
function getXInput(selectedParent, selection) {
if (selection.length === 1) {
return {
control: "input",
type: "number",
domainObject: selectedParent,
applicableSelectedItems: getAllTypes(selection),
property: function (selectionPath) {
return getPath(selectionPath) + ".x";
},
label: "X:",
title: "X position"
};
}
}
function getYInput(selectedParent, selection) {
if (selection.length === 1) {
return {
control: "input",
type: "number",
domainObject: selectedParent,
applicableSelectedItems: getAllTypes(selection),
property: function (selectionPath) {
return getPath(selectionPath) + ".y";
},
label: "Y:",
title: "Y position"
};
}
}
function getWidthInput(selectedParent, selection) {
if (selection.length === 1) {
return {
control: 'input',
type: 'number',
domainObject: selectedParent,
applicableSelectedItems: getAllTypes(selection),
property: function (selectionPath) {
return getPath(selectionPath) + ".width";
},
label: 'W:',
title: 'Resize object width'
};
}
}
function getHeightInput(selectedParent, selection) {
if (selection.length === 1) {
return {
control: 'input',
type: 'number',
domainObject: selectedParent,
applicableSelectedItems: getAllTypes(selection),
property: function (selectionPath) {
return getPath(selectionPath) + ".height";
},
label: 'H:',
title: 'Resize object height'
};
}
}
function getX2Input(selectedParent, selection) {
if (selection.length === 1) {
return {
control: "input",
type: "number",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
return selectionPath[0].context.layoutItem.type === 'line-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".x2";
},
label: "X2:",
title: "X2 position"
};
}
}
function getY2Input(selectedParent, selection) {
if (selection.length === 1) {
return {
control: "input",
type: "number",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
return selectionPath[0].context.layoutItem.type === 'line-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".y2";
},
label: "Y2:",
title: "Y2 position"
};
}
}
function getTextSizeMenu(selectedParent, selection) {
const TEXT_SIZE = [8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96, 128];
return {
control: "select-menu",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
return type === 'text-view' || type === 'telemetry-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".size";
},
title: "Set text size",
options: TEXT_SIZE.map(size => {
return {
value: size + "px"
};
})
};
}
function getFillMenu(selectedParent, selection) {
return {
control: "color-picker",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
return type === 'text-view' ||
type === 'telemetry-view' ||
type === 'box-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".fill";
},
icon: "icon-paint-bucket",
title: "Set fill color"
};
}
function getStrokeMenu(selectedParent, selection) {
return {
control: "color-picker",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
return type === 'text-view' ||
type === 'telemetry-view' ||
type === 'box-view' ||
type === 'image-view' ||
type === 'line-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".stroke";
},
icon: "icon-line-horz",
title: "Set border color"
};
}
function getTextColorMenu(selectedParent, selection) {
return {
control: "color-picker",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
return type === 'text-view' || type === 'telemetry-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".color";
},
icon: "icon-font",
mandatory: true,
title: "Set text color",
preventNone: true
};
}
function getURLButton(selectedParent, selection) {
return {
control: "button",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
return selectionPath[0].context.layoutItem.type === 'image-view';
}),
property: function (selectionPath) {
return getPath(selectionPath);
},
icon: "icon-image",
title: "Edit image properties",
dialog: DIALOG_FORM.image
};
}
function getTextButton(selectedParent, selection) {
return {
control: "button",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
return selectionPath[0].context.layoutItem.type === 'text-view';
}),
property: function (selectionPath) {
return getPath(selectionPath);
},
icon: "icon-gear",
title: "Edit text properties",
dialog: DIALOG_FORM.text
};
}
function getTelemetryValueMenu(selectionPath, selection) {
if (selection.length === 1) {
return {
control: "select-menu",
domainObject: selectionPath[1].context.item,
applicableSelectedItems: selection.filter(path => {
return path[0].context.layoutItem.type === 'telemetry-view';
}),
property: function (path) {
return getPath(path) + ".value";
},
title: "Set value",
options: openmct.telemetry.getMetadata(selectionPath[0].context.item).values().map(value => {
return {
name: value.name,
value: value.key
}
})
};
}
}
function getDisplayModeMenu(selectedParent, selection) {
if (selection.length === 1) {
return {
control: "select-menu",
domainObject: selectedParent,
applicableSelectedItems: selection.filter(selectionPath => {
return selectionPath[0].context.layoutItem.type === 'telemetry-view';
}),
property: function (selectionPath) {
return getPath(selectionPath) + ".displayMode";
},
title: "Set display mode",
options: [
{
name: 'Label + Value',
value: 'all'
},
{
name: "Label only",
value: "label"
},
{
name: "Value only",
value: "value"
}
]
};
}
}
function getSeparator() {
return {
control: "separator"
};
}
function isMainLayoutSelected(selectionPath) {
let selectedObject = selectionPath[0].context.item;
return selectedObject && selectedObject.type === 'layout' &&
!selectionPath[0].context.layoutItem;
}
if (isMainLayoutSelected(selectedObjects[0])) {
return [getAddButton(selectedObjects)];
}
let toolbar = {
'add-menu': [],
'toggle-frame': [],
'display-mode': [],
'telemetry-value': [],
'style': [],
'text-style': [],
'position': [],
'text': [],
'url': [],
'remove': []
};
selectedObjects.forEach(selectionPath => {
let selectedParent = selectionPath[1].context.item;
let layoutItem = selectionPath[0].context.layoutItem;
if (layoutItem.type === 'subobject-view') {
if (toolbar['add-menu'].length === 0 && selectionPath[0].context.item.type === 'layout') {
toolbar['add-menu'] = [getAddButton(selectedObjects, selectionPath)];
}
if (toolbar['toggle-frame'].length === 0) {
toolbar['toggle-frame'] = [getToggleFrameButton(selectedParent, selectedObjects)];
}
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
getXInput(selectedParent, selectedObjects),
getYInput(selectedParent, selectedObjects),
getHeightInput(selectedParent, selectedObjects),
getWidthInput(selectedParent, selectedObjects)
];
}
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'telemetry-view') {
if (toolbar['display-mode'].length === 0) {
toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selectedObjects)];
}
if (toolbar['telemetry-value'].length === 0) {
toolbar['telemetry-value'] = [getTelemetryValueMenu(selectionPath, selectedObjects)];
}
if (toolbar.style.length < 2) {
toolbar.style = [
getFillMenu(selectedParent, selectedObjects),
getStrokeMenu(selectedParent, selectedObjects)
];
}
if (toolbar['text-style'].length === 0) {
toolbar['text-style'] = [
getTextColorMenu(selectedParent, selectedObjects),
getTextSizeMenu(selectedParent, selectedObjects)
];
}
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
getXInput(selectedParent, selectedObjects),
getYInput(selectedParent, selectedObjects),
getHeightInput(selectedParent, selectedObjects),
getWidthInput(selectedParent, selectedObjects)
];
}
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'text-view') {
if (toolbar.style.length < 2) {
toolbar.style = [
getFillMenu(selectedParent, selectedObjects),
getStrokeMenu(selectedParent, selectedObjects)
];
}
if (toolbar['text-style'].length === 0) {
toolbar['text-style'] = [
getTextColorMenu(selectedParent, selectedObjects),
getTextSizeMenu(selectedParent, selectedObjects)
];
}
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
getXInput(selectedParent, selectedObjects),
getYInput(selectedParent, selectedObjects),
getHeightInput(selectedParent, selectedObjects),
getWidthInput(selectedParent, selectedObjects)
];
}
if (toolbar.text.length === 0) {
toolbar.text = [getTextButton(selectedParent, selectedObjects)];
}
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'box-view') {
if (toolbar.style.length < 2) {
toolbar.style = [
getFillMenu(selectedParent, selectedObjects),
getStrokeMenu(selectedParent, selectedObjects)
];
}
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
getXInput(selectedParent, selectedObjects),
getYInput(selectedParent, selectedObjects),
getHeightInput(selectedParent, selectedObjects),
getWidthInput(selectedParent, selectedObjects)
];
}
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'image-view') {
if (toolbar.style.length === 0) {
toolbar.style = [
getStrokeMenu(selectedParent, selectedObjects)
];
}
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
getXInput(selectedParent, selectedObjects),
getYInput(selectedParent, selectedObjects),
getHeightInput(selectedParent, selectedObjects),
getWidthInput(selectedParent, selectedObjects)
];
}
if (toolbar.url.length === 0) {
toolbar.url = [getURLButton(selectedParent, selectedObjects)];
}
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'line-view') {
if (toolbar.style.length === 0) {
toolbar.style = [
getStrokeMenu(selectedParent, selectedObjects)
];
}
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
getXInput(selectedParent, selectedObjects),
getYInput(selectedParent, selectedObjects),
getX2Input(selectedParent, selectedObjects),
getY2Input(selectedParent, selectedObjects)
];
}
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
}
});
let toolbarArray = Object.values(toolbar);
return _.flatten(toolbarArray.reduce((accumulator, group, index) => {
group = group.filter(control => control !== undefined);
if (group.length > 0) {
accumulator.push(group);
if (index < toolbarArray.length - 1) {
accumulator.push(getSeparator());
}
}
return accumulator;
}, []));
}
}
}
return DisplayLayoutToolbar;
});