[Display Layout] support ordering items (#2266)

* Add a toolbar menu for changing the display order of items.

* - Wire up orderItem
- Modify the toolbar API to support function as alternative for property path.
This commit is contained in:
Pegah Sarram 2019-01-23 10:51:29 -08:00 committed by Pete Richards
parent 8ef53d85c4
commit 9e811e722f
4 changed files with 163 additions and 64 deletions

View File

@ -73,10 +73,13 @@ define([], function () {
return openmct.$injector.get('dialogService').getUserInput(form, {});
}
function getPath() {
return `configuration.items[${selection[0].context.index}]`;
}
let selectedParent = selection[1] && selection[1].context.item,
selectedObject = selection[0].context.item,
layoutItem = selection[0].context.layoutItem,
layoutItemIndex = selection[0].context.index,
toolbar = [];
if (selectedObject && selectedObject.type === 'layout') {
@ -121,7 +124,6 @@ define([], function () {
return toolbar;
}
let path = `configuration.items[${layoutItemIndex}]`;
let separator = {
control: "separator"
};
@ -140,7 +142,7 @@ define([], function () {
label: 'Ok',
emphasis: 'true',
callback: function () {
removeItem(layoutItem, layoutItemIndex);
removeItem(layoutItem, selection[0].context.index);
prompt.dismiss();
}
},
@ -154,10 +156,43 @@ define([], function () {
});
}
};
let stackOrder = {
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) {
selection[1].context.orderItem(option.value, selection[0].context.index);
}
};
let useGrid = {
control: "toggle-button",
domainObject: selectedParent,
property: path + ".useGrid",
property: function () {
return getPath() + ".useGrid";
},
options: [
{
value: false,
@ -177,10 +212,14 @@ define([], function () {
toolbar.push(separator);
}
toolbar.push(stackOrder);
toolbar.push(separator);
toolbar.push({
control: "toggle-button",
domainObject: selectedParent,
property: path + ".hasFrame",
property: function () {
return getPath() + ".hasFrame";
},
options: [
{
value: false,
@ -194,6 +233,7 @@ define([], function () {
}
]
});
toolbar.push(separator);
toolbar.push(useGrid);
toolbar.push(separator);
toolbar.push(remove);
@ -202,21 +242,27 @@ define([], function () {
let fill = {
control: "color-picker",
domainObject: selectedParent,
property: path + ".fill",
property: function () {
return getPath() + ".fill";
},
icon: "icon-paint-bucket",
title: "Set fill color"
},
stroke = {
control: "color-picker",
domainObject: selectedParent,
property: path + ".stroke",
property: function () {
return getPath() + ".stroke";
},
icon: "icon-line-horz",
title: "Set border color"
},
color = {
control: "color-picker",
domainObject: selectedParent,
property: path + ".color",
property: function () {
return getPath() + ".color";
},
icon: "icon-font",
mandatory: true,
title: "Set text color",
@ -225,7 +271,9 @@ define([], function () {
size = {
control: "select-menu",
domainObject: selectedParent,
property: path + ".size",
property: function () {
return getPath() + ".size";
},
title: "Set text size",
options: TEXT_SIZE.map(size => {
return {
@ -237,7 +285,9 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".x",
property: function () {
return getPath() + ".x";
},
label: "X:",
title: "X position"
},
@ -245,7 +295,9 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".y",
property: function () {
return getPath() + ".y";
},
label: "Y:",
title: "Y position",
},
@ -253,7 +305,9 @@ define([], function () {
control: 'input',
type: 'number',
domainObject: selectedParent,
property: path + ".width",
property: function () {
return getPath() + ".width";
},
label: 'W:',
title: 'Resize object width'
},
@ -261,7 +315,9 @@ define([], function () {
control: 'input',
type: 'number',
domainObject: selectedParent,
property: path + ".height",
property: function () {
return getPath() + ".height";
},
label: 'H:',
title: 'Resize object height'
};
@ -270,7 +326,9 @@ define([], function () {
let displayMode = {
control: "select-menu",
domainObject: selectedParent,
property: path + ".displayMode",
property: function () {
return getPath() + ".displayMode";
},
title: "Set display mode",
options: [
{
@ -290,7 +348,9 @@ define([], function () {
value = {
control: "select-menu",
domainObject: selectedParent,
property: path + ".value",
property: function () {
return getPath() + ".value";
},
title: "Set value",
options: openmct.telemetry.getMetadata(selectedObject).values().map(value => {
return {
@ -304,6 +364,7 @@ define([], function () {
separator,
value,
separator,
stackOrder,
fill,
stroke,
color,
@ -314,7 +375,6 @@ define([], function () {
y,
height,
width,
separator,
useGrid,
separator,
remove
@ -323,30 +383,34 @@ define([], function () {
let text = {
control: "button",
domainObject: selectedParent,
property: path,
property: function () {
return getPath();
},
icon: "icon-gear",
title: "Edit text properties",
dialog: DIALOG_FORM['text']
};
toolbar = [
stackOrder,
fill,
stroke,
color,
separator,
color,
size,
separator,
x,
y,
height,
width,
useGrid,
separator,
text,
useGrid,
separator,
remove
];
} else if (layoutItem.type === 'box-view') {
toolbar = [
stackOrder,
fill,
stroke,
separator,
@ -354,7 +418,6 @@ define([], function () {
y,
height,
width,
separator,
useGrid,
separator,
remove
@ -363,21 +426,24 @@ define([], function () {
let url = {
control: "button",
domainObject: selectedParent,
property: path,
property: function () {
return getPath();
},
icon: "icon-image",
title: "Edit image properties",
dialog: DIALOG_FORM['image']
};
toolbar = [
stackOrder,
stroke,
separator,
x,
y,
height,
width,
useGrid,
separator,
url,
useGrid,
separator,
remove
];
@ -386,7 +452,9 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".x2",
property: function () {
return getPath() + ".x2";
},
label: "X2:",
title: "X2 position"
},
@ -394,18 +462,20 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".y2",
property: function () {
return getPath() + ".y2";
},
label: "Y2:",
title: "Y2 position",
};
toolbar = [
stackOrder,
stroke,
separator,
x,
y,
x2,
y2,
separator,
useGrid,
separator,
remove

View File

@ -117,6 +117,12 @@
'text-view': TextView,
'image-view': ImageView
};
const ORDERS = {
top: Number.POSITIVE_INFINITY,
up: 1,
down: -1,
bottom: Number.NEGATIVE_INFINITY
};
function getItemDefinition(itemType, ...options) {
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
@ -163,42 +169,45 @@
let itemIndex = selection[0].context.index;
if (itemIndex !== undefined) {
let path = `configuration.items[${itemIndex}]`;
this.removeSelectionListener = this.openmct.objects.observe(this.internalDomainObject, path + ".useGrid", function (value) {
let item = this.layoutItems[itemIndex];
if (value) {
item.x = Math.round(item.x / this.gridSize[0]);
item.y = Math.round(item.y / this.gridSize[1]);
item.width = Math.round(item.width / this.gridSize[0]);
item.height = Math.round(item.height / this.gridSize[1]);
if (item.x2) {
item.x2 = Math.round(item.x2 / this.gridSize[0]);
}
if (item.y2) {
item.y2 = Math.round(item.y2 / this.gridSize[1]);
}
} else {
item.x = this.gridSize[0] * item.x;
item.y = this.gridSize[1] * item.y;
item.width = this.gridSize[0] * item.width;
item.height = this.gridSize[1] * item.height;
if (item.x2) {
item.x2 = this.gridSize[0] * item.x2;
}
if (item.y2) {
item.y2 = this.gridSize[1] * item.y2;
}
}
item.useGrid = value;
this.mutate(`configuration.items[${itemIndex}]`, item);
}.bind(this));
this.attachSelectionListener(itemIndex);
}
this.updateDrilledIn();
},
attachSelectionListener(index) {
let path = `configuration.items[${index}].useGrid`;
this.removeSelectionListener = this.openmct.objects.observe(this.internalDomainObject, path, function (value) {
let item = this.layoutItems[index];
if (value) {
item.x = Math.round(item.x / this.gridSize[0]);
item.y = Math.round(item.y / this.gridSize[1]);
item.width = Math.round(item.width / this.gridSize[0]);
item.height = Math.round(item.height / this.gridSize[1]);
if (item.x2) {
item.x2 = Math.round(item.x2 / this.gridSize[0]);
}
if (item.y2) {
item.y2 = Math.round(item.y2 / this.gridSize[1]);
}
} else {
item.x = this.gridSize[0] * item.x;
item.y = this.gridSize[1] * item.y;
item.width = this.gridSize[0] * item.width;
item.height = this.gridSize[1] * item.height;
if (item.x2) {
item.x2 = this.gridSize[0] * item.x2;
}
if (item.y2) {
item.y2 = this.gridSize[1] * item.y2;
}
}
item.useGrid = value;
this.mutate(`configuration.items[${index}]`, item);
}.bind(this));
},
updateDrilledIn(drilledInItem) {
let identifier = drilledInItem && this.openmct.objects.makeKeyString(drilledInItem.identifier);
this.drilledIn = identifier;
@ -369,6 +378,22 @@
});
this.mutate("configuration.items", layoutItems);
this.$el.click();
},
orderItem(position, index) {
let delta = ORDERS[position];
let newIndex = Math.max(Math.min(index + delta, this.layoutItems.length - 1), 0);
let item = this.layoutItems[index];
if (newIndex !== index) {
this.layoutItems.splice(index, 1);
this.layoutItems.splice(newIndex, 0, item);
this.mutate('configuration.items', this.layoutItems);
if (this.removeSelectionListener) {
this.removeSelectionListener();
this.attachSelectionListener(newIndex);
}
}
}
},
mounted() {

View File

@ -61,7 +61,8 @@ export default function () {
return {
item: domainObject,
addElement: component && component.$refs.displayLayout.addElement,
removeItem: component && component.$refs.displayLayout.removeItem
removeItem: component && component.$refs.displayLayout.removeItem,
orderItem: component && component.$refs.displayLayout.orderItem
}
},
destroy() {

View File

@ -67,7 +67,7 @@
if (formKeys.length > 0) {
toolbarItem.value = this.getFormValue(domainObject, toolbarItem);
} else {
toolbarItem.value = _.get(domainObject, item.property);
toolbarItem.value = _.get(domainObject, this.getItemProperty(item));
}
this.registerListener(domainObject);
@ -116,7 +116,7 @@
if (toolbarItem.formKeys) {
toolbarItem.value = this.getFormValue(newObject, toolbarItem);
} else {
toolbarItem.value = _.get(newObject, item.property);
toolbarItem.value = _.get(newObject, this.getItemProperty(item));
}
}
}
@ -135,10 +135,13 @@
getFormValue(domainObject, toolbarItem) {
let value = {};
toolbarItem.formKeys.map(key => {
value[key] = _.get(domainObject, toolbarItem.property + "." + key);
value[key] = _.get(domainObject, this.getItemProperty(toolbarItem) + "." + key);
});
return value;
},
getItemProperty(item) {
return (typeof item.property === "function") ? item.property() : item.property;
},
removeListeners() {
if (this.unObserveObjects) {
this.unObserveObjects.forEach((unObserveObject) => {
@ -156,7 +159,7 @@
if (domainObject) {
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
if (changedItemId === id && item.property === s.property) {
if (changedItemId === id && this.getItemProperty(item) === this.getItemProperty(s)) {
toolbarItem.value = value;
}
}
@ -170,12 +173,12 @@
this.structure.map(s => {
if (s.formKeys) {
s.formKeys.forEach(key => {
this.openmct.objects.mutate(item.domainObject, item.property + "." + key, value[key]);
this.openmct.objects.mutate(item.domainObject, this.getItemProperty(item) + "." + key, value[key]);
});
}
});
} else {
this.openmct.objects.mutate(item.domainObject, item.property, value);
this.openmct.objects.mutate(item.domainObject, this.getItemProperty(item), value);
}
},
triggerMethod(item, event) {