mirror of
https://github.com/nasa/openmct.git
synced 2025-06-17 14:48:13 +00:00
* add context menu capability to table rows, add view switcher to preview * add an option to limit context menu actions to the ones requested, and modify preview action to also include a view historical data action * extend preview action into view historical data action * add context menu to LAD Table * add keys to context menu actions, allow tables to conditionally attach context menu handler * working switch y axis label * New vertical select element for Y axis configuration in plots - CSS for vertically rotated selects for Y axis label selection; - New theme constants; - Removed themedSelect theme mixins; - New SASS svgColorFromHex function; * use keys in lad table context menu options * show historical view context menu on alpha-numerics * make reviewer requested changes * pass contextual object path from object view down etc * made reviewer requested changes: removed options object, pass in object path instead * remove redundant function from LADRow.vue
158 lines
5.9 KiB
JavaScript
158 lines
5.9 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.
|
|
*****************************************************************************/
|
|
|
|
import ContextMenuComponent from './ContextMenu.vue';
|
|
import Vue from 'vue';
|
|
|
|
/**
|
|
* The ContextMenuAPI allows the addition of new context menu actions, and for the context menu to be launched from
|
|
* custom HTML elements.
|
|
* @interface ContextMenuAPI
|
|
* @memberof module:openmct
|
|
*/
|
|
class ContextMenuAPI {
|
|
constructor() {
|
|
this._allActions = [];
|
|
this._activeContextMenu = undefined;
|
|
|
|
this._hideActiveContextMenu = this._hideActiveContextMenu.bind(this);
|
|
this.registerAction = this.registerAction.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 ContextMenuAction
|
|
* @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
|
|
*/
|
|
registerAction(actionDefinition) {
|
|
this._allActions.push(actionDefinition);
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
_showContextMenuForObjectPath(objectPath, x, y, actionsToBeIncluded) {
|
|
|
|
let applicableActions = this._allActions.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;
|
|
}
|
|
});
|
|
|
|
if (this._activeContextMenu) {
|
|
this._hideActiveContextMenu();
|
|
}
|
|
|
|
this._activeContextMenu = this._createContextMenuForObject(objectPath, applicableActions);
|
|
this._activeContextMenu.$mount();
|
|
document.body.appendChild(this._activeContextMenu.$el);
|
|
|
|
let position = this._calculatePopupPosition(x, y, this._activeContextMenu.$el);
|
|
this._activeContextMenu.$el.style.left = `${position.x}px`;
|
|
this._activeContextMenu.$el.style.top = `${position.y}px`;
|
|
|
|
document.addEventListener('click', this._hideActiveContextMenu);
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
_calculatePopupPosition(eventPosX, eventPosY, menuElement) {
|
|
let menuDimensions = menuElement.getBoundingClientRect();
|
|
let overflowX = (eventPosX + menuDimensions.width) - document.body.clientWidth;
|
|
let overflowY = (eventPosY + menuDimensions.height) - document.body.clientHeight;
|
|
|
|
if (overflowX > 0) {
|
|
eventPosX = eventPosX - overflowX;
|
|
}
|
|
|
|
if (overflowY > 0) {
|
|
eventPosY = eventPosY - overflowY;
|
|
}
|
|
|
|
return {
|
|
x: eventPosX,
|
|
y: eventPosY
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_hideActiveContextMenu() {
|
|
document.removeEventListener('click', this._hideActiveContextMenu);
|
|
document.body.removeChild(this._activeContextMenu.$el);
|
|
this._activeContextMenu.$destroy();
|
|
this._activeContextMenu = undefined;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
_createContextMenuForObject(objectPath, actions) {
|
|
return new Vue({
|
|
components: {
|
|
ContextMenu: ContextMenuComponent
|
|
},
|
|
provide: {
|
|
actions: actions,
|
|
objectPath: objectPath
|
|
},
|
|
template: '<ContextMenu></ContextMenu>'
|
|
});
|
|
}
|
|
}
|
|
export default ContextMenuAPI;
|