abstract logic into actionAPI
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user