Instantly share code, notes, and snippets.
Last active
February 22, 2024 12:13
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save Damecek/e91c0398257039156e8d653bc3b59c5a to your computer and use it in GitHub Desktop.
Streamline Salesforce navigation with this Tampermonkey script. Quickly jump to key pages using aliases, directly from your browser. Ideal for devs and admins.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name URL Alias Navigator | |
| // @version 2.0 | |
| // @description Navigate using aliases | |
| // @author Damecek | |
| // @match https://*.lightning.force.com/* | |
| // @match https://*.sandbox.lightning.force.com/* | |
| // @grant none | |
| // @require https://unpkg.com/quick-score@0.2.0/dist/quick-score.min.js | |
| // ==/UserScript== | |
| (function() { | |
| "use strict"; | |
| const AliasNavigator = (() => { | |
| const MAX_DISPLAYED_ALIASES = 4; | |
| const aliases = [ | |
| { id: "Flow", path: "/lightning/setup/Flows/home" }, | |
| { id: "Digital Experience", path: "lightning/setup/SetupNetworks/home" }, | |
| { id: "Reports", path: "/lightning/o/Report/home" }, | |
| { id: "Dashboards", path: "/lightning/o/Dashboard/home" }, | |
| { id: "Deployment Status", path: "/lightning/setup/DeployStatus/home" }, | |
| { id: "Apex Jobs", path: "lightning/setup/AsyncApexJobs/home" }, | |
| { id: "Scheduled Jobs", path: "lightning/setup/ScheduledJobs/home" }, | |
| { id: "Paused And Failed Flow Interviews", path: "lightning/setup/Pausedflows/home" }, | |
| { id: "Setup", path: "/lightning/setup/SetupOneHome/home" }, | |
| { id: "Users", path: "/lightning/setup/ManageUsers/home" }, | |
| { id: "Profiles", path: "/lightning/setup/Profiles/home" }, | |
| { id: "Permission Sets", path: "/lightning/setup/PermSets/home" }, | |
| { id: "Object Manager", path: "/lightning/setup/ObjectManager/home" }, | |
| { id: "Custom Metadata", path: "/lightning/setup/CustomMetadata/home" }, | |
| { id: "Custom Settings", path: "/lightning/setup/CustomSettings/home" }, | |
| { id: "Company Information", path: "/lightning/setup/CompanyProfileInfo/home" }, | |
| { id: "Account List", path: "/lightning/o/Account/home" }, | |
| { id: "Contact List", path: "/lightning/o/Contact/home" }, | |
| { id: "Order List", path: "/lightning/o/Order/home" }, | |
| { id: "Opportunity List", path: "/lightning/o/Opportunity/home" } | |
| ]; | |
| function shouldTogglePopup(e) { | |
| return (e.ctrlKey || e.metaKey) && e.shiftKey && e.code === "KeyS"; | |
| } | |
| let qs = new quickScore.QuickScore(aliases, { keys: ["id"] }); | |
| let selectedIndex = 0; | |
| const container = createUI(); | |
| function createUI() { | |
| const containerHtml = ` | |
| <style> | |
| :root { | |
| --width: 350px; | |
| --height: 40px; | |
| --pos-top: 30vh; | |
| } | |
| #alias-input-container { | |
| display: none; | |
| position: fixed; | |
| top: calc(var(--pos-top) - var(--height)); | |
| left: calc(50vw - var(--width) / 2); | |
| z-index: 10000; | |
| background-color: #f0f0f0; | |
| border-radius: 8px; | |
| padding: 12px; | |
| box-shadow: 0 4px 8px rgba(0,0,0,.2); | |
| width: var(--width); | |
| flex-direction: column; | |
| } | |
| #alias-input { | |
| width: 100%; | |
| padding: 8px; | |
| box-sizing: border-box; | |
| font-size: large; | |
| border-radius: 4px; | |
| border: 1px solid #ccc; | |
| background-color: #f9f9f9; | |
| } | |
| #alias-dropdown { | |
| margin-top: 8px; | |
| background-color: #f9f9f9; | |
| border-radius: 4px; | |
| border: 1px solid #ccc; | |
| max-height: 160px; | |
| overflow-y: auto; | |
| font-size: large; | |
| } | |
| </style> | |
| <div id="alias-input-container"> | |
| <input type="text" id="alias-input" placeholder="Enter alias..."> | |
| <div id="alias-dropdown"></div> | |
| </div> | |
| `; | |
| document.body.insertAdjacentHTML("beforeend", containerHtml); | |
| return { | |
| container: document.getElementById("alias-input-container"), | |
| input: document.getElementById("alias-input"), | |
| dropdown: document.getElementById("alias-dropdown") | |
| }; | |
| } | |
| function toggleInputDisplay(show = true) { | |
| if (show) { | |
| container.container.style.display = "flex"; | |
| container.input.focus(); | |
| updateDropdown(); | |
| } else { | |
| if (container.container.style.display !== "none") { | |
| container.container.style.display = "none"; | |
| container.input.value = ""; | |
| container.dropdown.innerHTML = ""; | |
| } else { | |
| container.container.style.display = "flex"; | |
| container.input.focus(); | |
| updateDropdown(); | |
| } | |
| } | |
| } | |
| function updateDropdown() { | |
| const inputVal = container.input.value; | |
| const results = qs.search(inputVal); | |
| const toDisplay = results.slice(0, MAX_DISPLAYED_ALIASES).map(result => result.item.id); | |
| if (toDisplay.length === 0) { | |
| container.dropdown.style.display = "none"; | |
| } else { | |
| container.dropdown.style.display = ""; | |
| container.dropdown.innerHTML = toDisplay | |
| .map((alias, index) => `<div style="padding: 8px; cursor: pointer; ${index === selectedIndex ? "background-color: #ddd;" : ""}" class="dropdown-item">${alias}</div>`) | |
| .join(""); | |
| addDropdownEvents(toDisplay); | |
| } | |
| } | |
| function addDropdownEvents(toDisplay) { | |
| document.querySelectorAll(".dropdown-item").forEach((item, index) => { | |
| item.addEventListener("mouseenter", () => { | |
| removeHighlight(); | |
| selectedIndex = index; | |
| item.style.backgroundColor = "#ddd"; | |
| }); | |
| item.addEventListener("mouseleave", () => { | |
| item.style.backgroundColor = ""; | |
| }); | |
| item.addEventListener("click", () => { | |
| navigateToAlias(toDisplay[index]); | |
| toggleInputDisplay(false); | |
| }); | |
| }); | |
| } | |
| function removeHighlight() { | |
| document.querySelectorAll(".dropdown-item").forEach(item => item.style.backgroundColor = ""); | |
| } | |
| function updateHighlight(items) { | |
| removeHighlight(); | |
| if (items.length > 0) { | |
| items[selectedIndex].style.backgroundColor = "#ddd"; | |
| items[selectedIndex].scrollIntoView({ block: "nearest" }); | |
| } | |
| } | |
| function navigateToAlias(aliasId) { | |
| const aliasObj = aliases.find(alias => alias.id === aliasId); | |
| if (aliasObj && aliasObj.path) { | |
| window.location.pathname = aliasObj.path.startsWith("/") ? aliasObj.path : "/" + aliasObj.path; | |
| } | |
| } | |
| function attachEventListeners() { | |
| document.addEventListener("keydown", (e) => { | |
| if (shouldTogglePopup(e)) { | |
| e.preventDefault(); | |
| const isShown = container.container.style.display !== "none"; | |
| toggleInputDisplay(!isShown); | |
| } else if (e.code === "Escape" && container.container.style.display !== "none") { | |
| toggleInputDisplay(false); | |
| } | |
| }); | |
| container.input.addEventListener("input", () => { | |
| updateDropdown(); | |
| selectedIndex = 0; | |
| updateHighlight(document.querySelectorAll(".dropdown-item")); | |
| }); | |
| container.input.addEventListener("keydown", (e) => { | |
| const items = document.querySelectorAll(".dropdown-item"); | |
| if (e.code === "ArrowDown" || e.code === "ArrowUp") { | |
| e.preventDefault(); | |
| selectedIndex = (e.code === "ArrowDown") ? Math.min(items.length - 1, selectedIndex + 1) : Math.max(0, selectedIndex - 1); | |
| updateHighlight(items); | |
| } else if (e.code === "Enter" && items.length > 0 && items[selectedIndex]) { | |
| e.preventDefault(); | |
| navigateToAlias(items[selectedIndex].textContent); | |
| toggleInputDisplay(false); | |
| } | |
| }); | |
| } | |
| function init() { | |
| attachEventListeners(); | |
| } | |
| return { init }; | |
| })(); | |
| AliasNavigator.init(); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment