mirror of
https://github.com/nasa/openmct.git
synced 2025-06-12 20:28:14 +00:00
[Edit] Implement EditToolbar
Implement EditToolbar (sufficient to satisfy spec) which will construct an mct-toolbar-friendly form structure based on both the current selection and the view's defined toolbar structure. WTD-878.
This commit is contained in:
@ -4,17 +4,162 @@ define(
|
|||||||
function () {
|
function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// Utility functions for reducing truth arrays
|
||||||
|
function and(a, b) { return a && b; }
|
||||||
|
function or(a, b) { return a || b; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides initial structure and state (as suitable for provision
|
||||||
|
* to the `mct-toolbar` directive) for a view's tool bar, based on
|
||||||
|
* that view's declaration of what belongs in its tool bar and on
|
||||||
|
* the current selection.
|
||||||
|
*
|
||||||
|
* @param structure toolbar structure, as provided by view definition
|
||||||
|
* @param {Array} selection the current selection state
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
function EditToolbar(structure, selection) {
|
function EditToolbar(structure, selection) {
|
||||||
|
var toolbarStructure = Object.create(structure || {}),
|
||||||
|
toolbarState,
|
||||||
|
properties = [];
|
||||||
|
|
||||||
|
// Generate a new key for an item's property
|
||||||
|
function addKey(property) {
|
||||||
|
properties.push(property);
|
||||||
|
return properties.length - 1; // Return index of property
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update value for this property in all elements of the
|
||||||
|
// selection which have this property.
|
||||||
|
function updateProperties(property, value) {
|
||||||
|
// Update property in a selected element
|
||||||
|
function updateProperty(selected) {
|
||||||
|
// Ignore selected elements which don't have this property
|
||||||
|
if (selected[property] !== undefined) {
|
||||||
|
// Check if this is a setter, or just assignable
|
||||||
|
if (typeof selected[property] === 'function') {
|
||||||
|
selected[property](value);
|
||||||
|
} else {
|
||||||
|
selected[property] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update property in all selected elements
|
||||||
|
selection.forEach(updateProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up the current value associated with a property
|
||||||
|
// in selection i
|
||||||
|
function lookupState(property, selected) {
|
||||||
|
var value = selected[property];
|
||||||
|
return (typeof value === 'function') ? value() : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get initial value for a given property
|
||||||
|
function initializeState(property) {
|
||||||
|
var result;
|
||||||
|
// Look through all selections for this property;
|
||||||
|
// values should all match by the time we perform
|
||||||
|
// this lookup anyway.
|
||||||
|
selection.forEach(function (selected) {
|
||||||
|
result = (selected[property] !== undefined) ?
|
||||||
|
lookupState(property, selected) :
|
||||||
|
result;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all elements of the selection which have this
|
||||||
|
// property have the same value for this property.
|
||||||
|
function isConsistent(property) {
|
||||||
|
var consistent = true,
|
||||||
|
observed = false,
|
||||||
|
state;
|
||||||
|
|
||||||
|
// Check if a given element of the selection is consistent
|
||||||
|
// with previously-observed elements for this property.
|
||||||
|
function checkConsistency(selected) {
|
||||||
|
var next;
|
||||||
|
// Ignore selections which don't have this property
|
||||||
|
if (selected[property] !== undefined) {
|
||||||
|
// Look up state of this element in the selection
|
||||||
|
next = lookupState(property, selected);
|
||||||
|
// Detect inconsistency
|
||||||
|
if (observed) {
|
||||||
|
consistent = consistent && (next === state);
|
||||||
|
}
|
||||||
|
// Track state for next iteration
|
||||||
|
state = next;
|
||||||
|
observed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through selections
|
||||||
|
selection.forEach(checkConsistency);
|
||||||
|
|
||||||
|
return consistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to filter out items which are applicable (or not)
|
||||||
|
// to the current selection.
|
||||||
|
function isApplicable(item) {
|
||||||
|
var property = (item || {}).property,
|
||||||
|
exclusive = !(item || {}).inclusive;
|
||||||
|
|
||||||
|
// Check if a selected item defines this property
|
||||||
|
function hasProperty(selected) {
|
||||||
|
return selected[property] !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return property && selection.map(hasProperty).reduce(
|
||||||
|
exclusive ? and : or,
|
||||||
|
exclusive
|
||||||
|
) && isConsistent(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare a toolbar item based on current selection
|
||||||
|
function convertItem(item) {
|
||||||
|
var converted = Object.create(item || {});
|
||||||
|
converted.key = addKey(item.property);
|
||||||
|
return converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to filter out sections that have become empty
|
||||||
|
function nonEmpty(section) {
|
||||||
|
return section && section.items && section.items.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare a toolbar section based on current selection
|
||||||
|
function convertSection(section) {
|
||||||
|
var converted = Object.create(section || {});
|
||||||
|
converted.items =
|
||||||
|
((section || {}).items || [])
|
||||||
|
.map(convertItem)
|
||||||
|
.filter(isApplicable);
|
||||||
|
return converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolbarStructure.sections =
|
||||||
|
((structure || {}).sections || [])
|
||||||
|
.map(convertSection)
|
||||||
|
.filter(nonEmpty);
|
||||||
|
|
||||||
|
toolbarState = properties.map(initializeState);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
getStructure: function () {
|
getStructure: function () {
|
||||||
|
return toolbarStructure;
|
||||||
},
|
},
|
||||||
getState: function () {
|
getState: function () {
|
||||||
|
return toolbarState;
|
||||||
},
|
},
|
||||||
updateState: function (key) {
|
updateState: function (key, value) {
|
||||||
|
updateProperties(properties[key], value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,8 @@ define(
|
|||||||
testAB = { a: 0, b: 1 };
|
testAB = { a: 0, b: 1 };
|
||||||
testABC = { a: 0, b: 1, c: 2 };
|
testABC = { a: 0, b: 1, c: 2 };
|
||||||
testABC2 = { a: 4, b: 1, c: 2 }; // For inconsistent-state checking
|
testABC2 = { a: 4, b: 1, c: 2 }; // For inconsistent-state checking
|
||||||
testABCXYZ = { a: 'A!', b: 'B!', c: 'C!', x: 'X!', y: 'Y!', z: 'Z!' };
|
testABCXYZ = { a: 0, b: 1, c: 2, x: 'X!', y: 'Y!', z: 'Z!' };
|
||||||
testABCYZ = { a: 'A!', b: 'B!', c: 'C!', y: 'Y!', z: 'Z!' };
|
testABCYZ = { a: 0, b: 1, c: 2, y: 'Y!', z: 'Z!' };
|
||||||
});
|
});
|
||||||
|
|
||||||
it("provides properties from the original structure", function () {
|
it("provides properties from the original structure", function () {
|
||||||
|
Reference in New Issue
Block a user