diff --git a/tdx-enhanced.js b/tdx-enhanced.js index b53d0ed..736c3a3 100644 --- a/tdx-enhanced.js +++ b/tdx-enhanced.js @@ -1,7 +1,7 @@ // ==UserScript== // @name tdx-enhanced // @namespace ecn -// @version 2024-07-17-01 +// @version 2024-07-27-01 // @description enhanced tdx coloring & formatting. follows system color scheme. // @author Purdue STEM IT - it@purdue.edu // @match https://service.purdue.edu/TDNext/* @@ -132,12 +132,15 @@ function parseTicket(mutation=null) { let qBlock = document.querySelector("#ctlAttribute2285") - let header = document.getElementById("thTicket_spnTitle") + //ticket or task + let header = document.getElementById("thTicket_spnTitle") || document.querySelector("#upTaskHeader>h1") //change tab title if (header) { - let ticketTitle = header.innerText + let ticketTitle = header.childNodes[0].textContent document.title = ticketTitle + } else { + return } //add queue tag to ticket title @@ -163,6 +166,21 @@ header.appendChild(newBox) } + //handle button links - update for now + let buttons = document.querySelectorAll("#btnUpdateTicket, #liAddTicketTask") + console.log("Buttons:",buttons) + for (const button of buttons) { + /* + let id = button.id + switch(id) { + case "btnUpdateTicket": + handleLink("update",button) + } + */ + handleLink("update",button) + } + + //color the feed if darkmode var feedItems if (mutation) { @@ -390,7 +408,7 @@ } } - //find links & open in new tab + //find links & open in new tab, if configured //let linkTypes = ['Title','TicketID','CustomerName','ResponsibleFullName','LastModifiedByFullName'] //open people in new tabs let linkTypes = ['Title','TicketID','TicketTitle'] for (const linkType of linkTypes) { @@ -398,11 +416,54 @@ let link = item[linkType].cell.querySelector("a") if (link) { //override function that opens in windows + handleLink("report",link) + } + } + } + } + + function handleLink(source,link) { + let behavior = settings('get','linkBehavior') + if (behavior=="tabs") { + + switch(source) { + case 'report': { link.onclick = null - //open in new tab link.target = "_blank" + break } } + + } else { + link.onclick = (event)=>{ + event.preventDefault() + var params + var href + let w = (window.screen.width / 2.1) + let h = (window.screen.height / 1.25) + let l = 20 + let t = 50 + + switch(source) { + case 'report': { + href = link.href + break + } + + case 'update': { + l = (window.screen.width / 2) + l + + //restructure url for updating + let location = window.location.pathname + let baseHref = location.substr(0, location.lastIndexOf('/')) + href = `${baseHref}/Update${window.location.search}` + break + } + } + + params = `width=${w}px,height=${h}px,left=${l}px,top=${t}px` + return window.open(href,'_blank',params) + } } } @@ -417,7 +478,7 @@ if (!frame.querySelector("#customStyles")) { let head = frame.querySelector("head") let html = frame.querySelector("html") - html.classList.add(getColorMode()) + //html.classList.add(getColorMode()) //FIX THIS! let s = document.createElement("style") s.id = "customStyles" s.innerText = customStyles @@ -464,17 +525,55 @@ function changeTitle() { let title = document.querySelector(".organization-link a") if (title) { - title.innerText = "Purdue University - STEM IT" + title.innerText = "Purdue University - STEM" } - injectModeToggle() + injectSettings() + } + + function colorChange(color) { + localStorage.setItem("colors",color) + setColors(color) } + function setColors(color,value) { + console.log("Setting",color,"to",value) + //let col = tinycolor(value).toRgbString() + let col = value + let style = document.documentElement.style + + switch(color) { + case 'primaryColor': + style.setProperty('--dark-col-primary', col); + style.setProperty('--light-col-primary', col); + break + + case 'backgroundColor': + style.setProperty('--dark-bg-primary', col); + style.setProperty('--light-bg-primary', col); + break + + case 'theme': { + + for (const col of ["dark","light"]) { + let accent = `var(--${col}-${value}-accent)` + let bg = `var(--${col}-${value}-bg)` + style.setProperty(`--${col}-col-primary`, accent) + style.setProperty(`--${col}-bg-primary`, `var(--${col}-bg-default)`) + } + break + } + } + } + + /* function toggleColorMode() { let mode = getColorMode() == "darkMode" ? "lightMode" : "darkMode" setColorMode(mode) } + */ + function setColorMode(mode,store=true) { if (!mode) { mode = "auto" @@ -502,6 +601,7 @@ } + /* function getColorMode() { let localScheme = localStorage.getItem("styles") let autoScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? "darkMode" : "lightMode" @@ -522,6 +622,17 @@ let localScheme = localStorage.getItem("styles") let autoScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? "darkMode" : "lightMode" + let colors = localStorage.getItem("colors") + if (colors) { + console.log("Setting color from init") + setColors(colors) + } + + let primaryColor = document.querySelector("#primaryColor") + if (primaryColor) { + primaryColor.value = colors + } + if (localScheme != autoScheme && localScheme != "auto") { setColorMode(localScheme) } else { @@ -529,34 +640,190 @@ } addEventListener("storage", (event) => { - console.log("Storage event:",event) + //console.log("Storage event:",event) if (event.key == "styles") { setColorMode(event.newValue,false) + } else if (event.key == "colors") { + setColors(event.newValue) } }); } + */ + - function injectModeToggle() { + function injectSettings() { let iconBar = document.querySelector(".tdbar-settings .pull-right") + let toolsHTML = ` +
+ +
+ ` + let buttonHTML = ` - - - + ` - let button = document.createElement("span") - button.innerHTML = buttonHTML + let settingsHTML = ` + + + ` + + let settingsButton = document.createElement("span") + settingsButton.innerHTML = buttonHTML + + let settingsPage = document.createElement("div") + settingsPage.innerHTML = settingsHTML + + let toolsLink = document.createElement("span") + toolsLink.innerHTML = toolsHTML if (iconBar) { - iconBar.prepend(button) - button.querySelector("#colorMode").onclick = toggleColorMode + iconBar.prepend(settingsButton) + + //settings + //settingsPage.querySelector("#colorMode").onclick = toggleColorMode + settingsButton.querySelector("#settingsButton").addEventListener("click",()=>{ + settings("toggle",settingsPage) + }) + iconBar.appendChild(settingsPage) + + //form changes + let form = settingsPage.querySelector("form") + form.addEventListener("change", (event)=>{ + settings("update",form) + }); + + //tools link + let parent = iconBar.parentElement + parent.prepend(toolsLink) + } + } + + /* SETTINGS */ + + function settings(action,value=null) { + var data + var menu + try { + data = JSON.parse(localStorage.getItem("userSettings")) + if (!data) { + throw "Data is null" + } + } catch(e) { + console.error("Couldn't grab settings!",e) + //set defaults + data = { + linkBehavior: "tabs" + } + } + + switch(action) { + case 'apply': { + for (const setting in data) { + let form = document.forms.settingsForm + let value = data[setting] + console.log("Apply setting:",setting,value) + if (form) { + let elements = form.elements + form[setting].value = value + } + } + + if ('colorMode' in data) { + setColorMode(data.colorMode) + } + + if ('theme' in data) { + if (data.theme=="custom") { + setColors('primaryColor',data.primaryColor) + setColors('backgroundColor',data.backgroundColor) + } else { + setColors('theme',data.theme) + } + } + break + } + + case 'get': { + if (value) { + return value in data ? data[value] : null + } else { + return data + } + break + } + + case 'toggle': { + let menu = document.querySelector("#settingsMenu") + let newState = menu.classList.contains("show") ? "hide" : "show" + let oldState = newState=="show" ? "hide" : "show" + menu.classList.add(newState) + menu.classList.remove(oldState) + break + } + + case 'update': { + let form = value + let formData = new FormData(form) + data = Object.fromEntries([...formData]) + console.log("Settings update!",data) + localStorage.setItem("userSettings",JSON.stringify(data)) + settings("apply") + } } } + /* TDX TOOLS */ function checkPath() { let path = document.location.pathname if (path=="/TDWebApi/api/auth/loginsso") { @@ -571,30 +838,61 @@ } changeTitle() - checkColorMode() + //checkColorMode() + settings("apply") parseTicket() checkPath() + addEventListener("storage", (event) => { + //console.log("Storage event:",event) + if (event.key == "userSettings") { + settings("apply") + } + }); + const customStyles = ` /* Root Styles */ :root { - --dark-bg-0: #111; - --dark-bg-1: #222; - --dark-bg-2: #333; - --dark-bg-3: #444; - --dark-bg-4: #555; - --dark-col-0: #ab9266; - --dark-col-1: #CFB991; - --dark-col-2: #8d7c5d; + + --dark-bg-default: #000; + --light-bg-default: #fff; + + --dark-col-default: #ab9266; + --light-col-default: #cbb080; + + --dark-col-primary: var(--dark-col-default); + --light-col-primary: var(--light-col-default); + + --dark-bg-primary: var(--dark-bg-default); + --light-bg-primary: var(--light-bg-default); + + --dark-gold-accent: #ab9266; + --light-gold-accent: #b79a66; + + /* Original TDX blue */ + --dark-blue-accent: #4c778d; + --light-blue-accent: #005d8b; + + --dark-green-accent: #559170; + --light-green-accent: var(--dark-green-accent); + + --dark-bg-0: color-mix(in srgb,var(--dark-bg-primary),#fff 5%); + --dark-bg-1: color-mix(in srgb,var(--dark-bg-primary),#fff 12%); + --dark-bg-2: color-mix(in srgb,var(--dark-bg-primary),#fff 20%); + --dark-bg-3: color-mix(in srgb,var(--dark-bg-primary),#fff 25%); + --dark-bg-4: color-mix(in srgb,var(--dark-bg-primary),#fff 30%); + --dark-col-0: var(--dark-col-primary); + --dark-col-1: color-mix(in srgb,var(--dark-col-primary),#fff 25%); + --dark-col-2: color-mix(in srgb,var(--dark-col-primary),#fff 45%); --dark-col-link: #d1dbff; --dark-txt-0: #bbb; --dark-txt-1: #fff; --dark-txt-2: #ececec; --dark-txt-3: #929292; --dark-txt-4: #ffffff8c; - --dark-border-0: #2b2b2b; + --dark-border-0: color-mix(in srgb,var(--dark-bg-primary),#fff 18%); --dark-col-reply: #1e3438; --dark-col-highlight-1: #625714; --dark-col-highlight-2: #311462; @@ -607,15 +905,15 @@ --light-txt-2: #222; --light-txt-3: #333; --light-txt-4: #0000008c; - --light-col-0: #ccb387; - --light-col-1: #836836; - --light-col-2: #ba7600; - --light-bg-0: #fff; - --light-bg-1: #f5f5f5; - --light-bg-2: #fff; - --light-bg-3: #eee; - --light-bg-4: #ddd; - --light-border-0: #dfdfdf; + --light-col-0: var(--light-col-primary); + --light-col-1: color-mix(in srgb,var(--light-col-primary),#000 15%); + --light-col-2: color-mix(in srgb,var(--light-col-primary),#000 45%); + --light-bg-0: color-mix(in srgb,var(--light-bg-primary),#000 0%); + --light-bg-1: color-mix(in srgb,var(--light-bg-primary),#000 5%); + --light-bg-2: color-mix(in srgb,var(--light-bg-primary),#000 2%); + --light-bg-3: color-mix(in srgb,var(--light-bg-primary),#000 20%); + --light-bg-4: color-mix(in srgb,var(--light-bg-primary),#000 25%); + --light-border-0: color-mix(in srgb,var(--light-bg-primary),#000 18%); --light-col-reply: #d3f2ff; --light-col-highlight-1: #fff3c4; --light-col-highlight-2: #e3c4ff; @@ -735,6 +1033,31 @@ /* Global */ +#settingsMenu { + left: 250px; + padding: 10px; + width: 250px; + background: var(--bg-1); +} + +#settingsMenu.hide { + visibility: hidden; +} + +#settingsMenu h5 { + margin-bottom: 2px; +} + +#settingsMenu h3 { + font-weight: 500; + font-size: 18px; +} + +#settingsForm .flex { + display: flex; + gap: 24px; +} + .qBox { margin-left: 10px; padding: 5px;