// ==UserScript== // @name Jira:Extension-For-Jira.Skynet.KZ-and-Jira2.ERG.KZ // @namespace https://github.com/le91 // @version 1.6_by_01.03.2024 // @description Make GET request after page is fully loaded for a specific host - Element Creation for Jira // @author LukasEndigo // @match https://jira.skynet.kz/browse/* // @match https://jira2.erg.kz/browse/* // @match https://jira.skynet.kz/secure/RapidBoard.jspa?* // @match https://jira2.erg.kz/secure/RapidBoard.jspa?* // @icon https://www.google.com/s2/favicons?sz=64&domain=jira.com // @grant none // ==/UserScript== (async function () { `use strict`; async function MakeGetRequest(url) { try { const response = await fetch(url); return await response.json(); } catch (error) { console.error(`Ошибка выполнения GET запроса:`, error); } } async function MakePostRequest(url, data) { try { const response = await fetch(url, { method: `POST`, headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); return await response.json(); } catch (error) { console.error(`Ошибка выполнения POST запроса:`, error); } } async function CreateTokenElements() { const toolbar2_secondary = document.querySelector(`div.aui-toolbar2-secondary > div`); if (toolbar2_secondary) { const skynetTokenClass = ``; const skynetTokenButton = ``; toolbar2_secondary.insertAdjacentHTML(`afterbegin`, skynetTokenButton); toolbar2_secondary.insertAdjacentHTML(`afterbegin`, skynetTokenClass); const skynetTokenButtonClass = document.querySelector(`#skynet_token_button`); skynetTokenButtonClass.addEventListener(`click`, async function () { skynetTokenButtonClass.setAttribute(`disabled`, ``); const inputTokenValue = document.querySelector(`.skynet_token_input`).value; try { const tokenResponse = await MakeGetRequest(`https://extension-ojzdnx5uk6ayq2keje.skynet.kz/api/get_actual_token?v_token=${encodeURIComponent(inputTokenValue)}`); if (tokenResponse === `OK`) { localStorage.setItem(`skynet_key_token`, inputTokenValue); alert(`Ключ успешно проверен`); AfterClickAction(`Ключ успешно проверен`); } else if (tokenResponse === `ERROR`) { alert(`Ответ от сервера: ` + tokenResponse); } else { await ResponseCustomDialog(`Глобальная ошибка\n_Проверка Токена_\n ???`); } } catch (error) { await ResponseCustomDialog(`Глобальная ошибка\n_Проверка Токена_\nError fetching token. Check the console for details`); } skynetTokenButtonClass.removeAttribute(`disabled`); }); } } async function CreateStatusElements() { const toolbar2_secondary = document.querySelector(`div.aui-toolbar2-secondary > div`); console.log('CreateStatusElements'); if (toolbar2_secondary) { try { if (localStorage.getItem(`skynet_key_token`)) { const curPageURLOrigin = window.location.href.replace("#",""); const curPageURL = encodeURIComponent(curPageURLOrigin); const apiResponse = await MakeGetRequest(`https://extension-ojzdnx5uk6ayq2keje.skynet.kz/api/get_actual_status?v_id=`+ curPageURL + `&v_token=` + localStorage.getItem(`skynet_key_token`)); apiResponse.result.forEach((status) => { const actionButton = document.createElement(`div`); actionButton.innerHTML = status.html; const id = actionButton.firstChild.id; const role = actionButton.firstChild.role; actionButton.firstChild.href = `#`; actionButton.firstChild.addEventListener(`click`, async function () { actionButton.setAttribute(`disabled`, ``); try { let module = ``; try { const epicLinkLabel = document.querySelector(`.name[title="Epic Link"]`); if (epicLinkLabel) { const wrapDiv = epicLinkLabel.closest(`.wrap`); if (wrapDiv) { const valueText = wrapDiv.querySelector(`.value`).textContent.trim(); module = valueText } } } catch (error) {}; let submodule = ``; try { const linkingModuleLabel = document.getElementById(`linkingmodule-label`); if (linkingModuleLabel && linkingModuleLabel.textContent.trim() === `Issue Links`) { const toggleWrap = linkingModuleLabel.closest(`.toggle-wrap`); if (toggleWrap) { const linkContents = toggleWrap.querySelectorAll(`.link-content`); const concatenatedText = Array.from(linkContents, linkContent => { const linkSummaryElement = linkContent.querySelector(`.link-summary`); return linkSummaryElement ? linkSummaryElement.textContent.trim() : ``; }).join(`, `); submodule = concatenatedText.trim(); } } } catch (error) {}; let project_name = ``; try { project_name = document.querySelector(`#project-name-val`).innerText; } catch (error) {}; let desc = ``; try { desc = document.querySelector(`#summary-val`).innerText; } catch (error) {}; const postData = { id: curPageURLOrigin, project_name: project_name, desc: desc, status: status.dic_id, token: localStorage.getItem(`skynet_key_token`), module: module, submodule: submodule }; const data = await MakePostRequest(status.api, postData); var parsedData; try { parsedData = typeof data === `string` ? JSON.parse(data) : data; // console.log(parsedData); const detailValue = parsedData.detail; if (detailValue.includes(`OK Status`)) { AfterClickAction(data); } else if (detailValue.includes(`NO ACTUAL TOKEN`)) { await ResponseCustomDialog(detailValue); } else { await ResponseCustomDialog(`Глобальная ошибка\n_DB_ERROR_\n` + detailValue); // console.log(`Другое значение в detail:`, parsedData.detail); } } catch (error) { await ResponseCustomDialog(`Глобальная ошибка\n_Ошибка при парсинге JSON_\n` + error); } } catch (error) { await ResponseCustomDialog(`Глобальная ошибка\n_Error performing POST request_\n` + error); } }); toolbar2_secondary.insertBefore(actionButton.firstChild, toolbar2_secondary.firstChild); }); } else { location.reload(); }; } catch (error) { console.error(`Ошибка "fetching API" данных на запросе GET по статусам`, error); } } else { console.error(`Невозможно найти нужный элемент на странице, попробуйте выполнить команду:\n document.querySelector("div.aui-toolbar2-secondary > div");`); } } async function AfterClickAction(TextMessage) { const existingElements = document.querySelectorAll(`#skynet_token_class, #skynet_token_button`); existingElements.forEach(element => element.remove()); var skynetElements = document.querySelectorAll(`[id^="skynet"]`); skynetElements.forEach(function(element) { element.remove(); }); console.log('AfterClickAction || CLICK'); if (window.location.href.indexOf("/browse/") != -1) { console.log('AfterClickAction || browse'); if (localStorage.getItem(`skynet_key_token`)) { CreateStatusElements(); } else { CreateTokenElements(); } } if (window.location.href.indexOf("/secure/") != -1) { console.log('AfterClickAction || secure'); if (localStorage.getItem(`skynet_key_token`)) { lastHref = null; CreateStatusElements2(); } } } async function CreateStatusElements2() { var currentHref = window.location.origin + document.querySelector("#issuekey-val a, #issuekey-val h3 a").href; if (currentHref !== lastHref) { const toolbar2_secondary = document.querySelector('#ghx-detail-head > header > div.ghx-controls'); if ( toolbar2_secondary) { lastHref = currentHref; try { if (localStorage.getItem(`skynet_key_token`)) { const curPageURLOrigin = document.querySelector("#issuekey-val a, #issuekey-val h3 a").href.replace("#",""); const curPageURL = encodeURIComponent(curPageURLOrigin); const apiResponse = await MakeGetRequest(`https://extension-ojzdnx5uk6ayq2keje.skynet.kz/api/get_actual_status?v_id=`+ curPageURL + `&v_token=` + localStorage.getItem(`skynet_key_token`)); apiResponse.result.forEach((status) => { const actionButton = document.createElement(`div`); actionButton.innerHTML = status.html; const id = actionButton.firstChild.id; const role = actionButton.firstChild.role; actionButton.firstChild.href = `#`; actionButton.firstChild.addEventListener(`click`, async function () { actionButton.setAttribute(`disabled`, ``); try { let module = ``; try { const epicLinkLabel = document.querySelector(`.name[title="Epic Link"]`); if (epicLinkLabel) { const wrapDiv = epicLinkLabel.closest(`.wrap`); if (wrapDiv) { const valueText = wrapDiv.querySelector(`.value`).textContent.trim(); module = valueText } } } catch (error) {}; let submodule = `` try { const linkingModuleLabel = document.getElementById(`linkingmodule-label`); if (linkingModuleLabel && linkingModuleLabel.textContent.trim() === `Issue Links`) { const toggleWrap = linkingModuleLabel.closest(`.toggle-wrap`); if (toggleWrap) { const linkContents = toggleWrap.querySelectorAll(`.link-content`); const concatenatedText = Array.from(linkContents, linkContent => { const linkSummaryElement = linkContent.querySelector(`.link-summary`); return linkSummaryElement ? linkSummaryElement.textContent.trim() : ``; }).join(`, `); submodule = concatenatedText.trim(); } } } catch (error) {}; const postData = { id: curPageURLOrigin, project_name: document.querySelector("div.ghx-project").innerText, desc: document.querySelector("#summary-val").innerText, status: status.dic_id, token: localStorage.getItem(`skynet_key_token`), module: module, submodule: submodule }; const data = await MakePostRequest(status.api, postData); var parsedData; try { parsedData = typeof data === `string` ? JSON.parse(data) : data; // console.log(parsedData); const detailValue = parsedData.detail; if (detailValue.includes(`OK Status`)) { AfterClickAction(data); } else if (detailValue.includes(`NO ACTUAL TOKEN`)) { await ResponseCustomDialog(detailValue); } else { await ResponseCustomDialog(`Глобальная ошибка\n_DB_ERROR_\n` + detailValue); // console.log(`Другое значение в detail:`, parsedData.detail); } } catch (error) { await ResponseCustomDialog(`Глобальная ошибка\n_Ошибка при парсинге JSON_\n` + error); } } catch (error) { await ResponseCustomDialog(`Глобальная ошибка\n_Error performing POST request_\n` + error); } }); toolbar2_secondary.insertBefore(actionButton.firstChild, toolbar2_secondary.firstChild); document.querySelector("#skynet-status-12 > span.dropdown-text").remove(); }); } else { location.reload(); }; } catch (error) { console.error(`Ошибка "fetching API" данных на запросе GET по статусам`, error); } } else { console.error(`Невозможно найти нужный элемент на странице, попробуйте выполнить команду:\n document.querySelector("div.aui-toolbar2-secondary > div");`); } // Обновляем значение lastHref } } async function ResponseCustomDialog(response) { localStorage.removeItem(`skynet_key_token`); return new Promise((resolve) => { const resultDialog = document.createElement(`div`); resultDialog.innerHTML = `

