This commit is contained in:
438
src/api/gzmenu.js
Normal file
438
src/api/gzmenu.js
Normal file
@@ -0,0 +1,438 @@
|
||||
/////////////////////////////////
|
||||
// Menu utils and handlers
|
||||
//
|
||||
export default {
|
||||
///////////////////////////////////////////
|
||||
// TECH SUPPORT / CONTACT FORUM URL
|
||||
//
|
||||
contactSupportUrl() {
|
||||
const dbId = encodeURIComponent(
|
||||
window.$gz.store.state.globalSettings.serverDbId
|
||||
);
|
||||
const company = encodeURIComponent(
|
||||
window.$gz.store.state.globalSettings.company
|
||||
);
|
||||
return `https://contact.ayanova.com/contact?dbid=${dbId}&company=${company}`;
|
||||
},
|
||||
///////////////////////////////
|
||||
// CHANGE HANDLER
|
||||
//
|
||||
// Deal with a menu change request
|
||||
// called from App.vue
|
||||
handleMenuChange(vm, ctx) {
|
||||
const UTILITY_TYPES = [
|
||||
window.$gz.type.NoType,
|
||||
window.$gz.type.Global,
|
||||
window.$gz.type.NoType,
|
||||
window.$gz.type.ServerState,
|
||||
window.$gz.type.License,
|
||||
window.$gz.type.LogFile,
|
||||
window.$gz.type.ServerJob,
|
||||
window.$gz.type.TrialSeeder,
|
||||
window.$gz.type.ServerMetrics,
|
||||
window.$gz.type.UserOptions,
|
||||
window.$gz.type.FormCustom,
|
||||
window.$gz.type.DataListSavedFilter,
|
||||
window.$gz.type.GlobalOps,
|
||||
window.$gz.type.BizMetrics,
|
||||
window.$gz.type.Backup,
|
||||
window.$gz.type.Notification,
|
||||
window.$gz.type.NotifySubscription
|
||||
];
|
||||
|
||||
vm.appBar.isMain = ctx.isMain;
|
||||
vm.appBar.icon = ctx.icon;
|
||||
|
||||
vm.appBar.title = ""; //this prevents fou[translated]c
|
||||
vm.appBar.readOnly = ctx.readOnly;
|
||||
|
||||
if (ctx.readOnly === true) {
|
||||
vm.appBar.color = "readonlybanner";
|
||||
} else {
|
||||
vm.appBar.color = ctx.isMain ? "primary" : "secondary";
|
||||
}
|
||||
|
||||
//ctx.title if set is a Translation key
|
||||
//ctx.formData.recordName is the object name or serial number or whatever identifies it uniquely
|
||||
let recordName = "";
|
||||
if (
|
||||
ctx &&
|
||||
ctx.formData &&
|
||||
ctx.formData.recordName &&
|
||||
ctx.formData.recordName != "null" //some forms (part) present "null" as the record name due to attempts to format a name so if that's the case just turn it into null here to bypass
|
||||
) {
|
||||
recordName = ctx.formData.recordName;
|
||||
}
|
||||
const hasRecordName = !window.$gz.util.stringIsNullOrEmpty(recordName);
|
||||
if (ctx.title) {
|
||||
//it has a title translation key
|
||||
const translatedTitle = vm.$sock.t(ctx.title);
|
||||
if (hasRecordName) {
|
||||
//recordname takes all precedence in AppBar in order to conserve space (narrow view etc)
|
||||
//also it just looks cleaner, the icon is already there to indicate where the user is at
|
||||
vm.appBar.title = recordName;
|
||||
document.title = `${recordName} - ${translatedTitle} Sockeye `;
|
||||
} else {
|
||||
vm.appBar.title = translatedTitle;
|
||||
document.title = `${translatedTitle} ${recordName}`;
|
||||
}
|
||||
} else {
|
||||
if (hasRecordName) {
|
||||
//not title but has record name
|
||||
vm.appBar.title = recordName;
|
||||
document.title = `${recordName} Sockeye`;
|
||||
} else {
|
||||
document.title = "Sockeye";
|
||||
}
|
||||
}
|
||||
|
||||
//Parse the formdata if present
|
||||
//FORMDATA is OPTIONAL and only required for forms that need to allow
|
||||
//viewing object history, attachments, custom fields, etc that kind of thing
|
||||
//usually CORE objects with an id, NOT utility type forms
|
||||
let formSockType = 0;
|
||||
let formRecordId = 0;
|
||||
if (ctx.formData) {
|
||||
if (ctx.formData.sockType != null) {
|
||||
formSockType = ctx.formData.sockType;
|
||||
}
|
||||
if (ctx.formData.recordId != null) {
|
||||
formRecordId = ctx.formData.recordId;
|
||||
}
|
||||
}
|
||||
|
||||
//flag for if it's wikiable, reviewable, attachable, searchable, historical
|
||||
const isCoreBizObject = formSockType != 0 && formRecordId != 0;
|
||||
|
||||
//set the help url if presented or default to the User section intro
|
||||
vm.appBar.helpUrl = ctx.helpUrl ? ctx.helpUrl : "user-intro";
|
||||
|
||||
vm.appBar.menuItems = [];
|
||||
|
||||
//CONTEXT TOP PORTION
|
||||
//populate the context portion of the menu so handle accordingly
|
||||
if (ctx.menuItems) {
|
||||
vm.appBar.menuItems = ctx.menuItems;
|
||||
}
|
||||
|
||||
//STANDARD BIZ OBJECT OPTIONS
|
||||
//NOTE: This applies equally to all core business object types that are basically real world and have an id and a type (all are wikiable, attachable and reviewable)
|
||||
//Not utility type objects like datalist etc
|
||||
//there will be few exceptions so they will be coded in later if needed but assume anything with an id and a type
|
||||
if (isCoreBizObject && !ctx.hideCoreBizStandardOptions) {
|
||||
//"Review" was follow up type of schedule marker
|
||||
//basically it's now a "Reminder" type of object but it's own thing with separate collection
|
||||
|
||||
vm.appBar.menuItems.push({
|
||||
title: "Review",
|
||||
icon: "$sockiCalendarCheck",
|
||||
key: "app:review",
|
||||
data: {
|
||||
sockType: formSockType,
|
||||
recordId: formRecordId,
|
||||
recordName: recordName
|
||||
}
|
||||
});
|
||||
|
||||
//AFAIK right now any item with an id and a type can have a history
|
||||
//anything not would be the exception rather than the rule
|
||||
vm.appBar.menuItems.push({
|
||||
title: "History",
|
||||
icon: "$sockiHistory",
|
||||
key: "app:history",
|
||||
data: { sockType: formSockType, recordId: formRecordId }
|
||||
});
|
||||
}
|
||||
|
||||
//CUSTOMIZE
|
||||
//set custom fields and link to translation text editor
|
||||
|
||||
if (
|
||||
isCoreBizObject &&
|
||||
ctx.formData &&
|
||||
ctx.formData.formCustomTemplateKey != undefined &&
|
||||
window.$gz.role.hasRole([
|
||||
window.$gz.role.AUTHORIZATION_ROLES.BizAdmin,
|
||||
window.$gz.role.AUTHORIZATION_ROLES.BizAdminRestricted
|
||||
])
|
||||
) {
|
||||
//NOTE: BizAdmin can edit, BizAdminRestricted can read only
|
||||
//add customize menu item
|
||||
|
||||
//customize
|
||||
vm.appBar.menuItems.push({
|
||||
title: "Customize",
|
||||
icon: "$sockiCustomize",
|
||||
data: ctx.formData.formCustomTemplateKey,
|
||||
key: "app:customize"
|
||||
});
|
||||
}
|
||||
|
||||
//GLOBAL BOTTOM PORTION
|
||||
|
||||
//SEARCH
|
||||
//all forms except the search form
|
||||
if (!ctx.hideSearch && !UTILITY_TYPES.includes(formSockType)) {
|
||||
//For all forms but not on the search form itself; if this is necessary for others then make a nosearch or something flag controlled by incoming ctx but if not then this should suffice
|
||||
vm.appBar.menuItems.push({
|
||||
title: "Search",
|
||||
icon: "$sockiSearch",
|
||||
key: "app:search",
|
||||
data: formSockType
|
||||
});
|
||||
}
|
||||
|
||||
//HELP
|
||||
vm.appBar.menuItems.push({
|
||||
title: "MenuHelp",
|
||||
icon: "$sockiQuestionCircle",
|
||||
key: "app:help",
|
||||
data: vm.appBar.helpUrl
|
||||
});
|
||||
|
||||
//ABOUT
|
||||
if (!isCoreBizObject && ctx.helpUrl != "sock-about") {
|
||||
vm.appBar.menuItems.push({
|
||||
title: "HelpAboutSockeye",
|
||||
icon: "$sockiInfoCircle",
|
||||
key: "app:nav:abt",
|
||||
data: "sock-about"
|
||||
});
|
||||
}
|
||||
},
|
||||
//Unused to date of beta 0.9
|
||||
// ///////////////////////////////
|
||||
// // CHANGE HANDLER
|
||||
// //
|
||||
// // Deal with a menu item update request
|
||||
// // called from App.vue
|
||||
// handleReplaceMenuItem(vm, newItem) {
|
||||
// if (!vm.appBar.menuItems || !newItem) {
|
||||
// return;
|
||||
// }
|
||||
// //Find the key that is in the collection and replace it
|
||||
// for (let i = 0; i < vm.appBar.menuItems.length; i++) {
|
||||
// if (vm.appBar.menuItems[i].key == newItem.key) {
|
||||
// //NOTE: since we are adding a new object, it has no reactivity in it so we need to use the Vue.Set to set it which
|
||||
// //automatically adds the setters and getters that trigger reactivity
|
||||
// //If it was set directly on the array it wouldn't update the UI
|
||||
// vm.$set(vm.appBar.menuItems, i, newItem);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//////////////////////////////////////////////
|
||||
// LAST REPORT CHANGE HANDLER
|
||||
// update / add last report menu item
|
||||
//
|
||||
handleUpsertLastReport(vm, newItem) {
|
||||
if (!vm.appBar.menuItems || !newItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
window.$gz.eventBus.$emit("menu-upsert-last-report", {
|
||||
title: reportSelected.name,
|
||||
notrans: true,
|
||||
icon: "$sockiFileAlt",
|
||||
key: formKey + ":report:" + reportSelected.id,
|
||||
vm: vm
|
||||
});
|
||||
*/
|
||||
let key = null;
|
||||
//Find the last report key and update it if present
|
||||
for (let i = 0; i < vm.appBar.menuItems.length; i++) {
|
||||
key = vm.appBar.menuItems[i].key;
|
||||
if (key && key.includes(":report:")) {
|
||||
vm.appBar.menuItems[i].key = newItem.key;
|
||||
vm.appBar.menuItems[i].title = newItem.title;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//No prior last report so slot it in under the report one
|
||||
for (let i = 0; i < vm.appBar.menuItems.length; i++) {
|
||||
key = vm.appBar.menuItems[i].key;
|
||||
if (key && key.endsWith(":report")) {
|
||||
vm.appBar.menuItems.splice(i + 1, 0, newItem);
|
||||
}
|
||||
}
|
||||
},
|
||||
///////////////////////////////
|
||||
// ENABLE / DISABLE HANDLER
|
||||
//
|
||||
// Deal with a menu item enable / disable
|
||||
// called from App.vue
|
||||
handleDisableMenuItem(vm, key, disabled) {
|
||||
if (!vm.appBar.menuItems || !key) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Find the menu item and set it to disabled and recolor it to disabled color and return
|
||||
for (let i = 0; i < vm.appBar.menuItems.length; i++) {
|
||||
const menuItem = vm.appBar.menuItems[i];
|
||||
if (menuItem.key == key) {
|
||||
vm.$set(vm.appBar.menuItems[i], "disabled", disabled);
|
||||
//menuItem.disabled = disabled;
|
||||
vm.$set(vm.appBar.menuItems[i], "color", disabled ? "disabled" : "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
///////////////////////////////
|
||||
// CHANGE ICON HANDLER
|
||||
// Change icon dymanically
|
||||
// (note, can pass null for new icon to clear it)
|
||||
//
|
||||
handleChangeMenuItemIcon(vm, key, newIcon) {
|
||||
if (!vm.appBar.menuItems || !key) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Find the menu item and change it's icon
|
||||
for (let i = 0; i < vm.appBar.menuItems.length; i++) {
|
||||
const menuItem = vm.appBar.menuItems[i];
|
||||
if (menuItem.key == key) {
|
||||
vm.$set(vm.appBar.menuItems[i], "icon", newIcon);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
///////////////////////////////
|
||||
// APP (GLOBAL) CLICK HANDLER
|
||||
//
|
||||
// Deal with a menu change request
|
||||
// called from App.vue
|
||||
handleAppClick(vm, menuItem) {
|
||||
//Key will start with the string "app:" if it's a global application command that should be handled here,
|
||||
//otherwise it's a local command for a local form only
|
||||
//If there is any extended information required for the command it will be in the data property of the menu item
|
||||
//split a key into component parts, part one is the responsible party, part two is the command, part three only exists to make it unique if necessary
|
||||
//each part is separated by a colon
|
||||
|
||||
//Handle different items
|
||||
const item = this.parseMenuItem(menuItem);
|
||||
if (!item.disabled && item.owner == "app") {
|
||||
switch (item.key) {
|
||||
case "help":
|
||||
if (item.data.includes("~customer~")) {
|
||||
window.open(
|
||||
window.$gz.api.helpUrlCustomer() +
|
||||
item.data.replace("~customer~", ""),
|
||||
"_blank"
|
||||
);
|
||||
} else {
|
||||
window.open(window.$gz.api.helpUrl() + item.data, "_blank");
|
||||
}
|
||||
break;
|
||||
|
||||
case "search":
|
||||
vm.$router.push({
|
||||
name: "home-search",
|
||||
params: { socktype: item.data }
|
||||
});
|
||||
break;
|
||||
case "review":
|
||||
//go to list
|
||||
// path: "/home-reviews/:aType?/:objectId?",
|
||||
vm.$router.push({
|
||||
name: "home-reviews",
|
||||
params: {
|
||||
aType: window.$gz.util.stringToIntOrNull(item.data.sockType),
|
||||
objectId: window.$gz.util.stringToIntOrNull(item.data.recordId),
|
||||
name: item.data.recordName
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "history":
|
||||
vm.$router.push({
|
||||
name: "sock-history",
|
||||
params: {
|
||||
socktype: item.data.sockType,
|
||||
recordid: item.data.recordId
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "customize":
|
||||
vm.$router.push({
|
||||
name: "sock-customize",
|
||||
params: { formCustomTemplateKey: item.data }
|
||||
});
|
||||
break;
|
||||
case "nav":
|
||||
vm.$router.push({ name: item.data });
|
||||
break;
|
||||
default:
|
||||
window.$gz.eventBus.$emit(
|
||||
"notify-warning",
|
||||
"gzmenu:handleAppClick - unrecognized command [" +
|
||||
menuItem.key +
|
||||
"]"
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
///////////////////////////////
|
||||
// PARSE MENU ITEM CLICK
|
||||
//
|
||||
// parse out the parts of a
|
||||
// menu item from a click event
|
||||
//
|
||||
parseMenuItem(menuItem) {
|
||||
//format is "AREA:KEY:UNIQUEID"
|
||||
//and data is in data portion
|
||||
const keyparts = menuItem.key.split(":");
|
||||
const ret = {
|
||||
owner: keyparts[0],
|
||||
key: keyparts[1],
|
||||
data: menuItem.data,
|
||||
disabled: menuItem.disabled,
|
||||
vm: menuItem.vm ? menuItem.vm : null
|
||||
};
|
||||
if (keyparts.length > 2) {
|
||||
ret.id = keyparts[2];
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
///////////////////////////////////
|
||||
// WIRE UP MENU EVENTS
|
||||
//
|
||||
// called once from app.vue only
|
||||
//
|
||||
wireUpEventHandlers(vm) {
|
||||
const that = this;
|
||||
window.$gz.eventBus.$on("menu-change", function handleMenuChange(ctx) {
|
||||
that.handleMenuChange(vm, ctx);
|
||||
});
|
||||
|
||||
window.$gz.eventBus.$on(
|
||||
"menu-upsert-last-report",
|
||||
function handleUpsertLastReport(newItem) {
|
||||
that.handleUpsertLastReport(vm, newItem);
|
||||
}
|
||||
);
|
||||
|
||||
window.$gz.eventBus.$on("menu-disable-item", function handleDisableMenuItem(
|
||||
key
|
||||
) {
|
||||
that.handleDisableMenuItem(vm, key, true);
|
||||
});
|
||||
|
||||
window.$gz.eventBus.$on("menu-enable-item", function handleDisableMenuItem(
|
||||
key
|
||||
) {
|
||||
that.handleDisableMenuItem(vm, key, false);
|
||||
});
|
||||
|
||||
window.$gz.eventBus.$on(
|
||||
"menu-change-item-icon",
|
||||
function handleChangeMenuItemIcon(key, newIcon) {
|
||||
that.handleChangeMenuItemIcon(vm, key, newIcon);
|
||||
}
|
||||
);
|
||||
|
||||
window.$gz.eventBus.$on("menu-click", function handleMenuClick(menuitem) {
|
||||
that.handleAppClick(vm, menuitem);
|
||||
});
|
||||
}
|
||||
//new functions above here
|
||||
};
|
||||
Reference in New Issue
Block a user