383 lines
20 KiB
JavaScript
383 lines
20 KiB
JavaScript
// ==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 = `<a id="skynet_token_class" style="margin: 15px 4px 4px;"><input class="skynet_token_input" placeholder="Input Token" spellcheck="true" type="password" value="" autocomplete="one-time-code"></a>`;
|
||
const skynetTokenButton = `<a id="skynet_token_button" role="button" class="aui-button toolbar-trigger" href="#" resolved=""><span class="icon aui-icon aui-icon-small aui-iconfont-task"></span></a>`;
|
||
|
||
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 = `
|
||
<div style="position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgb(0 0 0 / 70%);z-index: 9998;"></div>
|
||
<div style="position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: white;padding: 20px;border: 2px solid #333;border-radius: 2px;box-shadow: 0 0 50px rgb(255 255 255 / 85%);z-index: 9999;">
|
||
<button id="closeButton" style="position: absolute; top: 0; right: 0; background: none; border: none; font-size: 20px; cursor: pointer;">❌</button>
|
||
<h2>Response Result</h2>
|
||
<pre>${response}</pre>
|
||
</div>`
|
||
;
|
||
|
||
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 });
|
||
}
|
||
|
||
})
|
||
(); |