Response Result

${response}
` ; document.body.appendChild(resultDialog); const closeButton = document.getElementById(`closeButton`); closeButton.addEventListener(`click`, () => { resultDialog.remove(); resolve(); location.reload(); }); }); } let lastHref = null; console.info(`Skynet Code: Injected`); if (window.location.href.indexOf(`/browse/`) != -1) { // console.info(`browse`); const handlePLSidebarChanges = () => { const contentSection = document.querySelector(`#content > section`); if (contentSection && !contentSection.classList.contains(`sidebar-placeholder`)) { console.info(`Skynet Code: Page Load`); if (localStorage.getItem(`skynet_key_token`)) { CreateStatusElements(); } else { CreateTokenElements(); } observerBrowser.disconnect(); } }; const observerBrowser = new MutationObserver(handlePLSidebarChanges); observerBrowser.observe(document.getElementById(`content`), { childList: true}); } if (window.location.href.indexOf(`/secure/`) != -1) { // console.info(`secure`); const targetElement = document.querySelector(`#gh`); const observerRapidBoard = new MutationObserver((mutationsList, observer) => { mutationsList.forEach((mutation) => { if (mutation.type === `attributes` && mutation.attributeName === `class` && mutation.target === document.querySelector(`#attachmentmodule`) ) { if (targetElement.classList.contains(`js-ghx-detail-loaded`)) { setTimeout(CreateStatusElements2(), 500) } } }); }); observerRapidBoard.observe(targetElement, { attributes: true, subtree: true }); } }) ();