// KefinTweaks Custom Menu Links Configuration UI // Modular configuration modal for managing custom menu links (function() { 'use strict'; const LOG = (...args) => console.log('[KefinTweaks CustomMenuLinks Config]', ...args); const ERR = (...args) => console.error('[KefinTweaks CustomMenuLinks Config]', ...args); const MODAL_ID = 'kefin-custommenulinks-config'; /** * Load configuration from window.KefinTweaksConfig */ async function loadConfig() { const config = window.KefinTweaksConfig || {}; return { customMenuLinks: Array.isArray(config.customMenuLinks) ? config.customMenuLinks : [] }; } /** * Save configuration to JS Injector */ async function saveConfig(customMenuLinks) { try { if (!window.KefinTweaksConfig) { window.KefinTweaksConfig = {}; } window.KefinTweaksConfig.customMenuLinks = customMenuLinks; // Placement is per-link; do not keep the legacy global top-nav flag delete window.KefinTweaksConfig.showCustomMenuLinksInTopNav; if (window.KefinTweaksUtils && window.KefinTweaksUtils.saveConfigToJavaScriptInjector) { await window.KefinTweaksUtils.saveConfigToJavaScriptInjector(); LOG('Configuration saved to JS Injector'); return true; } else if (window.KefinTweaksConfiguration && window.KefinTweaksConfiguration.findJavaScriptInjectorPlugin) { const pluginId = await window.KefinTweaksConfiguration.findJavaScriptInjectorPlugin(); if (pluginId) { await window.KefinTweaksConfiguration.saveConfigToJavaScriptInjector(window.KefinTweaksConfig); LOG('Configuration saved to JS Injector (fallback)'); return true; } ERR('saveConfigToJavaScriptInjector not available'); return false; } else { ERR('saveConfigToJavaScriptInjector not available'); return false; } } catch (error) { ERR('Error saving config:', error); return false; } } /** * Build configuration HTML */ function buildConfigHTML(config) { return `
name and either url or action (a dotted path on window, e.g. MyPlugin.openDialog). Defaults: sideMenu true, topNavigation "none", userMenu false. Use collapsed with topNavigation: "main" on v12 to place under More. Optional order overrides top-nav position: for main, left-to-right child index (0 = first); for right, right-to-left (0 = last child).[
{
"name": "My Custom Link",
"icon": "link",
"url": "#/userpluginsettings.html?pageUrl=https://domain.com/custom-page",
"openInNewTab": false,
"sideMenu": true,
"topNavigation": "none",
"userMenu": false,
"collapsed": false
},
{
"name": "Top Nav First",
"icon": "star",
"url": "#/home",
"sideMenu": false,
"topNavigation": "main",
"order": 0
},
{
"name": "Top Nav Link",
"icon": "star",
"url": "#/home",
"sideMenu": false,
"topNavigation": "main",
"collapsed": true
},
{
"name": "Header Right Near End",
"icon": "extension",
"action": "MyPlugin.openDialog",
"sideMenu": false,
"topNavigation": "right",
"order": 1
},
{
"name": "External Link",
"icon": "open_in_new",
"url": "https://example.com",
"openInNewTab": true,
"sideMenu": true,
"topNavigation": "none"
}
]