codekingpro/portable-devtools
114k
1/////////////////////////////////////////////////////////////2//3// pgAdmin 4 - PostgreSQL Tools4//5// Copyright (C) 2013 - 2024, The pgAdmin Development Team6// This software is released under the PostgreSQL Licence7//8//////////////////////////////////////////////////////////////9import _ from 'lodash';10import gettext from 'sources/gettext';11 12export default class Menu {13 constructor(name, label, id, index, addSepratior) {14 this.label = label;15 this.name = name;16 this.id = id;17 this.index = index || 1;18 this.menuItems = [];19 this.addSepratior = addSepratior || false;20 }21 22 static create(name, label, id, index, addSepratior) {23 let menuObj = new Menu(name, label, id, index, addSepratior);24 return menuObj;25 }26 27 addMenuItem(menuItem, index=null) {28 if (menuItem instanceof MenuItem) {29 menuItem.parentMenu = this;30 if(index) {31 this.menuItems.splice(index, 0, menuItem);32 } else {33 this.menuItems.push(menuItem);34 Menu.sortMenus(this.menuItems);35 }36 } else {37 throw new Error(gettext('Invalid MenuItem instance'));38 }39 40 41 }42 43 addMenuItems(menuItems) {44 menuItems.forEach((item) => {45 if (item instanceof MenuItem) {46 item.parentMenu = this;47 this.menuItems.push(item);48 if(item?.menu_items && item.menu_items.length > 0) {49 item.menu_items.forEach((i)=> {50 i.parentMenu = item;51 });52 Menu.sortMenus(item.menu_items);53 }54 } else {55 let subItems = Object.values(item);56 subItems.forEach((subItem)=> {57 if (subItem instanceof MenuItem) {58 subItem.parentMenu = this;59 this.menuItems.push(subItem);60 } else {61 throw new Error(gettext('Invalid MenuItem instance'));62 }63 });64 }65 });66 67 // Sort by alphanumeric ordered first68 this.menuItems.sort(function (a, b) {69 return a.label.localeCompare(b.label);70 });71 72 // Sort by priority73 this.menuItems.sort(function (a, b) {74 return a.priority - b.priority;75 });76 77 }78 79 setMenuItems(menuItems) {80 this.menuItems = menuItems;81 Menu.sortMenus(this.menuItems);82 83 this.menuItems.forEach((item)=> {84 if(item?.menu_items?.length > 0) {85 Menu.sortMenus(item.menu_items);86 }87 });88 }89 90 static sortMenus(menuItems) {91 // Sort by alphanumeric ordered first92 menuItems.sort(function (a, b) {93 return a.label.localeCompare(b.label);94 });95 96 // Sort by priority97 menuItems.sort(function (a, b) {98 return a.priority - b.priority;99 });100 }101 102 getMenuItems() {103 return this.menuItems;104 }105}106 107 108export class MenuItem {109 constructor(options, onDisableChange, onChangeChecked) {110 let menu_opts = [111 'name', 'label', 'priority', 'module', 'callback', 'data', 'enable',112 'category', 'target', 'url', 'node',113 'checked', 'below', 'menu_items', 'is_checkbox', 'action', 'applies', 'is_native_only', 'type',114 ];115 let defaults = {116 url: '#',117 target: '_self',118 enable: true,119 type: 'normal'120 };121 _.extend(this, defaults, _.pick(options, menu_opts));122 if (!this.callback) {123 this.callback = (item) => {124 if (item.url != '#') {125 window.open(item.url);126 }127 };128 }129 this.onDisableChange = onDisableChange;130 this.changeChecked = onChangeChecked;131 this._isDisabled = true;132 this.checkAndSetDisabled();133 }134 135 static create(options) {136 return MenuItem(options);137 }138 139 change_checked(isChecked) {140 this.checked = isChecked;141 this.changeChecked?.(this);142 }143 144 getMenuItems() {145 return this.menu_items;146 }147 148 contextMenuCallback(self) {149 self.callback();150 }151 152 getContextItem(label, is_disabled, sub_ctx_item) {153 let self = this;154 return {155 name: label,156 disabled: is_disabled,157 callback: () => { this.contextMenuCallback(self); },158 ...(sub_ctx_item && Object.keys(sub_ctx_item).length > 0) && { items: sub_ctx_item }159 };160 }161 162 checkAndSetDisabled(node, item, forceDisable) {163 if(!_.isUndefined(forceDisable)) {164 this._isDisabled = forceDisable;165 } else {166 this._isDisabled = this.disabled(node, item);167 }168 this.onDisableChange?.(this.parentMenu, this);169 }170 171 get isDisabled() {172 return this._isDisabled;173 }174 175 /*176 * Checks this menu enable/disable state based on the selection.177 */178 disabled(node, item) {179 if (this.enable == undefined) {180 return false;181 }182 183 if (this.node) {184 if (!node) {185 return true;186 }187 if (_.isArray(this.node) ? (188 _.indexOf(this.node, node) == -1189 ) : (this.node != node._type)) {190 return true;191 }192 }193 194 if (_.isBoolean(this.enable)) return !this.enable;195 if (_.isFunction(this.enable) && node) {196 return !this.enable.apply(this.module, [node, item, this.data]);197 }198 if (this.module && _.isBoolean(this.module[this.enable])) {199 return !this.module[this.enable];200 }201 if(!node) {202 return true;203 }204 if (this.module && _.isFunction(this.module[this.enable])) {205 return !(this.module[this.enable])(node, item, this.data);206 }207 208 return false;209 }210}211 