Announcing the Saviynt Knowledge Exchange unifying the Saviynt forums, documentation, training,
and more in a single search tool across platforms. Read the announcement here.

Saviynt UI Improvements for mouse/kb devices (Tampermonkey Script)

yogesh2
New Contributor III
New Contributor III

I have created a custom script to modify some Saviynt UI parameters and this makes Saviynt UI much more functional in my opinion. I didn't know where else to share so sharing here.

The OOTB UI is good but most elements are too large IMO (maybe optimized for touch devices), and since most of us are using Saviynt on a PC (I hope) with a mouse and keyboard, I think this causes lots of wasted space.

Anyways, here are some screenshots showing what this script changes:

Default user identity page:

yogesh2_0-1712296690391.png

Modified UI, rows are more compact and thus more records are shown on screen in same space. (this is applied for most pages with lists, like endpoint lists, connections, etc.)

yogesh2_2-1712296817014.png

User update history (OOTB):

yogesh2_6-1712297136586.png

Modified:

yogesh2_8-1712297171546.png

Changes to data analyzer: uses monospace font, wider area to write query by default (so you don't have to resize the query textbox every-single-time), run queries by pressing Ctrl+Enter on keyboard, show-hide table list with a button/keyboard shortcut:

OOTB Style:

yogesh2_11-1712298006547.png

Modified (Table list hidden):

yogesh2_9-1712297395149.png

Modified (Table list visible):

yogesh2_10-1712297599453.png

Script:

// ==UserScript==
// @name         Saviynt UI Improvements
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  This script tries to make Saviynt UI better optimized for non touch devices.
// @author       Yogesh
// @match        *://*.saviyntcloud.com/*
// @exclude      *://docs.saviyntcloud.com/*
// @grant GM_addStyle
// ==/UserScript==

(function () {
    'use strict';


    //window.onload = function () {
    setTimeout(function() {

        // CSS modifications
        GM_addStyle("td { padding: 3px !important; }\
        .control-label {margin-top: 0px !important;}\
        label {margin-bottom: 0px !important;}\
        .form-group {margin-bottom: 3px !important;}\
        body {font-family: 'Tahoma', sans-serif !important;}\
        .page-title{margin: 0 0 5px 0 !important}\
        ");

        // Thiccen the scroll bars:
        // checks for updates to the page and applies the height to new scrollbars when they are loaded
        const scrollBarObserver = new MutationObserver(() => {
            const scrollBars = document.querySelectorAll(".slimScrollBarH");
            scrollBars.forEach((scrollBar) => {
                scrollBar.style.height = "25px";
            });
        });

        scrollBarObserver.observe(document.body, {
            childList: true,
            subtree: true,
        });

        // modifications for data analyzer
        if (window.location.href.includes("dataAnalyzer")) {

            GM_addStyle("body {font-family: 'Consolas', monospace !important;}            ");

            document.addEventListener("keydown", (event) => {
                // RUN QUERY WITH CTRL+ENTER
                if (event.ctrlKey && event.key === "Enter") {
                    // Get a reference to the querySubmit button
                    const querySubmitButton = document.getElementById("querySubmit");
                    querySubmitButton.click();
                }
                // HIDE TABLE LIST SIDEBAR WITH CTRL + '
                if (event.ctrlKey && event.key === "'") {
                    if (tablelistbox.style.display === "none") {
                        tablelistbox.style.display = "block";
                    } else {
                        tablelistbox.style.display = "none";
                    }
                }
            });

            const scrollbar = document.querySelector("#pageLayout > div > div:nth-child(2) > div.col-md-3.custpaddingright > div > div.portlet-body > div > div.slimScrollBar");
            scrollbar.style.width = "20px";
//             scrollbar.style.visibility = "hidden";

            const scrollbarback = document.querySelector("#pageLayout > div > div:nth-child(2) > div.col-md-3.custpaddingright > div > div.portlet-body > div > div.slimScrollRail");
            scrollbarback.style.width = "20px";
//             scrollbarback.style.visibility = "hidden";

            const containerbox = document.querySelector("#pageLayout > div > div:nth-child(2)");
            containerbox.style.display = "flex";
            containerbox.style.flexDirection = "row";

            const tablelistbox = document.querySelector("#pageLayout > div > div:nth-child(2) > div.col-md-3.custpaddingright");
            tablelistbox.style.maxWidth = "400px"
            tablelistbox.style.display = "none";

            const sqlbuilder = document.querySelector("#pageLayout > div > div:nth-child(2) > div.col-md-9.custpaddingleft");
            sqlbuilder.classList.remove("custpaddingleft");

            sqlbuilder.style.flex = "1";

            // enlarge query area
            const queryArea = document.getElementById("queryArea");
            queryArea.style.height = "200px";

            // const tablelistcontent = document.querySelector("body > div.page-container > div.page-content > div:nth-child(2) > div.col-md-3.custpaddingright > div > div.portlet-body > div > div.tablediv");
            // tablelistcontent.style.height = "100%";
            // tablelistcontent.style.overflow = "auto";

            // const tablelist = document.querySelector("body > div.page-container > div.page-content > div:nth-child(2) > div.col-md-3.custpaddingright > div > div.portlet-body > div");
            // tablelist.style.height = "auto";

            // hide the useless header (blank space on top)
            const pageTitle = document.querySelector("#pageLayout > div > div:nth-child(1) > div > ul");
            pageTitle.style.display = "none";


            // BUTTON TO SHOW HIDE TABLE LIST IN DATA ANALYZER
            // Create a button element
            const button = document.createElement("button");
            button.textContent = "Toggle Table List (Ctrl + ')";
            button.style.position = "fixed";
            button.style.bottom = "20px";
            button.style.right = "20px";
            button.style.zIndex = "9999";
            button.style.borderRadius = "10px !important";
            button.style.height = "30px";
            button.id = "toggleTableList";


            // Add the button to the page
            document.body.appendChild(button);

            // Add an event listener to the button
            button.addEventListener("click", () => {
                // Toggle the display property of the table list box
                if (tablelistbox.style.display === "none") {
                    tablelistbox.style.display = "block";
                } else {
                    tablelistbox.style.display = "none";
                }
            });

        }

        // Add "show all columns" button on user repository page
        if (window.location.href.includes("users/list")) {

            const button = document.createElement("button");
            button.textContent = "Show All Fields";
            button.style.position = "fixed";
            button.style.bottom = "20px";
            button.style.right = "20px";
            button.style.zIndex = "9999";
            button.style.borderRadius = "10px !important";
            button.style.height = "30px";
            button.id = "toggleTableList";


            // Add the button to the page
            document.body.appendChild(button);

            // Get the table list box element

            // Add an event listener to the button
            button.addEventListener("click", () => {
                // Get the div that contains the checkboxes
                const checkboxDiv = document.getElementById("usersList_column_toggler");

                // Get all checkboxes within the div
                // const checkboxes = checkboxDiv.querySelectorAll("input[type='checkbox']");

                // // Loop through the checkboxes and check them
                // checkboxes.forEach(checkbox => {
                //     checkbox.checked = true;
                // });

                // get all spans and add "checked" class to them
                // const spans = checkboxDiv.querySelectorAll("span");
                // for (let i = 0; i < spans.length; i++) {
                //     spans[i].classList.add("checked");
                // }

                const labels = checkboxDiv.getElementsByTagName("label");

                for (let i = 0; i < labels.length; i++) {
                    const span = labels[i].getElementsByTagName("span")[0];
                    if (!span.classList.contains("checked")) {
                        labels[i].click();
                    }
                }

            });

        }



    }, 2000); // 2000 milliseconds (adjust as needed) // if using timeout
    // } // if using Window.onload
    //end



})();

 

1 REPLY 1

rushikeshvartak
All-Star
All-Star

For any desired improvements or enhancements to this process, Saviynt encourages you to submit your proposal through Saviynt's Ideas Portal at https://ideas.saviynt.com/ideas/

Your valuable input is crucial to shaping the evolution of Saviynt systems.

Please notify us once the idea ticket has been created.


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.