TutorDBOps Helper

try to improve TutorDBOps

当前为 2021-10-01 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         TutorDBOps Helper
// @namespace    http://tpdbops.tutorabc.com/
// @version      0.62
// @description  try to improve TutorDBOps
// @author       Tex
// @match        http://tpdbops.tutorabc.com/mysqlmanage/select_*
// @icon         https://www.google.com/s2/favicons?domain=tutorabc.com
// @grant        none
// ==/UserScript==

(function() {
    const isMssqlPage = location.pathname.includes('mssql');

    const dbopsStorage = {
        prefix: isMssqlPage ? 'dbops-mssql-' : 'dbops-mysql-',
        set:(key, value) => localStorage.setItem(dbopsStorage.prefix+key, value),
        get:(key) => localStorage.getItem(dbopsStorage.prefix+key),
    }
    function addCss(cssString) {
        const head = document.getElementsByTagName('head')[0];
        const newCss = document.createElement('style');
        newCss.type = "text/css";
        newCss.innerHTML = cssString;
        head.appendChild(newCss);
    }
    function loadScript(url, callback) {
        if(!url) return;
        const head = document.getElementsByTagName('head')[0];
        const script = document.createElement('script');
        head.appendChild(script);
        script.src = url;
        script.onload = script.onreadystagechange = function() {
            console.log('loaded:', url);
            callback && callback();
        }
    }

    const searchBtn = document.getElementById("search");
    function submitSql() {
        searchBtn.click();
    }

    function collapse(showLeftArea) {
        // hide sidebar
        const sidebar = document.querySelector("#container > aside");
        sidebar.style.width = showLeftArea? '230px' : '0px';
        sidebar.style.opacity = showLeftArea? '1' : '0';
        sidebar.style['z-index'] = showLeftArea? 'unset' : '-1';
        //  remove right area margin left
        const rightblock = document.querySelector("#container > section");
        rightblock.style['margin-left'] = showLeftArea ? '230px':'0px';
    }

    function aceLoadCallback() {
        ace.config.loadModule('ace/ext/textarea', function(m) {
            const textArea = document.querySelector("form div > textarea");
            m.transformTextarea(textArea, {fontSize: '14px', mode: isMssqlPage ? 'sqlserver':'mysql', theme: 'cobalt', showPrintMargin: false });
        })
    }

    loadScript('https://ajaxorg.github.io/ace-builds/src-noconflict/ace.js', aceLoadCallback);

    const storageVal = dbopsStorage.get('showLeftArea');
    let showLeftArea = storageVal === 'true' ?? true;
    collapse(showLeftArea)

    function toggleRightArea() {
        // toggle state
        showLeftArea = !showLeftArea;
        dbopsStorage.set('showLeftArea',showLeftArea);
        collapse(showLeftArea)
    }

    const hint = document.querySelector("div.box.box-success > form > table > tbody > tr > td:nth-child(2)");
    hint.style.display = 'none';

    const executePlanBtn = document.querySelector("div.box.box-success > form > table > tbody > tr > td:nth-child(1) > div > div > button:nth-child(7)")
    const hostTitle = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(1) > input");
    const dbTitle = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(3) > input");
    if(executePlanBtn) executePlanBtn.innerText="查看執行計畫";
    searchBtn.innerText="執行"
    hostTitle.value="主機 (雙擊輸入框清空)"
    dbTitle.value="資料庫"

    const hostSelector = document.querySelector("#doc-vld-post-1");
    const dbSelector = document.querySelector("#doc-vld-level-1")

    const storedHost = dbopsStorage.get('host');
    const storedDB = dbopsStorage.get('db');

    const hosts = Array.from(hostSelector.children).map(e => e.value);
    const hostInput = document.createElement('input');
    hostInput.setAttribute("list", "hostlist");
    hostInput.id='hosts';
    hostInput.name='hosts';
    hostInput.placeholder="請選擇主機";
    hostInput.className="topInput"
    hostInput.ondblclick = (e) => {
        e.target.value='';
    }
    if(storedHost) hostInput.value = storedHost;
    const hostDataList = document.createElement('datalist');
    hostDataList.id = 'hostlist';
    hosts.forEach(e => {
        const op = document.createElement('option');
        op.value = e;
        hostDataList.appendChild(op)
    });

    const hostAnchor = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(1)");
    hostAnchor.parentNode.insertBefore(hostDataList, hostAnchor.nextSibling);
    hostAnchor.parentNode.insertBefore(hostInput, hostAnchor.nextSibling);

    //hostSelector.remove();
    hostSelector.style.display="none";
    hostSelector.removeAttribute("required");
    hostSelector.name="hh";


    function updateDBInput(val, callback) {
        fetch('http://tpdbops.tutorabc.com/mysqlmanage/ipdbname/'+val)
            .then(r => r.json())
            .then(dbs => {
            dbDataList.replaceChildren(null);
            dbInput.value='';
            dbs.forEach((e, index) => {
                const op = document.createElement('option');
                op.value = e;
                dbDataList.appendChild(op)
            })
            const dbAnchor = document.querySelector("form > div.box-header.with-border.table_sort_form > a:nth-child(5)");
            dbAnchor.parentNode.insertBefore(dbDataList, dbAnchor.nextSibling);
            dbAnchor.parentNode.insertBefore(dbInput, dbAnchor.nextSibling);
            callback();
        })
    }

    const dbInput = document.createElement('input');
    dbInput.setAttribute("list", "dblist");
    dbInput.id='dbs';
    dbInput.name='dbs';
    dbInput.placeholder="請選擇資料庫";
    dbInput.className="topInput"
    dbInput.ondblclick = (e) => {
        e.target.value='';
    }
    if(storedHost && storedDB) {
        updateDBInput(storedHost, () => {dbInput.value = storedDB})
    };
    const dbDataList = document.createElement('datalist');
    dbDataList.id='dblist'
    hostInput.onchange = (e) => {
        dbopsStorage.set('host',e.target.value);
        updateDBInput(e.target.value)
        hostSelector.value=e.target.value;
    }

    dbInput.onchange = (e) => {
        dbopsStorage.set('db',e.target.value);
        dbSelector.value=e.target.value;
    }

    //dbSelector.remove();
    dbSelector.style.display="none";
    dbSelector.removeAttribute("required");
    dbSelector.name="dd";

    // autofocus sql textarea
    const sqlTextArea = document.querySelector("form > table > tbody > tr > td:nth-child(1) > div > div > textarea")
    sqlTextArea.focus();

    // enroll event
    document.onkeydown = function(e) {
        if(e.code === 'Enter' && e.ctrlKey) {
            submitSql();
        }
        if(e.code === 'KeyB' && e.ctrlKey) {
            toggleRightArea();
        }
    }

    addCss(`
       * {
        font-family: Consolas;
        font-weight: bold;
        font-size: 14px;
       }
       .form-group, div.box.box-success > form > table {
         width: 100%;
       }
       textarea.form-control {
         width: 100% !important;
         height: 60vh;
       }
       table.table-hover, small{
         transform: rotateX(180deg);
       }
       .box-footer {
       transform: rotateX(180deg);
       }
       .box-footer ~ .box-footer{
         margin-top: 30px;
         overflow: unset !important;
         overflow-x: auto !important;
       }
       .box-footer table {
         width: 99%;
         margin: 0 auto;
       }
       .topInput {
         margin-left: 10px;
         width: 250px;
       }
       .table_sort_form > a:nth-child(1) > input {
         cursor: default;
       }
       .table_sort_form > a:nth-child(3) > input {
         cursor: default;
       }
       form > table > tbody > tr > td:nth-child(1) > div > div > div {
         width: 100% !important;
       ]
    `)
})();