abstract logic into actionAPI

This commit is contained in:
Deep Tailor
2020-08-18 16:26:20 -07:00
parent f8ff44dac0
commit 4479cbc7a2
5 changed files with 37 additions and 137 deletions

View File

@@ -20,6 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
import EventEmitter from 'EventEmitter';
import { timingSafeEqual } from 'crypto';
class ActionsAPI extends EventEmitter {
constructor() {
@@ -34,7 +35,9 @@ class ActionsAPI extends EventEmitter {
this.registerViewAction = this.registerViewAction.bind(this);
this.removeAllViewActions = this.removeAllViewActions.bind(this);
this._applicableObjectActions = this._applicableObjectActions.bind(this);
this._groupedAndSortedObjectActions = this._groupedAndSortedObjectActions.bind(this);
this._applicableViewActions = this._applicableViewActions.bind(this);
this._applicableActions = this._applicableActions.bind(this);
}
registerObjectAction(actionDefinition) {
@@ -44,7 +47,7 @@ class ActionsAPI extends EventEmitter {
registerViewAction(viewKey, actionDefinition) {
if (Array.isArray(actionDefinition)) {
this._viewActions[viewKey] = actionDefinition
this._viewActions[viewKey] = actionDefinition;
} else {
if (this._viewActions[viewKey]) {
this._viewActions[viewKey].push(actionDefinition);
@@ -72,11 +75,13 @@ class ActionsAPI extends EventEmitter {
if (action.appliesTo === undefined && actionsToBeIncluded.includes(action.key)) {
return true;
}
return action.appliesTo(objectPath, actionsToBeIncluded) && actionsToBeIncluded.includes(action.key);
} else {
if (action.appliesTo === undefined) {
return true;
}
return action.appliesTo(objectPath, actionsToBeIncluded) && !action.hideInDefaultMenu;
}
});
@@ -87,18 +92,32 @@ class ActionsAPI extends EventEmitter {
};
});
return this._groupAndSortActions(applicableActions);
return applicableActions;
}
_groupedAndSortedObjectActions(objectPath, actionsToBeIncluded) {
let actions = this._applicableObjectActions(objectPath, actionsToBeIncluded);
return this._groupAndSortActions(actions);
}
_applicableViewActions(viewKey) {
return this._viewActions[viewKey] || [];
}
_applicableActions(objectPath, viewKey, actionsToBeIncluded) {
let objectActions = this._applicableObjectActions(objectPath, actionsToBeIncluded);
let viewActions = this._applicableViewActions(viewKey);
let combinedActions = objectActions.concat(viewActions);
return this._groupAndSortActions(combinedActions);
}
_groupAndSortActions(actionsArray) {
let actionsObject = {};
let groupedSortedActionsArray = [];
function sortDescending(a,b) {
function sortDescending(a, b) {
return b.priority - a.priority;
}

View File

@@ -32,50 +32,12 @@ import Menu from './menu.js';
class MenuAPI {
constructor(openmct) {
this.openmct = openmct;
this._allObjectActions = [];
this._groupOrder = ['windowing', 'undefined', 'view', 'action', 'json'];
this.showMenu = this.showMenu.bind(this);
this.registerObjectAction = this.registerObjectAction.bind(this);
this._clearMenuComponent = this._clearMenuComponent.bind(this);
this._applicableObjectActions = this._applicableObjectActions.bind(this);
this._showObjectMenu = this._showObjectMenu.bind(this);
}
/**
* Defines an item to be added to context menus. Allows specification of text, appearance, and behavior when
* selected. Applicabilioty can be restricted by specification of an `appliesTo` function.
*
* @interface ObjectAction
* @memberof module:openmct
* @property {string} name the human-readable name of this view
* @property {string} description a longer-form description (typically
* a single sentence or short paragraph) of this kind of view
* @property {string} cssClass the CSS class to apply to labels for this
* view (to add icons, for instance)
* @property {string} key unique key to identify the context menu action
* (used in custom context menu eg table rows, to identify which actions to include)
* @property {boolean} hideInDefaultMenu optional flag to hide action from showing in the default context menu (tree item)
*/
/**
* @method appliesTo
* @memberof module:openmct.ContextMenuAction#
* @param {DomainObject[]} objectPath the path of the object that the context menu has been invoked on.
* @returns {boolean} true if the action applies to the objects specified in the 'objectPath', otherwise false.
*/
/**
* Code to be executed when the action is selected from a context menu
* @method invoke
* @memberof module:openmct.ContextMenuAction#
* @param {DomainObject[]} objectPath the path of the object to invoke the action on.
*/
/**
* @param {ContextMenuAction} actionDefinition
*/
registerObjectAction(actionDefinition) {
this._allObjectActions.push(actionDefinition);
}
showMenu(x, y, actions) {
if (this.menuComponent) {
this.menuComponent.dismiss();
@@ -96,61 +58,8 @@ class MenuAPI {
delete this.menuComponent;
}
_applicableObjectActions(objectPath, actionsToBeIncluded) {
let applicableActions = this._allObjectActions.filter((action) => {
if (actionsToBeIncluded) {
if (action.appliesTo === undefined && actionsToBeIncluded.includes(action.key)) {
return true;
}
return action.appliesTo(objectPath, actionsToBeIncluded) && actionsToBeIncluded.includes(action.key);
} else {
if (action.appliesTo === undefined) {
return true;
}
return action.appliesTo(objectPath) && !action.hideInDefaultMenu;
}
});
applicableActions.forEach(action => {
action.callBack = () => {
return action.invoke(objectPath);
};
});
return this._groupAndSortActions(applicableActions);
}
_groupAndSortActions(actionsArray) {
let actionsObject = {};
let groupedSortedActionsArray = [];
function sortDescending(a,b) {
return b.priority - a.priority;
}
actionsArray.forEach(action => {
if (actionsObject[action.group] === undefined) {
actionsObject[action.group] = [action];
} else {
actionsObject[action.group].push(action);
}
});
this._groupOrder.forEach(group => {
let groupArray = actionsObject[group];
if (groupArray) {
groupedSortedActionsArray.push(groupArray.sort(sortDescending));
}
});
return groupedSortedActionsArray;
}
_showObjectMenu(objectPath, x, y, actionsToBeIncluded) {
let applicableActions = this.openmct.actions._applicableObjectActions(objectPath, actionsToBeIncluded);
let applicableActions = this.openmct.actions._groupedAndSortedObjectActions(objectPath, actionsToBeIncluded);
this.showMenu(x, y, applicableActions);
}

View File

@@ -928,41 +928,47 @@ export default {
name: 'Export Table Data',
description: "Export this view's data",
cssClass: 'icon-download labeled',
callBack: this.exportAllDataAsCSV
callBack: this.exportAllDataAsCSV,
group: 'view'
};
let exportMarkedRows = {
name: 'Export Marked Rows',
description: "Export marked rows as CSV",
cssClass: 'icon-download labeled',
callBack: this.exportMarkedDataAsCSV
callBack: this.exportMarkedDataAsCSV,
group: 'view'
};
let unmarkAllRows = {
name: 'Unmark All Rows',
description: 'Unmark all rows',
cssClass: 'icon-x labeled',
callBack: this.unmarkAllRows,
showInStatusBar: true
showInStatusBar: true,
group: 'view'
}
let pausePlay = {
name: this.paused ? 'Play' : 'Pause',
description: this.paused ? 'Continue real-time data flow' : 'Pause real-time data flow',
cssClass: this.paused ? 'c-button pause-play is-paused' : 'icon-pause',
callBack: this.togglePauseByButton,
showInStatusBar: true
showInStatusBar: true,
group: 'view'
}
let expandColumns = {
name: 'Expand Columns',
description: "Increase column widths to fit currently available data.",
cssClass: 'icon-arrows-right-left labeled',
callBack: this.recalculateColumnWidths,
showInStatusBar: true
showInStatusBar: true,
group: 'view'
}
let autosizeColumns = {
name: 'Autosize Columns',
description: "Automatically size columns to fit the table into the available space.",
cssClass: 'icon-expand labeled',
callBack: this.autosizeColumns,
showInStatusBar: true
showInStatusBar: true,
group: 'view'
}
let columnSizing;
let applicableOptions = [];

View File

@@ -216,24 +216,7 @@ export default {
}
},
showMenuItems(event) {
let viewKey = this.viewProvider.getViewContext && this.viewProvider.getViewContext().getViewKey();
let applicableViewMenuItems;
if (viewKey) {
applicableViewMenuItems = this.openmct.actions._applicableViewActions(viewKey);
}
let applicableObjectMenuItems = this.openmct.actions._applicableObjectActions(this.objectPath);
let applicableMenuItems;
if (!applicableViewMenuItems) {
applicableMenuItems = applicableObjectMenuItems;
} else if(!applicableObjectMenuItems) {
applicableMenuItems = applicableViewMenuItems;
} else {
applicableObjectMenuItems.splice(1, 0, applicableViewMenuItems);
applicableMenuItems = applicableObjectMenuItems;
}
let applicableMenuItems = this.openmct.actions._applicableActions(this.objectPath, this.viewKey);
this.openmct.menus.showMenu(event.x, event.y, applicableMenuItems);
}

View File

@@ -342,24 +342,7 @@ export default {
}
},
showMenuItems(event) {
let viewKey = this.viewProvider.getViewContext && this.viewProvider.getViewContext().getViewKey();
let applicableViewMenuItems;
if (viewKey) {
applicableViewMenuItems = this.openmct.actions._applicableViewActions(viewKey);
}
let applicableObjectMenuItems = this.openmct.actions._applicableObjectActions(this.openmct.router.path);
let applicableMenuItems;
if (!applicableViewMenuItems) {
applicableMenuItems = applicableObjectMenuItems;
} else if(!applicableObjectMenuItems) {
applicableMenuItems = applicableViewMenuItems;
} else {
applicableObjectMenuItems.splice(1, 0, applicableViewMenuItems);
applicableMenuItems = applicableObjectMenuItems;
}
let applicableMenuItems = this.openmct.actions._applicableActions(this.openmct.router.path, this.statusBarViewKey);
this.openmct.menus.showMenu(event.x, event.y, applicableMenuItems);
},