bunkerweb is now W3C friendly

This commit is contained in:
BlasenhauerJ 2023-04-25 18:49:57 +02:00
parent 8ea94a2e4d
commit 6916a81c5d
31 changed files with 681 additions and 684 deletions

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ import {
class Download {
constructor(prefix = "cache") {
this.prefix = prefix;
this.listContainer = document.querySelector(`[cache-container]`);
this.listContainer = document.querySelector(`[data-cache-container]`);
this.init();
}
@ -16,11 +16,11 @@ class Download {
this.listContainer.addEventListener("click", (e) => {
try {
if (
e.target.closest("button").hasAttribute(`${this.prefix}-download`)
e.target.closest("button").hasAttribute(`data-${this.prefix}-download`)
) {
const btnEl = e.target.closest("button");
const jobName = btnEl.getAttribute("cache-download");
const fileName = btnEl.getAttribute("cache-file");
const jobName = btnEl.getAttribute("data-cache-download");
const fileName = btnEl.getAttribute("data-cache-file");
this.sendFileToDL(jobName, fileName);
}
} catch (err) {}

View File

@ -2,9 +2,9 @@ import { Checkbox } from "./utils/form.js";
class Menu {
constructor() {
this.sidebarEl = document.querySelector("[sidebar-menu]");
this.toggleBtn = document.querySelector("[sidebar-menu-toggle]");
this.closeBtn = document.querySelector("[sidebar-menu-close]");
this.sidebarEl = document.querySelector("[data-sidebar-menu]");
this.toggleBtn = document.querySelector("[data-sidebar-menu-toggle]");
this.closeBtn = document.querySelector("[data-sidebar-menu-close]");
this.toggleBtn.addEventListener("click", this.toggle.bind(this));
this.closeBtn.addEventListener("click", this.close.bind(this));
@ -15,7 +15,7 @@ class Menu {
window.addEventListener("click", (e) => {
try {
if (
e.target.closest("aside").hasAttribute("sidebar-menu") &&
e.target.closest("aside").hasAttribute("data-sidebar-menu") &&
e.target.closest("button").getAttribute("role") === "tab"
) {
this.close();
@ -53,7 +53,7 @@ class News {
}
render(lastNews) {
const newsContainer = document.querySelector("[news-container]");
const newsContainer = document.querySelector("[data-news-container]");
//remove default message
newsContainer.textContent = "";
//render last news
@ -76,7 +76,7 @@ class News {
);
//add to DOM
document
.querySelector("[news-container]")
.querySelector("[data-news-container]")
.insertAdjacentHTML("afterbegin", cardHTML);
});
}
@ -157,8 +157,8 @@ class Sidebar {
class darkMode {
constructor() {
this.htmlEl = document.querySelector("html");
this.darkToggleEl = document.querySelector("[dark-toggle]");
this.darkToggleLabel = document.querySelector("[dark-toggle-label]");
this.darkToggleEl = document.querySelector("[data-dark-toggle]");
this.darkToggleLabel = document.querySelector("[data-dark-toggle-label]");
this.csrf = document.querySelector("input#csrf_token");
this.init();
}
@ -197,8 +197,8 @@ class darkMode {
class FlashMsg {
constructor() {
this.openBtn = document.querySelector("[flash-sidebar-open]");
this.flashCount = document.querySelector("[flash-count]");
this.openBtn = document.querySelector("[data-flash-sidebar-open]");
this.flashCount = document.querySelector("[data-flash-count]");
this.isMsgCheck = false;
this.init();
}
@ -211,7 +211,7 @@ class FlashMsg {
//stop animate if clicked once
this.openBtn.addEventListener("click", (e) => {
try {
if (e.target.closest("button").hasAttribute("flash-sidebar-open")) {
if (e.target.closest("button").hasAttribute("data-flash-sidebar-open")) {
this.isMsgCheck = true;
}
} catch (err) {}
@ -219,14 +219,14 @@ class FlashMsg {
//remove flash message and change count
window.addEventListener("click", (e) => {
try {
if (e.target.closest("button").hasAttribute("close-flash-message")) {
if (e.target.closest("button").hasAttribute("data-close-flash-message")) {
//remove logic
const closeBtn = e.target.closest("button");
const flashEl = closeBtn.closest("[flash-message]");
const flashEl = closeBtn.closest("[data-flash-message]");
flashEl.remove();
//update count
this.flashCount.textContent =
document.querySelectorAll("[flash-message]").length;
document.querySelectorAll("[data-flash-message]").length;
}
} catch (err) {}
});
@ -254,9 +254,9 @@ class FlashMsg {
class Loader {
constructor() {
this.menuContainer = document.querySelector("[menu-container]");
this.logoContainer = document.querySelector("[loader]");
this.logoEl = document.querySelector("[loader-img]");
this.menuContainer = document.querySelector("[data-menu-container]");
this.logoContainer = document.querySelector("[data-loader]");
this.logoEl = document.querySelector("[data-loader-img]");
this.isLoading = true;
this.init();
}
@ -292,14 +292,14 @@ class Loader {
const setLoader = new Loader();
const setMenu = new Menu();
const setNewsSidebar = new Sidebar(
"[sidebar-info]",
"[sidebar-info-open]",
"[sidebar-info-close]"
"[data-sidebar-info]",
"[data-sidebar-info-open]",
"[data-sidebar-info-close]"
);
const setFlashSidebar = new Sidebar(
"[flash-sidebar]",
"[flash-sidebar-open]",
"[flash-sidebar-close]"
"[data-flash-sidebar]",
"[data-flash-sidebar-open]",
"[data-flash-sidebar-close]"
);
const setNews = new News();
const setDarkM = new darkMode();

View File

@ -15,12 +15,12 @@ class Multiple {
init() {
//hide multiple btn if no multiple exist on a plugin
const multiples = document.querySelectorAll(
`[${this.prefix}-settings-multiple]`
`[data-${this.prefix}-settings-multiple]`
);
multiples.forEach((container) => {
if (container.querySelectorAll(`[setting-container]`).length <= 0)
if (container.querySelectorAll(`[data-setting-container]`).length <= 0)
container.parentElement
.querySelector("[multiple-handler]")
.querySelector("[data-multiple-handler]")
.classList.add("hidden");
});
}
@ -36,5 +36,5 @@ const format = new FormatValue();
const setMultiple = new Multiple("global-config");
const setFilterGlobal = new FilterSettings(
"settings-filter",
"[service-content='settings']"
"[data-service-content='settings']"
);

View File

@ -13,12 +13,12 @@ class Dropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-setting-select`) &&
.hasAttribute(`data-${this.prefix}-setting-select`) &&
!e.target.closest("button").hasAttribute(`disabled`)
) {
const btnName = e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select`);
.getAttribute(`data-${this.prefix}-setting-select`);
if (this.lastDrop !== btnName) {
this.lastDrop = btnName;
this.closeAllDrop();
@ -32,12 +32,12 @@ class Dropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-setting-select-dropdown-btn`)
.hasAttribute(`data-${this.prefix}-setting-select-dropdown-btn`)
) {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`${this.prefix}-setting-select-dropdown-btn`
`data-${this.prefix}-setting-select-dropdown-btn`
);
//stop if same value to avoid new fetching
const isSameVal = this.isSameValue(btnSetting, btnValue);
@ -49,7 +49,7 @@ class Dropdown {
this.changeDropBtnStyle(btnSetting, btn);
//show / hide filter
if (btnSetting === "instances") {
this.hideFilterOnLocal(btn.getAttribute("_type"));
this.hideFilterOnLocal(btn.getAttribute("data-_type"));
}
}
} catch (err) {}
@ -58,15 +58,15 @@ class Dropdown {
closeAllDrop() {
const drops = document.querySelectorAll(
`[${this.prefix}-setting-select-dropdown]`
`[data-${this.prefix}-setting-select-dropdown]`
);
drops.forEach((drop) => {
drop.classList.add("hidden");
drop.classList.remove("flex");
document
.querySelector(
`svg[${this.prefix}-setting-select="${drop.getAttribute(
`${this.prefix}-setting-select-dropdown`
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
`data-${this.prefix}-setting-select-dropdown`
)}"]`
)
.classList.remove("rotate-180");
@ -75,7 +75,7 @@ class Dropdown {
isSameValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[${this.prefix}-setting-select-text="${btnSetting}"]`
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
);
const currVal = selectCustom.textContent;
return currVal === value ? true : false;
@ -83,30 +83,30 @@ class Dropdown {
setSelectNewValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[${this.prefix}-setting-select="${btnSetting}"]`
`[data-${this.prefix}-setting-select="${btnSetting}"]`
);
selectCustom.querySelector(
`[${this.prefix}-setting-select-text]`
`[data-${this.prefix}-setting-select-text]`
).textContent = value;
}
hideDropdown(btnSetting) {
//hide dropdown
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
//svg effect
const dropdownChevron = document.querySelector(
`svg[${this.prefix}-setting-select="${btnSetting}"]`
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`
);
dropdownChevron.classList.remove("rotate-180");
}
changeDropBtnStyle(btnSetting, selectedBtn) {
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
);
//reset dropdown btns
const btnEls = dropdownEl.querySelectorAll("button");
@ -133,13 +133,13 @@ class Dropdown {
toggleSelectBtn(e) {
const attribut = e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select`);
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${attribut}"]`
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
);
const dropdownChevron = document.querySelector(
`svg[${this.prefix}-setting-select="${attribut}"]`
`svg[data-${this.prefix}-setting-select="${attribut}"]`
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
@ -173,7 +173,7 @@ class Dropdown {
class Filter {
constructor(prefix = "jobs") {
this.prefix = prefix;
this.container = document.querySelector(`[${this.prefix}-filter]`);
this.container = document.querySelector(`[data-${this.prefix}-filter]`);
this.keyInp = document.querySelector("input#keyword");
this.successValue = "all";
this.reloadValue = "all";
@ -189,12 +189,12 @@ class Filter {
if (
e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select-dropdown-btn`) ===
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
"success"
) {
setTimeout(() => {
const value = document
.querySelector(`[${this.prefix}-setting-select-text="success"]`)
.querySelector(`[data-${this.prefix}-setting-select-text="success"]`)
.textContent.trim();
this.successValue = value;
@ -210,12 +210,12 @@ class Filter {
if (
e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select-dropdown-btn`) ===
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
"reload"
) {
setTimeout(() => {
const value = document
.querySelector(`[${this.prefix}-setting-select-text="reload"]`)
.querySelector(`[data-${this.prefix}-setting-select-text="reload"]`)
.textContent.trim();
this.reloadValue = value;
@ -232,7 +232,7 @@ class Filter {
}
filter() {
const jobs = document.querySelector(`[${this.prefix}-list]`).children;
const jobs = document.querySelector(`[data-${this.prefix}-list]`).children;
if (jobs.length === 0) return;
//reset
for (let i = 0; i < jobs.length; i++) {
@ -250,8 +250,8 @@ class Filter {
for (let i = 0; i < jobs.length; i++) {
const el = jobs[i];
const type = el
.querySelector(`[${this.prefix}-success]`)
.getAttribute(`${this.prefix}-success`)
.querySelector(`[data-${this.prefix}-success]`)
.getAttribute(`data-${this.prefix}-success`)
.trim();
if (type !== this.successValue) el.classList.add("hidden");
}
@ -262,8 +262,8 @@ class Filter {
for (let i = 0; i < jobs.length; i++) {
const el = jobs[i];
const type = el
.querySelector(`[${this.prefix}-reload]`)
.getAttribute(`${this.prefix}-reload`)
.querySelector(`[data-${this.prefix}-reload]`)
.getAttribute(`data-${this.prefix}-reload`)
.trim();
if (type !== this.reloadValue) el.classList.add("hidden");
}
@ -275,15 +275,15 @@ class Filter {
for (let i = 0; i < jobs.length; i++) {
const el = jobs[i];
const name = el
.querySelector(`[${this.prefix}-name`)
.querySelector(`[data-${this.prefix}-name]`)
.textContent.trim()
.toLowerCase();
const date = el
.querySelector(`[${this.prefix}-last_run`)
.querySelector(`[data-${this.prefix}-last_run]`)
.textContent.trim()
.toLowerCase();
const every = el
.querySelector(`[${this.prefix}-every`)
.querySelector(`[data-${this.prefix}-every]`)
.textContent.trim()
.toLowerCase();
@ -300,7 +300,7 @@ class Filter {
class Download {
constructor(prefix = "jobs") {
this.prefix = prefix;
this.listContainer = document.querySelector(`[${this.prefix}-list]`);
this.listContainer = document.querySelector(`[data-${this.prefix}-list]`);
this.init();
}
@ -308,11 +308,11 @@ class Download {
this.listContainer.addEventListener("click", (e) => {
try {
if (
e.target.closest("button").hasAttribute(`${this.prefix}-download`)
e.target.closest("button").hasAttribute(`data-${this.prefix}-download`)
) {
const btnEl = e.target.closest("button");
const jobName = btnEl.getAttribute("jobs-download");
const fileName = btnEl.getAttribute("jobs-file");
const jobName = btnEl.getAttribute("data-jobs-download");
const fileName = btnEl.getAttribute("data-jobs-file");
this.sendFileToDL(jobName, fileName);
}
} catch (err) {}

View File

@ -14,12 +14,12 @@ class Dropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-setting-select`) &&
.hasAttribute(`data-${this.prefix}-setting-select`) &&
!e.target.closest("button").hasAttribute(`disabled`)
) {
const btnName = e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select`);
.getAttribute(`data-${this.prefix}-setting-select`);
if (this.lastDrop !== btnName) {
this.lastDrop = btnName;
this.closeAllDrop();
@ -32,12 +32,12 @@ class Dropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-setting-select-dropdown-btn`)
.hasAttribute(`data-${this.prefix}-setting-select-dropdown-btn`)
) {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`${this.prefix}-setting-select-dropdown-btn`
`data-${this.prefix}-setting-select-dropdown-btn`
);
//stop if same value to avoid new fetching
const isSameVal = this.isSameValue(btnSetting, btnValue);
@ -49,7 +49,7 @@ class Dropdown {
this.changeDropBtnStyle(btnSetting, btn);
//show / hide filter
if (btnSetting === "instances") {
this.hideFilterOnLocal(btn.getAttribute("_type"));
this.hideFilterOnLocal(btn.getAttribute("data-_type"));
}
}
} catch (err) {}
@ -58,15 +58,15 @@ class Dropdown {
closeAllDrop() {
const drops = document.querySelectorAll(
`[${this.prefix}-setting-select-dropdown]`
`[data-${this.prefix}-setting-select-dropdown]`
);
drops.forEach((drop) => {
drop.classList.add("hidden");
drop.classList.remove("flex");
document
.querySelector(
`svg[${this.prefix}-setting-select="${drop.getAttribute(
`${this.prefix}-setting-select-dropdown`
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
`data-${this.prefix}-setting-select-dropdown`
)}"]`
)
.classList.remove("rotate-180");
@ -75,7 +75,7 @@ class Dropdown {
isSameValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[${this.prefix}-setting-select-text="${btnSetting}"]`
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
);
const currVal = selectCustom.textContent;
return currVal === value ? true : false;
@ -83,30 +83,30 @@ class Dropdown {
setSelectNewValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[${this.prefix}-setting-select="${btnSetting}"]`
`[data-${this.prefix}-setting-select="${btnSetting}"]`
);
selectCustom.querySelector(
`[${this.prefix}-setting-select-text]`
`[data-${this.prefix}-setting-select-text]`
).textContent = value;
}
hideDropdown(btnSetting) {
//hide dropdown
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
//svg effect
const dropdownChevron = document.querySelector(
`svg[${this.prefix}-setting-select="${btnSetting}"]`
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`
);
dropdownChevron.classList.remove("rotate-180");
}
changeDropBtnStyle(btnSetting, selectedBtn) {
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
);
//reset dropdown btns
const btnEls = dropdownEl.querySelectorAll("button");
@ -133,13 +133,13 @@ class Dropdown {
toggleSelectBtn(e) {
const attribut = e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select`);
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${attribut}"]`
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
);
const dropdownChevron = document.querySelector(
`svg[${this.prefix}-setting-select="${attribut}"]`
`svg[data-${this.prefix}-setting-select="${attribut}"]`
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
@ -174,7 +174,7 @@ class FetchLogs {
constructor(prefix = "logs") {
this.prefix = prefix;
this.instance = document.querySelector(
`[${this.prefix}-setting-select-text="instances"]`
`[data-${this.prefix}-setting-select-text="instances"]`
);
this.instanceName = "";
this.updateInp = document.querySelector("input#update-date");
@ -187,8 +187,8 @@ class FetchLogs {
this.isLiveUpdate = false;
this.updateDelay = 2000;
this.lastUpdate = Date.now() - 86400000;
this.container = document.querySelector(`[${this.prefix}-settings]`);
this.logListContainer = document.querySelector(`[${this.prefix}-list]`);
this.container = document.querySelector(`[data-${this.prefix}-settings]`);
this.logListContainer = document.querySelector(`[data-${this.prefix}-list]`);
this.submitSettings = document.querySelector("button#submit-settings");
this.init();
}
@ -268,10 +268,10 @@ class FetchLogs {
goBottomList() {
document
.querySelector(`[${this.prefix}-list]`)
.querySelector(`[data-${this.prefix}-list]`)
.scrollTo(
0,
document.querySelector(`[${this.prefix}-list]`).scrollHeight
document.querySelector(`[data-${this.prefix}-list]`).scrollHeight
);
}
@ -318,14 +318,14 @@ class FetchLogs {
typeEl.className =
"dark:text-gray-400 dark:opacity-80 text-sm col-span-3 m-0";
typeEl.textContent = log.type;
typeEl.setAttribute("logs-type", "");
typeEl.setAttribute("data-logs-type", "");
logContainer.appendChild(typeEl);
//content
const contentEl = document.createElement("p");
contentEl.className =
"dark:text-gray-400 dark:opacity-80 text-sm col-span-9 m-0";
contentEl.textContent = log.content;
contentEl.setAttribute("logs-content", "");
contentEl.setAttribute("data-logs-content", "");
logContainer.appendChild(contentEl);
//show on DOM
this.logListContainer.appendChild(logContainer);
@ -343,7 +343,7 @@ class FetchLogs {
class Filter {
constructor(prefix = "logs") {
this.prefix = prefix;
this.container = document.querySelector(`[${this.prefix}-filter]`);
this.container = document.querySelector(`[data-${this.prefix}-filter]`);
this.keyInp = document.querySelector("input#keyword");
this.lastType = "all";
this.initHandler();
@ -356,13 +356,13 @@ class Filter {
if (
e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select-dropdown-btn`) ===
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
"types"
) {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`${this.prefix}-setting-select-dropdown-btn`
`data-${this.prefix}-setting-select-dropdown-btn`
);
this.lastType = btnValue;
@ -378,7 +378,7 @@ class Filter {
}
filter() {
const logs = document.querySelector(`[${this.prefix}-list]`).children;
const logs = document.querySelector(`[data-${this.prefix}-list]`).children;
if (logs.length === 0) return;
//reset
for (let i = 0; i < logs.length; i++) {
@ -395,7 +395,7 @@ class Filter {
for (let i = 0; i < logs.length; i++) {
const el = logs[i];
const typeEl = el.querySelector("[logs-type]");
const typeEl = el.querySelector("[data-logs-type]");
if (this.lastType !== "misc" && typeEl.textContent !== this.lastType)
el.classList.add("hidden");
if (
@ -413,7 +413,7 @@ class Filter {
for (let i = 0; i < logs.length; i++) {
const el = logs[i];
const content = el
.querySelector("[logs-content]")
.querySelector("[data-logs-content]")
.textContent.trim()
.toLowerCase();
if (!content.includes(keyword)) el.classList.add("hidden");

View File

@ -12,12 +12,12 @@ class Dropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-setting-select`) &&
.hasAttribute(`data-${this.prefix}-setting-select`) &&
!e.target.closest("button").hasAttribute(`disabled`)
) {
const btnName = e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select`);
.getAttribute(`data-${this.prefix}-setting-select`);
if (this.lastDrop !== btnName) {
this.lastDrop = btnName;
this.closeAllDrop();
@ -31,12 +31,12 @@ class Dropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-setting-select-dropdown-btn`)
.hasAttribute(`data-${this.prefix}-setting-select-dropdown-btn`)
) {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`${this.prefix}-setting-select-dropdown-btn`
`data-${this.prefix}-setting-select-dropdown-btn`
);
//stop if same value to avoid new fetching
const isSameVal = this.isSameValue(btnSetting, btnValue);
@ -48,7 +48,7 @@ class Dropdown {
this.changeDropBtnStyle(btnSetting, btn);
//show / hide filter
if (btnSetting === "instances") {
this.hideFilterOnLocal(btn.getAttribute("_type"));
this.hideFilterOnLocal(btn.getAttribute("data-_type"));
}
}
} catch (err) {}
@ -57,15 +57,15 @@ class Dropdown {
closeAllDrop() {
const drops = document.querySelectorAll(
`[${this.prefix}-setting-select-dropdown]`
`[data-${this.prefix}-setting-select-dropdown]`
);
drops.forEach((drop) => {
drop.classList.add("hidden");
drop.classList.remove("flex");
document
.querySelector(
`svg[${this.prefix}-setting-select="${drop.getAttribute(
`${this.prefix}-setting-select-dropdown`
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
`data-${this.prefix}-setting-select-dropdown`
)}"]`
)
.classList.remove("rotate-180");
@ -74,7 +74,7 @@ class Dropdown {
isSameValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[${this.prefix}-setting-select-text="${btnSetting}"]`
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
);
const currVal = selectCustom.textContent;
return currVal === value ? true : false;
@ -82,30 +82,30 @@ class Dropdown {
setSelectNewValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[${this.prefix}-setting-select="${btnSetting}"]`
`[data-${this.prefix}-setting-select="${btnSetting}"]`
);
selectCustom.querySelector(
`[${this.prefix}-setting-select-text]`
`[data-${this.prefix}-setting-select-text]`
).textContent = value;
}
hideDropdown(btnSetting) {
//hide dropdown
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
//svg effect
const dropdownChevron = document.querySelector(
`svg[${this.prefix}-setting-select="${btnSetting}"]`
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`
);
dropdownChevron.classList.remove("rotate-180");
}
changeDropBtnStyle(btnSetting, selectedBtn) {
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
);
//reset dropdown btns
const btnEls = dropdownEl.querySelectorAll("button");
@ -132,13 +132,13 @@ class Dropdown {
toggleSelectBtn(e) {
const attribut = e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select`);
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[${this.prefix}-setting-select-dropdown="${attribut}"]`
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
);
const dropdownChevron = document.querySelector(
`svg[${this.prefix}-setting-select="${attribut}"]`
`svg[data-${this.prefix}-setting-select="${attribut}"]`
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
@ -172,7 +172,7 @@ class Dropdown {
class Filter {
constructor(prefix = "plugins") {
this.prefix = prefix;
this.container = document.querySelector(`[${this.prefix}-filter]`);
this.container = document.querySelector(`[data-${this.prefix}-filter]`);
this.keyInp = document.querySelector("input#keyword");
this.lastType = "all";
this.initHandler();
@ -185,7 +185,7 @@ class Filter {
if (
e.target
.closest("button")
.getAttribute(`${this.prefix}-setting-select-dropdown-btn`) ===
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
"types"
) {
const btn = e.target.closest("button");
@ -204,7 +204,7 @@ class Filter {
}
filter() {
const logs = document.querySelector(`[${this.prefix}-list]`).children;
const logs = document.querySelector(`[data-${this.prefix}-list]`).children;
if (logs.length === 0) return;
//reset
for (let i = 0; i < logs.length; i++) {
@ -220,7 +220,7 @@ class Filter {
if (this.lastType === "all") return;
for (let i = 0; i < logs.length; i++) {
const el = logs[i];
const type = el.getAttribute(`${this.prefix}-external`).trim();
const type = el.getAttribute(`data-${this.prefix}-external`).trim();
if (type !== this.lastType) el.classList.add("hidden");
}
}
@ -231,7 +231,7 @@ class Filter {
for (let i = 0; i < logs.length; i++) {
const el = logs[i];
const content = el
.querySelector(`[${this.prefix}-content]`)
.querySelector(`[data-${this.prefix}-content]`)
.textContent.trim()
.toLowerCase();
@ -242,7 +242,7 @@ class Filter {
class Upload {
constructor() {
this.container = document.querySelector("[plugins-upload]");
this.container = document.querySelector("[data-plugins-upload]");
this.form = document.querySelector("#dropzone-form");
this.dropZoneElement = document.querySelector(".drop-zone");
this.fileInput = document.querySelector(".file-input");
@ -286,8 +286,8 @@ class Upload {
//close fail/success log
this.container.addEventListener("click", (e) => {
try {
if (e.target.closest("button").hasAttribute("upload-message-delete")) {
const message = e.target.closest("div[upload-message]");
if (e.target.closest("button").hasAttribute("data-upload-message-delete")) {
const message = e.target.closest("div[data-upload-message]");
message.remove();
}
} catch (err) {}
@ -362,18 +362,21 @@ class Upload {
}
allowReload() {
const reloadBtn = document.querySelector("[plugin-reload-btn]");
const reloadBtn = document.querySelector("[data-plugin-reload-btn]");
reloadBtn.removeAttribute("disabled");
}
fileLoad(name, fileSize) {
const str = `<div u class="mt-2 rounded p-2 w-full bg-gray-100 dark:bg-gray-800">
const str = `<div class="mt-2 rounded p-2 w-full bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-between">
<svg class="fill-sky-500 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM385 215c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71V392c0 13.3-10.7 24-24 24s-24-10.7-24-24V177.9l-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 103c9.4-9.4 24.6-9.4 33.9 0L385 215z"/></svg>
<svg class="fill-sky-500 stroke-sky-500 h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
<span class="text-sm text-slate-700 dark:text-gray-300 mr-4">${name} </span>
<span class="text-sm text-slate-700 dark:text-gray-300">${fileSize}</span>
<svg class=" fill-gray-600 dark:fill-gray-300 dark:opacity-80 h-3 w-3 " xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
<svg class=" fill-gray-600 dark:fill-gray-300 dark:opacity-80 h-3 w-3 " viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"/>
</svg>
</div>
</div>
@ -382,7 +385,7 @@ class Upload {
}
fileSuccess(name, fileSize) {
const str = `<div upload-message class="mt-2 rounded p-2 w-full bg-gray-100 dark:bg-gray-800">
const str = `<div data-upload-message class="mt-2 rounded p-2 w-full bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-between">
<svg
class="fill-green-500 h-5 w-5"
@ -395,10 +398,10 @@ class Upload {
</svg>
<span class="text-sm text-slate-700 dark:text-gray-300 mr-4">${name} </span>
<span class="text-sm text-slate-700 dark:text-gray-300">${fileSize}</span>
<button type="button" upload-message-delete>
<button type="button" data-upload-message-delete>
<svg class="cursor-pointer fill-gray-600 dark:fill-gray-300 dark:opacity-80 h-4 w-4 " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"></path>
</svg>
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"></path>
</svg>
</button>
</div>
</div>
@ -407,7 +410,7 @@ class Upload {
}
fileFail(name, fileSize) {
const str = `<div upload-message class="mt-2 rounded p-2 w-full bg-gray-100 dark:bg-gray-800">
const str = `<div data-upload-message class="mt-2 rounded p-2 w-full bg-gray-100 dark:bg-gray-800">
<div class="flex items-center justify-between">
<svg
class="fill-red-500 h-5 w-5 mr-4"
@ -420,7 +423,7 @@ class Upload {
</svg>
<span class="text-sm text-slate-700 dark:text-gray-300 mr-4">${name} </span>
<span class="text-sm text-slate-700 dark:text-gray-300">${fileSize}</span>
<button type="button" upload-message-delete>
<button type="button" data-upload-message-delete>
<svg class="cursor-pointer fill-gray-600 dark:fill-gray-300 dark:opacity-80 h-4 w-4 " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"></path>
@ -437,13 +440,13 @@ class Upload {
class Modal {
constructor(prefix = "plugins") {
this.prefix = prefix;
this.container = document.querySelector(`[${this.prefix}-list]`);
this.modal = document.querySelector(`[${this.prefix}-modal]`);
this.container = document.querySelector(`[data-${this.prefix}-list]`);
this.modal = document.querySelector(`[data-${this.prefix}-modal]`);
this.modalNameInp = this.modal.querySelector("input#name");
this.modalExtInp = this.modal.querySelector("input#external");
this.modalTitle = this.modal.querySelector(`[${this.prefix}-modal-title]`);
this.modalTxt = this.modal.querySelector(`[${this.prefix}-modal-text]`);
this.modalTitle = this.modal.querySelector(`[data-${this.prefix}-modal-title]`);
this.modalTxt = this.modal.querySelector(`[data-${this.prefix}-modal-text]`);
this.init();
}
@ -452,7 +455,7 @@ class Modal {
//DELETE HANDLER
try {
if (
e.target.closest("button").getAttribute(`${this.prefix}-action`) ===
e.target.closest("button").getAttribute(`data-${this.prefix}-action`) ===
"delete"
) {
const btnEl = e.target.closest("button");
@ -466,7 +469,7 @@ class Modal {
//CLOSE MODAL HANDLER
try {
if (
e.target.closest("button").hasAttribute(`${this.prefix}-modal-close`)
e.target.closest("button").hasAttribute(`data-${this.prefix}-modal-close`)
) {
this.hideModal();
}
@ -482,8 +485,8 @@ class Modal {
this.modalTxt.textContent = `Are you sure you want to delete ${elName} ?`;
//external
const isExternal = el
.closest("[plugins-external]")
.getAttribute("plugins-external")
.closest("[data-plugins-external]")
.getAttribute("data-plugins-external")
.trim()
.includes("external")
? "True"

View File

@ -9,15 +9,15 @@ import {
class ServiceModal {
constructor() {
//modal elements
this.modal = document.querySelector("[services-modal]");
this.modalTitle = this.modal.querySelector("[services-modal-title]");
this.modalTabs = this.modal.querySelector(["[services-tabs]"]);
this.modalTabsHeader = this.modal.querySelector(["[services-tabs-header]"]);
this.modal = document.querySelector("[data-services-modal]");
this.modalTitle = this.modal.querySelector("[data-services-modal-title]");
this.modalTabs = this.modal.querySelector(["[data-services-tabs]"]);
this.modalTabsHeader = this.modal.querySelector(["[data-services-tabs-header]"]);
this.modalCard = this.modal.querySelector("[services-modal-card]");
this.modalCard = this.modal.querySelector("[data-services-modal-card]");
//modal forms
this.formNewEdit = this.modal.querySelector("[services-modal-form]");
this.formDelete = this.modal.querySelector("[services-modal-form-delete]");
this.formNewEdit = this.modal.querySelector("[data-services-modal-form]");
this.formDelete = this.modal.querySelector("[data-services-modal-form-delete]");
//container
this.container = document.querySelector("main");
this.init();
@ -27,8 +27,8 @@ class ServiceModal {
//to update modal data on new button click
getActionAndServName(target) {
const action = target.closest("button").getAttribute("services-action");
const serviceName = target.closest("button").getAttribute("services-name");
const action = target.closest("button").getAttribute("data-services-action");
const serviceName = target.closest("button").getAttribute("data-services-name");
return [action, serviceName];
}
@ -37,7 +37,7 @@ class ServiceModal {
this.modal.addEventListener("click", (e) => {
//close
try {
if (e.target.closest("button").hasAttribute("services-modal-close")) {
if (e.target.closest("button").hasAttribute("data-services-modal-close")) {
this.closeModal();
}
} catch (err) {}
@ -47,7 +47,7 @@ class ServiceModal {
//edit action
try {
if (
e.target.closest("button").getAttribute("services-action") === "edit"
e.target.closest("button").getAttribute("data-services-action") === "edit"
) {
//set form info and right form
const [action, serviceName] = this.getActionAndServName(e.target);
@ -55,9 +55,9 @@ class ServiceModal {
//get service data and parse it
//multiple type logic is launch at same time on relate class
const servicesSettings = e.target
.closest("[services-service]")
.querySelector("[services-settings]")
.getAttribute("value");
.closest("[data-services-service]")
.querySelector("[data-services-settings]")
.getAttribute("data-value");
const obj = JSON.parse(servicesSettings);
this.updateModalData(obj);
//show modal
@ -67,7 +67,7 @@ class ServiceModal {
//new action
try {
if (
e.target.closest("button").getAttribute("services-action") === "new"
e.target.closest("button").getAttribute("data-services-action") === "new"
) {
//set form info and right form
const [action, serviceName] = this.getActionAndServName(e.target);
@ -86,7 +86,7 @@ class ServiceModal {
//delete action
try {
if (
e.target.closest("button").getAttribute("services-action") ===
e.target.closest("button").getAttribute("data-services-action") ===
"delete"
) {
//set form info and right form
@ -113,19 +113,19 @@ class ServiceModal {
//for all other settings values
const defaultMethod = "default";
const defaultVal = inp.getAttribute("default-value") || "";
const defaultVal = inp.getAttribute("data-default-value") || "";
//SET VALUE
if (inp.getAttribute("type") === "checkbox") {
inp.checked = defaultVal === "yes" ? true : false;
inp.setAttribute("value", defaultVal);
inp.value = defaultVal;
inp.setAttribute("method", defaultMethod);
inp.setAttribute("data-method", defaultMethod);
}
if (inp.getAttribute("type") !== "checkbox") {
inp.setAttribute("value", defaultVal);
inp.setAttribute("method", defaultMethod);
inp.setAttribute("data-method", defaultMethod);
}
//SET METHOD
@ -135,17 +135,17 @@ class ServiceModal {
const selects = this.modal.querySelectorAll("select");
selects.forEach((select) => {
const defaultMethod = "default";
const defaultVal = select.getAttribute("default-value") || "";
const defaultVal = select.getAttribute("data-default-value") || "";
document
.querySelector(
`[setting-select=${select.getAttribute("setting-select-default")}]`
`[data-setting-select=${select.getAttribute("data-setting-select-default")}]`
)
.removeAttribute("disabled");
select.parentElement
.querySelector(
`button[setting-select-dropdown-btn][value='${defaultVal}']`
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`
)
.click();
@ -178,7 +178,7 @@ class ServiceModal {
if (action === "delete") {
this.showDeleteForm();
formEl.querySelector(
`[services-modal-text]`
`[data-services-modal-text]`
).textContent = `Are you sure you want to delete ${serviceName} ?`;
const nameInp = formEl.querySelector(`input[name="SERVER_NAME"]`);
nameInp.setAttribute("value", serviceName);
@ -258,7 +258,7 @@ class ServiceModal {
) {
inp.setAttribute("value", value);
inp.value = value;
inp.setAttribute("method", method);
inp.setAttribute("data-method", method);
}
//for checkbox
if (
@ -267,24 +267,24 @@ class ServiceModal {
) {
inp.checked = value === "yes" ? true : false;
inp.setAttribute("value", value);
inp.setAttribute("method", method);
inp.setAttribute("data-method", method);
if (inp.hasAttribute("disabled")) {
const hidden_inp = inp
.closest("div[checkbox-handler]")
.closest("div[data-checkbox-handler]")
.querySelector("input[type='hidden']");
hidden_inp.setAttribute("value", value);
hidden_inp.setAttribute("method", method);
hidden_inp.setAttribute("data-method", method);
}
}
//for select
if (inp.tagName === "SELECT") {
inp.parentElement
.querySelector(
`button[setting-select-dropdown-btn][value='${value}']`
`button[data-setting-select-dropdown-btn][value='${value}']`
)
.click();
inp.setAttribute("method", method);
inp.setAttribute("data-method", method);
}
//check disabled/enabled after setting values and methods
@ -307,7 +307,7 @@ class ServiceModal {
openModal() {
//switch to first setting
document.querySelector("button[tab-handler]").click();
document.querySelector("button[data-tab-handler]").click();
//show modal el
this.modal.classList.add("flex");
this.modal.classList.remove("hidden");
@ -318,7 +318,7 @@ class Multiple {
constructor(prefix) {
this.prefix = prefix;
this.container = document.querySelector("main");
this.modalForm = document.querySelector(`[${this.prefix}-modal-form]`);
this.modalForm = document.querySelector(`[data-${this.prefix}-modal-form]`);
this.init();
}
@ -331,15 +331,15 @@ class Multiple {
//edit button
try {
if (
e.target.closest("button").getAttribute("services-action") === "edit"
e.target.closest("button").getAttribute("data-services-action") === "edit"
) {
//remove all multiples
this.removePrevMultiples();
//get multiple service values and parse as obj
const servicesSettings = e.target
.closest("[services-service]")
.querySelector("[services-settings]")
.getAttribute("value");
.closest("[data-services-service]")
.querySelector("[data-services-settings]")
.getAttribute("data-value");
const obj = JSON.parse(servicesSettings);
//keep only multiple settings value
const multipleSettings = this.getMultiplesOnly(obj);
@ -351,7 +351,7 @@ class Multiple {
//new button
try {
if (
e.target.closest("button").getAttribute("services-action") === "new"
e.target.closest("button").getAttribute("data-services-action") === "new"
) {
this.removePrevMultiples();
this.addOneMultGroup();
@ -363,14 +363,14 @@ class Multiple {
//ADD BTN
try {
if (
e.target.closest("button").hasAttribute(`${this.prefix}-multiple-add`)
e.target.closest("button").hasAttribute(`data-${this.prefix}-multiple-add`)
) {
//get plugin from btn
const btn = e.target.closest("button");
const attName = btn.getAttribute(`${this.prefix}-multiple-add`);
const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`);
//get all multiple groups
const multipleEls = document.querySelectorAll(
`[${this.prefix}-settings-multiple*="${attName}"]`
`[data-${this.prefix}-settings-multiple*="${attName}"]`
);
//case no schema
if (multipleEls.length <= 0) return;
@ -382,7 +382,7 @@ class Multiple {
//and keep the highest num
multipleEls.forEach((container) => {
const ctnrName = container.getAttribute(
"services-settings-multiple"
"data-services-settings-multiple"
);
const num = this.getSuffixNumOrFalse(ctnrName);
if (!isNaN(num) && num > topNum) topNum = num;
@ -393,7 +393,7 @@ class Multiple {
const setNum = +currNum === 0 ? `` : `_${currNum}`;
//the default (schema) group is the last group
const schema = document.querySelector(
`[${this.prefix}-settings-multiple="${attName}_SCHEMA"]`
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`
);
//clone schema to create a group with new num
const schemaClone = schema.cloneNode(true);
@ -411,11 +411,11 @@ class Multiple {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-multiple-toggle`)
.hasAttribute(`data-${this.prefix}-multiple-toggle`)
) {
const att = e.target
.closest("button")
.getAttribute(`${this.prefix}-multiple-toggle`);
.getAttribute(`data-${this.prefix}-multiple-toggle`);
this.toggleMultByAtt(att);
}
//remove last child
@ -426,10 +426,10 @@ class Multiple {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-multiple-delete`)
.hasAttribute(`data-${this.prefix}-multiple-delete`)
) {
const multContainer = e.target.closest(
"[services-settings-multiple]"
"[data-services-settings-multiple]"
);
multContainer.remove();
}
@ -451,11 +451,11 @@ class Multiple {
? name.replace(`_${splitName[splitName.length - 1]}`, "").trim()
: name.trim();
const relateSetting = document.querySelector(
`[setting-container=${nameSuffixLess}_SCHEMA]`
`[data-setting-container=${nameSuffixLess}_SCHEMA]`
);
const relateCtnr = relateSetting.closest("[services-settings-multiple]");
const relateCtnr = relateSetting.closest("[data-services-settings-multiple]");
const relateCtnrName = relateCtnr.getAttribute(
"services-settings-multiple"
"data-services-settings-multiple"
);
//then we sort the setting on the right container name by suffixe number
if (!(relateCtnrName in sortMultiples)) {
@ -471,12 +471,12 @@ class Multiple {
}
addOneMultGroup() {
const settings = document.querySelector("[services-modal-form]");
const multAddBtns = settings.querySelectorAll("[services-multiple-add]");
const settings = document.querySelector("[data-services-modal-form]");
const multAddBtns = settings.querySelectorAll("[data-services-multiple-add]");
multAddBtns.forEach((btn) => {
//check if already one (SCHEMA exclude so length >= 2)
const plugin = btn.closest("[plugin-item]");
if (plugin.querySelectorAll("[services-settings-multiple]").length >= 2)
const plugin = btn.closest("[data-plugin-item]");
if (plugin.querySelectorAll("[data-services-settings-multiple]").length >= 2)
return;
btn.click();
});
@ -484,11 +484,11 @@ class Multiple {
showMultByAtt(att) {
const multContainers = document.querySelectorAll(
`[services-settings-multiple^=${att}]`
`[data-services-settings-multiple^=${att}]`
);
multContainers.forEach((container) => {
if (
!container.getAttribute("services-settings-multiple").includes("SCHEMA")
!container.getAttribute("data-services-settings-multiple").includes("SCHEMA")
)
container.classList.remove("hidden");
});
@ -496,11 +496,11 @@ class Multiple {
toggleMultByAtt(att) {
const multContainers = document.querySelectorAll(
`[services-settings-multiple^=${att}]`
`[data-services-settings-multiple^=${att}]`
);
multContainers.forEach((container) => {
if (
!container.getAttribute("services-settings-multiple").includes("SCHEMA")
!container.getAttribute("data-services-settings-multiple").includes("SCHEMA")
)
container.classList.toggle("hidden");
});
@ -510,12 +510,12 @@ class Multiple {
//get schema settings
const multiples = {};
const schemaSettings = document.querySelectorAll(
`[setting-container$="SCHEMA"]`
`[data-setting-container$="SCHEMA"]`
);
// loop on every schema settings
schemaSettings.forEach((schema) => {
const schemaName = schema
.getAttribute("setting-container")
.getAttribute("data-setting-container")
.replace("_SCHEMA", "")
.trim();
//check if match with service setting
@ -539,12 +539,14 @@ class Multiple {
)) {
//we need to access the DOM schema container
const schemaCtnr = document.querySelector(
`[services-settings-multiple="${schemaCtnrName}"]`
`[data-services-settings-multiple="${schemaCtnrName}"]`
);
//now we have to loop on each multiple settings group
for (const [suffix, settings] of Object.entries(multGroupBySuffix)) {
//we have to clone schema container first
const schemaCtnrClone = schemaCtnr.cloneNode(true);
//remove id to avoid duplicate and for W3C
schemaCtnr.removeAttribute('id')
//now we replace _SCHEMA by current suffix everywhere we need
//unless it is 0 that means no suffix
const suffixFormat = +suffix === 0 ? `` : `_${suffix}`;
@ -553,7 +555,7 @@ class Multiple {
for (const [name, data] of Object.entries(settings)) {
//get setting container of clone container
const settingContainer = schemaCtnrClone.querySelector(
`[setting-container="${name}"]`
`[data-setting-container="${name}"]`
);
//replace input info
this.setSetting(data["value"], data["method"], settingContainer);
@ -570,9 +572,9 @@ class Multiple {
changeCloneSuffix(schemaCtnrClone, suffix) {
//rename multiple container
schemaCtnrClone.setAttribute(
"services-settings-multiple",
"data-services-settings-multiple",
schemaCtnrClone
.getAttribute("services-settings-multiple")
.getAttribute("data-services-settings-multiple")
.replace("_SCHEMA", suffix)
);
@ -587,13 +589,14 @@ class Multiple {
//rename setting container
const settingCtnrs = schemaCtnrClone.querySelectorAll(
"[setting-container]"
"[data-setting-container]"
);
settingCtnrs.forEach((settingCtnr) => {
settingCtnr.setAttribute(
"setting-container",
settingCtnr.getAttribute("setting-container").replace("_SCHEMA", suffix)
"data-setting-container",
settingCtnr.getAttribute("data-setting-container").replace("_SCHEMA", suffix)
);
settingCtnr.setAttribute('id', settingCtnr.getAttribute('id').replace("_SCHEMA", suffix))
});
//rename input
@ -636,22 +639,22 @@ class Multiple {
inp.checked = value === "yes" ? true : false;
if (inp.hasAttribute("disabled")) {
const hidden_inp = inp
.closest("div[checkbox-handler]")
.closest("div[data-checkbox-handler]")
.querySelector("input[type='hidden']");
hidden_inp.setAttribute("value", value);
}
}
inp.value = value;
inp.setAttribute("method", method);
inp.setAttribute("data-method", method);
});
} catch (err) {}
//update select
try {
const select = settingContainer.querySelector("select");
const name = select.getAttribute("services-setting-select-default");
const name = select.getAttribute("data-services-setting-select-default");
const selTxt = document.querySelector(
`[services-setting-select-text='${name}']`
`[data-services-setting-select-text='${name}']`
);
selTxt.textContent = value;
@ -664,7 +667,7 @@ class Multiple {
? option.setAttribute("selected")
: option.removeAttribute("selected");
}
select.setAttribute("method", method);
select.setAttribute("data-method", method);
} catch (err) {}
}
@ -676,17 +679,17 @@ class Multiple {
setDisabled() {
const multipleCtnr = document.querySelectorAll(
"[services-settings-multiple]"
"[data-services-settings-multiple]"
);
multipleCtnr.forEach((container) => {
const settings = container.querySelectorAll("[setting-container]");
const settings = container.querySelectorAll("[data-setting-container]");
settings.forEach((setting) => {
//replace input info
try {
const inps = setting.querySelectorAll("input");
inps.forEach((inp) => {
const method = inp.getAttribute("method") || "default";
const method = inp.getAttribute("data-method") || "default";
if (method === "ui" || method === "default") {
inp.removeAttribute("disabled");
} else {
@ -698,10 +701,10 @@ class Multiple {
try {
const selects = setting.querySelectorAll("select");
selects.forEach((select) => {
const method = select.getAttribute("method") || "default";
const name = select.getAttribute("services-setting-select-default");
const method = select.getAttribute("data-method") || "default";
const name = select.getAttribute("data-services-setting-select-default");
const selDOM = document.querySelector(
`button[services-setting-select='${name}']`
`button[data-services-setting-select='${name}']`
);
if (method === "ui" || method === "default") {
selDOM.removeAttribute("disabled", "");
@ -726,23 +729,23 @@ class Multiple {
hiddenIfNoMultiples() {
//hide multiple btn if no multiple exist on a plugin
const multiples = document.querySelectorAll(
`[${this.prefix}-settings-multiple]`
`[data-${this.prefix}-settings-multiple]`
);
multiples.forEach((container) => {
if (container.querySelectorAll(`[setting-container]`).length <= 0)
if (container.querySelectorAll(`[data-setting-container]`).length <= 0)
container.parentElement
.querySelector("[multiple-handler]")
.querySelector("[data-multiple-handler]")
.classList.add("hidden");
});
}
removePrevMultiples() {
const multiPlugins = document.querySelectorAll(
`[${this.prefix}-settings-multiple]`
`[data-${this.prefix}-settings-multiple]`
);
multiPlugins.forEach((multiGrp) => {
if (
!multiGrp.getAttribute("services-settings-multiple").includes("SCHEMA")
!multiGrp.getAttribute("data-services-settings-multiple").includes("SCHEMA")
)
multiGrp.remove();
});
@ -778,7 +781,7 @@ const setModal = new ServiceModal();
const format = new FormatValue();
const setFilterGlobal = new FilterSettings(
"settings-filter",
"[service-content='settings']"
"[data-service-content='settings']"
);
const setMultiple = new Multiple("services");

View File

@ -1,15 +1,15 @@
class FolderNav {
constructor(prefix) {
this.prefix = prefix;
this.breadContainer = document.querySelector(`[${this.prefix}-breadcrumb]`);
this.container = document.querySelector(`[${this.prefix}-container]`);
this.listContainer = document.querySelector(`[${this.prefix}-folders]`);
this.els = document.querySelectorAll(`div[${this.prefix}-element]`);
this.breadContainer = document.querySelector(`[data-${this.prefix}-breadcrumb]`);
this.container = document.querySelector(`[data-${this.prefix}-container]`);
this.listContainer = document.querySelector(`[data-${this.prefix}-folders]`);
this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`);
this.files = document.querySelectorAll(
`div[${this.prefix}-element][_type='file']`
`div[data-${this.prefix}-element][data-_type='file']`
);
this.addFileEl = document.querySelector(`[${this.prefix}-add-file]`);
this.addFolderEl = document.querySelector(`[${this.prefix}-add-folder]`);
this.addFileEl = document.querySelector(`[data-${this.prefix}-add-file]`);
this.addFolderEl = document.querySelector(`[data-${this.prefix}-add-folder]`);
this.initSorted();
this.initNav();
}
@ -25,9 +25,9 @@ class FolderNav {
this.container.addEventListener("click", (e) => {
//GO ON NESTED FOLDER
try {
if (e.target.closest("div").getAttribute("_type") === "folder") {
if (e.target.closest("div").getAttribute("data-_type") === "folder") {
//avoid logic on action btn click
const folder = e.target.closest("div[_type='folder']");
const folder = e.target.closest("div[data-_type='folder']");
this.updatedNested(folder);
}
} catch (err) {}
@ -36,8 +36,8 @@ class FolderNav {
if (
e.target
.closest("li")
.hasAttribute(`${this.prefix}-breadcrumb-item`) &&
!e.target.closest("li").hasAttribute(`${this.prefix}-back`) &&
.hasAttribute(`data-${this.prefix}-breadcrumb-item`) &&
!e.target.closest("li").hasAttribute(`data-${this.prefix}-back`) &&
e.target.closest("li").nextSibling !== null
) {
const breadItem = e.target.closest("li");
@ -47,8 +47,8 @@ class FolderNav {
//BREADCRUMB BACK LOGIC
try {
if (
e.target.closest("li").hasAttribute(`${this.prefix}-back`) &&
+this.breadContainer.lastElementChild.getAttribute("level") !== 0
e.target.closest("li").hasAttribute(`data-${this.prefix}-back`) &&
+this.breadContainer.lastElementChild.getAttribute("data-level") !== 0
) {
//back is like clicking on last prev element
const prevItem =
@ -81,7 +81,7 @@ class FolderNav {
//remove useless bread
this.removeBreadElByLvl(+prevLvl);
const folder = document.querySelector(
`div[${this.prefix}-element][path='${item.getAttribute("path")}']`
`div[data-${this.prefix}-element][data-path='${item.getAttribute("data-path")}']`
);
this.updateActions(folder);
}
@ -91,8 +91,8 @@ class FolderNav {
//by default
this.hideAddConf();
//check if folder allow add file/folder
const isAddFile = folder.getAttribute("can-create-file");
const isAddFolder = folder.getAttribute("can-create-folder");
const isAddFile = folder.getAttribute("data-can-create-file");
const isAddFolder = folder.getAttribute("data-can-create-folder");
isAddFile === "True" ? this.addFileEl.classList.remove("hidden") : "";
isAddFolder === "True" ? this.addFolderEl.classList.remove("hidden") : "";
}
@ -104,11 +104,11 @@ class FolderNav {
showCurrentFolderEls(path, lvl) {
const nestedEl = document.querySelectorAll(
`div[path^="${path}/"][level="${+lvl + 1}"]`
`div[data-path^="${path}/"][data-level="${+lvl + 1}"]`
);
for (let i = 0; i < nestedEl.length; i++) {
const el = nestedEl[i];
el.setAttribute("current-el", "");
el.setAttribute("data-current-el", "");
el.classList.remove("hidden");
}
}
@ -117,28 +117,28 @@ class FolderNav {
//the clicked bread item
removeBreadElByLvl(lvl) {
const breadcrumbItem = this.breadContainer.querySelectorAll(
`[${this.prefix}-breadcrumb-item]`
`[data-${this.prefix}-breadcrumb-item]`
);
breadcrumbItem.forEach((item) => {
if (item.hasAttribute("level") && +item.getAttribute("level") > lvl)
if (item.hasAttribute("data-level") && +item.getAttribute("data-level") > lvl)
item.remove();
});
}
//retrieve path, level and text
getElAtt(el) {
const newPath = el.getAttribute("path");
const newLvl = el.getAttribute("level");
const newTxt = el.getAttribute("name");
const newPath = el.getAttribute("data-path");
const newLvl = el.getAttribute("data-level");
const newTxt = el.getAttribute("data-name");
return [newPath, newLvl, newTxt];
}
//hidden all folders
hiddenConfEls() {
this.els = document.querySelectorAll(`div[${this.prefix}-element]`);
this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`);
this.els.forEach((el) => {
el.classList.add("hidden");
el.removeAttribute("current-el");
el.removeAttribute("data-current-el");
});
}
@ -149,10 +149,10 @@ class FolderNav {
itemEl.className = "leading-normal text-sm";
//set item atts
const itemAtt = [
["path", path],
[`${this.prefix}-breadcrumb-item`, ""],
["level", level],
["name", name],
["data-path", path],
[`data-${this.prefix}-breadcrumb-item`, ""],
["data-level", level],
["data-name", name],
];
for (let i = 0; i < itemAtt.length; i++) {
itemEl.setAttribute(`${itemAtt[i][0]}`, `${itemAtt[i][1]}`);
@ -171,9 +171,9 @@ class FolderNav {
class FolderDropdown {
constructor(prefix) {
this.prefix = prefix;
this.container = document.querySelector(`[${this.prefix}-container]`);
this.container = document.querySelector(`[data-${this.prefix}-container]`);
this.dropEls = document.querySelectorAll(
`[${this.prefix}-action-dropdown]`
`[data-${this.prefix}-action-dropdown]`
);
this.init();
}
@ -184,7 +184,7 @@ class FolderDropdown {
//remove when none click
try {
if (
!e.target.closest("div").hasAttribute(`${this.prefix}-action-button`)
!e.target.closest("div").hasAttribute(`data-${this.prefix}-action-button`)
) {
this.hideDropEls();
}
@ -192,11 +192,11 @@ class FolderDropdown {
//show dropdown actions for folders
try {
if (
e.target.closest("div").hasAttribute(`${this.prefix}-action-button`)
e.target.closest("div").hasAttribute(`data-${this.prefix}-action-button`)
) {
const dropEl = e.target
.closest(`div[${this.prefix}-element]`)
.querySelector(`[${this.prefix}-action-dropdown]`);
.closest(`div[data-${this.prefix}-element]`)
.querySelector(`[data-${this.prefix}-action-dropdown]`);
//avoid multiple dropdown
if (prevActionBtn === "") prevActionBtn = dropEl;
if (prevActionBtn !== dropEl) this.hideDropEls();
@ -209,13 +209,13 @@ class FolderDropdown {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-action-dropdown-btn`)
.hasAttribute(`data-${this.prefix}-action-dropdown-btn`)
) {
const att = e.target
.closest("button")
.getAttribute(`${this.prefix}-action-dropdown-btn`);
.getAttribute(`data-${this.prefix}-action-dropdown-btn`);
const dropEl = document.querySelector(
`[${this.prefix}-action-dropdown="${att}"]`
`[data-${this.prefix}-action-dropdown="${att}"]`
);
this.hideDrop(dropEl);
}
@ -245,7 +245,7 @@ class FolderDropdown {
class FolderEditor {
constructor() {
this.editor = ace.edit("editor");
this.darkMode = document.querySelector("[dark-toggle]");
this.darkMode = document.querySelector("[data-dark-toggle]");
this.initEditor();
this.listenDarkToggle();
}
@ -287,32 +287,32 @@ class FolderModal {
constructor(prefix) {
this.prefix = prefix;
//container
this.container = document.querySelector(`[${this.prefix}-container]`);
this.container = document.querySelector(`[data-${this.prefix}-container]`);
//add service/file elements
this.breadContainer = document.querySelector(`[${this.prefix}-breadcrumb]`);
this.breadContainer = document.querySelector(`[data-${this.prefix}-breadcrumb]`);
this.addConfContainer = document.querySelector(
`[${this.prefix}-add-container]`
`[data-${this.prefix}-add-container]`
);
//modal DOM elements
this.form = document.querySelector(`[${this.prefix}-modal-form]`);
this.modalEl = document.querySelector(`[${this.prefix}-modal]`);
this.form = document.querySelector(`[data-${this.prefix}-modal-form]`);
this.modalEl = document.querySelector(`[data-${this.prefix}-modal]`);
this.modalTitle = this.modalEl.querySelector(
`[${this.prefix}-modal-title]`
`[data-${this.prefix}-modal-title]`
);
this.modalPath = this.modalEl.querySelector(`[${this.prefix}-modal-path]`);
this.modalPath = this.modalEl.querySelector(`[data-${this.prefix}-modal-path]`);
this.modalEditor = this.modalEl.querySelector(
`[${this.prefix}-modal-editor]`
`[data-${this.prefix}-modal-editor]`
);
this.modalPathPrev = this.modalPath.querySelector(
`p[${this.prefix}-modal-path-prefix]`
`p[data-${this.prefix}-modal-path-prefix]`
);
this.modalPathName = this.modalPath.querySelector("input");
this.modalPathSuffix = this.modalPath.querySelector(
`p[${this.prefix}-modal-path-suffix]`
`p[data-${this.prefix}-modal-path-suffix]`
);
this.modalSubmit = this.modalEl.querySelector(
`[${this.prefix}-modal-submit]`
`[data-${this.prefix}-modal-submit]`
);
//hidden input for backend
this.modalInpPath = this.modalEl.querySelector("#path");
@ -336,7 +336,7 @@ class FolderModal {
this.addConfContainer.addEventListener("click", (e) => {
//add folder
try {
if (e.target.closest("li").hasAttribute(`${this.prefix}-add-folder`)) {
if (e.target.closest("li").hasAttribute(`data-${this.prefix}-add-folder`)) {
this.setModal(
"new",
this.getPathFromBread(),
@ -349,7 +349,7 @@ class FolderModal {
} catch (err) {}
//add file
try {
if (e.target.closest("li").hasAttribute(`${this.prefix}-add-file`)) {
if (e.target.closest("li").hasAttribute(`data-${this.prefix}-add-file`)) {
this.setModal(
"new",
this.getPathFromBread(),
@ -367,10 +367,10 @@ class FolderModal {
this.container.addEventListener("click", (e) => {
//click on file logic
try {
if (e.target.closest("div").getAttribute("_type") == "file") {
if (e.target.closest("div").getAttribute("data-_type") == "file") {
const btnEl = e.target
.closest("div")
.querySelector('button[value="view"]');
.querySelector('button[value]');
const [action, path, type, content, name, level] =
this.getInfoFromActionBtn(btnEl);
this.setModal(action, path, type, content, name, level);
@ -382,7 +382,7 @@ class FolderModal {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-action-dropdown-btn`) &&
.hasAttribute(`data-${this.prefix}-action-dropdown-btn`) &&
e.target.closest("button").getAttribute("value") !== "download"
) {
const btnEl = e.target.closest("button");
@ -397,7 +397,7 @@ class FolderModal {
if (
e.target
.closest("button")
.hasAttribute(`${this.prefix}-action-dropdown-btn`) &&
.hasAttribute(`data-${this.prefix}-action-dropdown-btn`) &&
e.target.closest("button").getAttribute("value") === "download"
) {
const btnEl = e.target.closest("button");
@ -414,7 +414,7 @@ class FolderModal {
//close modal logic
try {
if (
e.target.closest("button").hasAttribute(`${this.prefix}-modal-close`)
e.target.closest("button").hasAttribute(`data-${this.prefix}-modal-close`)
) {
this.closeModal();
}
@ -467,12 +467,12 @@ class FolderModal {
//for add file/folder btn
//get path of last bread element
getPathFromBread() {
const path = this.breadContainer.lastElementChild.getAttribute("path");
const path = this.breadContainer.lastElementChild.getAttribute("data-path");
return `${path}/`;
}
getLevelFromBread() {
const level = this.breadContainer.lastElementChild.getAttribute("level");
const level = this.breadContainer.lastElementChild.getAttribute("data-level");
return level;
}
//set all needed data from btn action and folder info
@ -562,16 +562,16 @@ class FolderModal {
//get all needed info when clicking on action btn
getInfoFromActionBtn(btnEl) {
const action = btnEl.getAttribute("value");
const name = btnEl.getAttribute(`${this.prefix}-action-dropdown-btn`);
const folder = btnEl.closest(`[${this.prefix}-element]`);
const level = folder.getAttribute("level");
const path = folder.getAttribute("path");
const type = folder.getAttribute("_type");
const name = btnEl.getAttribute(`data-${this.prefix}-action-dropdown-btn`);
const folder = btnEl.closest(`[data-${this.prefix}-element]`);
const level = folder.getAttribute("data-level");
const path = folder.getAttribute("data-path");
const type = folder.getAttribute("data-_type");
let content;
try {
content = folder
.querySelector(`[${this.prefix}-content]`)
.getAttribute("value");
.querySelector(`[data-${this.prefix}-content]`)
.getAttribute("data-value");
} catch (err) {
content = "";
}

View File

@ -9,7 +9,7 @@ class Checkbox {
try {
//case a related checkbox element is clicked and checkbox is enabled
if (
e.target.closest("div").hasAttribute("checkbox-handler") &&
e.target.closest("div").hasAttribute("data-checkbox-handler") &&
!e.target
.closest("div")
.querySelector('input[type="checkbox"]')
@ -41,15 +41,15 @@ class Select {
try {
if (!e.target.closest("button")) {
const selectEls = document.querySelectorAll(
"div[setting-select-dropdown]"
"div[data-setting-select-dropdown]"
);
selectEls.forEach((select) => {
select.classList.add("hidden");
select.classList.remove("flex");
});
const btnEls = document.querySelectorAll("button[setting-select]");
const btnEls = document.querySelectorAll("button[data-setting-select]");
btnEls.forEach((btn) => {
const dropdownChevron = btn.querySelector(`svg[setting-select]`);
const dropdownChevron = btn.querySelector(`svg[data-setting-select]`);
dropdownChevron.classList.remove("rotate-180");
});
}
@ -57,7 +57,7 @@ class Select {
//SELECT BTN LOGIC
try {
if (
e.target.closest("button").hasAttribute(`setting-select`) &&
e.target.closest("button").hasAttribute(`data-setting-select`) &&
!e.target.closest("button").hasAttribute(`disabled`)
) {
const btnEl = e.target.closest("button");
@ -67,22 +67,22 @@ class Select {
//SELECT DROPDOWN BTN LOGIC
try {
if (
e.target.closest("button").hasAttribute(`setting-select-dropdown-btn`)
e.target.closest("button").hasAttribute(`data-setting-select-dropdown-btn`)
) {
const btn = e.target.closest(`button[setting-select-dropdown-btn]`);
const btn = e.target.closest(`button[data-setting-select-dropdown-btn]`);
const btnValue = btn.getAttribute("value");
//add new value to custom
const selectCustom = btn
.closest("div[select-container]")
.querySelector(`button[setting-select]`);
.closest("div[data-select-container]")
.querySelector(`button[data-setting-select]`);
selectCustom.querySelector(`[setting-select-text]`).textContent =
selectCustom.querySelector(`[data-setting-select-text]`).textContent =
btnValue;
//add selected to new value
//change style
const dropdownEl = btn.closest(`div[setting-select-dropdown]`);
const dropdownEl = btn.closest(`div[data-setting-select-dropdown]`);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
@ -109,12 +109,12 @@ class Select {
//close dropdown
const dropdownChevron =
selectCustom.querySelector(`svg[setting-select]`);
selectCustom.querySelector(`svg[data-setting-select]`);
dropdownChevron.classList.remove("rotate-180");
//update real select element
const realSel = btn
.closest("div[setting-container]")
.closest("div[data-setting-container]")
.querySelector("select");
this.updateSelected(realSel, btnValue);
}
@ -141,8 +141,8 @@ class Select {
//toggle dropdown
const dropdownEl = btn
.closest("div")
.querySelector(`[setting-select-dropdown]`);
const dropdownChevron = btn.querySelector(`svg[setting-select]`);
.querySelector(`[data-setting-select-dropdown]`);
const dropdownChevron = btn.querySelector(`svg[data-setting-select]`);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
dropdownChevron.classList.toggle("rotate-180");
@ -157,10 +157,10 @@ class Password {
init() {
window.addEventListener("click", (e) => {
try {
if (e.target.closest("button").hasAttribute("setting-password")) {
if (e.target.closest("button").hasAttribute("data-setting-password")) {
const btn = e.target.closest("button");
const action = btn.getAttribute("setting-password");
const inp = btn.closest("[setting-container]").querySelector("input");
const action = btn.getAttribute("data-setting-password");
const inp = btn.closest("[data-setting-container]").querySelector("input");
this.setValDisplay(action, inp);
this.hiddenBtns(btn);
this.showOppositeBtn(btn, action);
@ -174,7 +174,7 @@ class Password {
const opposite = action === "visible" ? "invisible" : "visible";
btnEls.forEach((btn) => {
const action = btn.getAttribute("setting-password");
const action = btn.getAttribute("data-setting-password");
if (action === opposite) {
btn.classList.add("flex");
@ -199,8 +199,8 @@ class Password {
getBtns(btnEl) {
return btnEl
.closest("[setting-container]")
.querySelectorAll("button[setting-password]");
.closest("[data-setting-container]")
.querySelectorAll("button[data-setting-password]");
}
}

View File

@ -7,7 +7,7 @@ class Popover {
window.addEventListener("pointerover", (e) => {
//POPOVER LOGIC
try {
if (e.target.closest("svg").hasAttribute(`popover-btn`)) {
if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) {
this.showPopover(e.target);
}
} catch (err) {}
@ -16,7 +16,7 @@ class Popover {
window.addEventListener("pointerout", (e) => {
//POPOVER LOGIC
try {
if (e.target.closest("svg").hasAttribute(`popover-btn`)) {
if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) {
this.hidePopover(e.target);
}
} catch (err) {}
@ -26,14 +26,14 @@ class Popover {
showPopover(el) {
const btn = el.closest("svg");
//toggle curr popover
const popover = btn.parentElement.querySelector(`[popover-content]`);
const popover = btn.parentElement.querySelector(`[data-popover-content]`);
popover.classList.remove("hidden");
}
hidePopover(el) {
const btn = el.closest("svg");
//toggle curr popover
const popover = btn.parentElement.querySelector(`[popover-content]`);
const popover = btn.parentElement.querySelector(`[data-popover-content]`);
popover.classList.add("hidden");
}
}
@ -47,15 +47,15 @@ class Tabs {
window.addEventListener("click", (e) => {
try {
if (
e.target.closest("button").hasAttribute("tab-handler") ||
e.target.closest("button").hasAttribute("tab-handler-mobile")
e.target.closest("button").hasAttribute("data-tab-handler") ||
e.target.closest("button").hasAttribute("data-tab-handler-mobile")
) {
//get needed data
const tab = e.target.closest("button");
const tabAtt =
tab.getAttribute("tab-handler") ||
tab.getAttribute("tab-handler-mobile");
const container = tab.closest("div[service-content]");
tab.getAttribute("data-tab-handler") ||
tab.getAttribute("data-tab-handler-mobile");
const container = tab.closest("div[data-service-content]");
// change style
this.resetTabsStyle(container);
this.highlightClicked(container, tabAtt);
@ -69,9 +69,9 @@ class Tabs {
} catch (err) {}
try {
if (e.target.closest("button").hasAttribute("tab-dropdown-btn")) {
if (e.target.closest("button").hasAttribute("data-tab-dropdown-btn")) {
const dropBtn = e.target.closest("button");
const container = dropBtn.closest("div[service-content]");
const container = dropBtn.closest("div[data-service-content]");
this.toggleDropdown(container);
}
} catch (err) {}
@ -80,13 +80,13 @@ class Tabs {
resetTabsStyle(container) {
//reset desktop style
const tabsDesktop = container.querySelectorAll("button[tab-handler]");
const tabsDesktop = container.querySelectorAll("button[data-tab-handler]");
tabsDesktop.forEach((tab) => {
tab.classList.remove("brightness-90", "z-[1001]");
tab.classList.add("z-1000");
});
//reset mobile style
const tabsMobile = container.querySelectorAll("button[tab-handler-mobile]");
const tabsMobile = container.querySelectorAll("button[data-tab-handler-mobile]");
tabsMobile.forEach((tab) => {
tab.classList.add(
"bg-white",
@ -107,13 +107,13 @@ class Tabs {
highlightClicked(container, tabAtt) {
//desktop case
const tabDesktop = container.querySelector(
`button[tab-handler='${tabAtt}']`
`button[data-tab-handler='${tabAtt}']`
);
tabDesktop.classList.add("brightness-90", "z-[1001]");
//mobile case
const tabMobile = container.querySelector(
`button[tab-handler-mobile='${tabAtt}']`
`button[data-tab-handler-mobile='${tabAtt}']`
);
tabMobile.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
tabMobile.classList.remove(
@ -124,30 +124,30 @@ class Tabs {
}
hideAllSettings(container) {
const plugins = container.querySelectorAll("[plugin-item]");
const plugins = container.querySelectorAll("[data-plugin-item]");
plugins.forEach((plugin) => {
plugin.classList.add("hidden");
});
}
showSettingClicked(container, tabAtt) {
const plugin = container.querySelector(`[plugin-item='${tabAtt}']`);
const plugin = container.querySelector(`[data-plugin-item='${tabAtt}']`);
plugin.classList.remove("hidden");
}
setDropBtnText(container, tabAtt) {
const dropBtn = container.querySelector("[tab-dropdown-btn]");
const dropBtn = container.querySelector("[data-tab-dropdown-btn]");
dropBtn.querySelector("span").textContent = tabAtt;
}
closeDropdown(container) {
const dropdown = container.querySelector("[tab-dropdown]");
const dropdown = container.querySelector("[data-tab-dropdown]");
dropdown.classList.add("hidden");
dropdown.classList.remove("flex");
}
toggleDropdown(container) {
const dropdown = container.querySelector("[tab-dropdown]");
const dropdown = container.querySelector("[data-tab-dropdown]");
dropdown.classList.toggle("hidden");
dropdown.classList.toggle("flex");
}
@ -174,7 +174,7 @@ class FilterSettings {
this.input = document.querySelector(`input#${inputID}`);
//DESKTOP
this.container = document.querySelector(container);
this.deskTabs = this.container.querySelectorAll(`[tab-handler]`);
this.deskTabs = this.container.querySelectorAll(`[data-tab-handler]`);
this.init();
}
@ -206,15 +206,15 @@ class FilterSettings {
});
//case no setting match, hidden tab and content
if (settingCount === hiddenCount) {
const tabName = tab.getAttribute(`tab-handler`);
const tabName = tab.getAttribute(`data-tab-handler`);
//hide mobile and desk tabs
tab.classList.add("hidden");
this.container
.querySelector(`[tab-handler-mobile="${tabName}"]`)
.querySelector(`[data-tab-handler-mobile="${tabName}"]`)
.classList.add("hidden");
this.container
.querySelector(`[plugin-item=${tabName}]`)
.querySelector("[setting-header]")
.querySelector(`[data-plugin-item=${tabName}]`)
.querySelector("[data-setting-header]")
.classList.add("hidden");
}
@ -224,15 +224,15 @@ class FilterSettings {
resetFilter() {
this.deskTabs.forEach((tab) => {
const tabName = tab.getAttribute(`tab-handler`);
const tabName = tab.getAttribute(`data-tab-handler`);
//hide mobile and desk tabs
tab.classList.remove("hidden");
this.container
.querySelector(`[tab-handler-mobile="${tabName}"]`)
.querySelector(`[data-tab-handler-mobile="${tabName}"]`)
.classList.remove("hidden");
this.container
.querySelector(`[plugin-item=${tabName}]`)
.querySelector("[setting-header]")
.querySelector(`[data-plugin-item=${tabName}]`)
.querySelector("[data-setting-header]")
.classList.remove("hidden");
const settings = this.getSettingsFromTab(tab);
settings.forEach((setting) => {
@ -242,11 +242,11 @@ class FilterSettings {
}
getSettingsFromTab(tabEl) {
const tabName = tabEl.getAttribute(`tab-handler`);
const tabName = tabEl.getAttribute(`data-tab-handler`);
const settingContainer = this.container
.querySelector(`[plugin-item="${tabName}"]`)
.querySelector(`[plugin-settings]`);
const settings = settingContainer.querySelectorAll("[setting-container]");
.querySelector(`[data-plugin-item="${tabName}"]`)
.querySelector(`[data-plugin-settings]`);
const settings = settingContainer.querySelectorAll("[data-setting-container]");
return settings;
}
}

View File

@ -10,11 +10,11 @@
>Your browser does not support JavaScript!</noscript
>
<div
loader
data-loader
class="fixed z-[10000] transition duration-300 h-screen w-screen bg-primary flex justify-center align-middle items-center"
>
<img
loader-img
data-loader-img
src="images/logo-menu-2.png"
class="duration-300 w-40 h-12 sm:w-50 sm:h-14 md:w-60 md:h-16 lg:w-80 lg:h-24 inline transition-all"
alt="main logo"

View File

@ -1,2 +1,2 @@
{% extends "base.html" %} {% block content %} {% include "file-manager.html" %}
{% extends "base.html" %} {% block content %} {% include "file_manager.html" %}
{% endblock %}

View File

@ -1,2 +1,2 @@
{% extends "base.html" %} {% block content %} {% include "file-manager.html" %}
{% extends "base.html" %} {% block content %} {% include "file_manager.html" %}
{% endblock %}

View File

@ -2,7 +2,7 @@
url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- main container -->
<div
{{current_endpoint}}-container
data-{{current_endpoint}}-container
class="dark:brightness-110 md:min-h-75-screen col-span-12 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<div class="w-full grid-cols-12 grid">
@ -13,12 +13,12 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
</h5>
<!--breadcrumb -->
<ul
{{current_endpoint}}-breadcrumb
data-{{current_endpoint}}-breadcrumb
class="flex flex-wrap bg-transparent rounded-lg md:mb-8"
>
<li
{{current_endpoint}}-breadcrumb-item
{{current_endpoint}}-back
data-{{current_endpoint}}-breadcrumb-item
data-{{current_endpoint}}-back
class="mr-2 cursor-pointer text-sm capitalize leading-normal text-gray-700"
aria-current="page"
>
@ -39,10 +39,10 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
</svg>
</li>
<li
{{current_endpoint}}-breadcrumb-item
level="0"
path="{% if current_endpoint == "cache" %}/var/cache/bunkerweb{% elif current_endpoint == "configs" %}/etc/bunkerweb/{{current_endpoint}}{% endif %}"
name="{{current_endpoint}}"
data-{{current_endpoint}}-breadcrumb-item
data-level="0"
data-path="{% if current_endpoint == "cache" %}/var/cache/bunkerweb{% elif current_endpoint == "configs" %}/etc/bunkerweb/{{current_endpoint}}{% endif %}"
data-name="{{current_endpoint}}"
class="leading-normal text-sm"
>
<button
@ -57,11 +57,11 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
</div>
<!-- actions -->
<ul
{{current_endpoint}}-add-container
data-{{current_endpoint}}-add-container
class="col-span-12 md:col-span-4 my-2 md:my-0 w-full flex justify-center md:justify-end items-center mb-3"
>
<li
{{current_endpoint}}-add-folder
data-{{current_endpoint}}-add-folder
class="rounded transition hidden flex-col items-center mx-2 p-2 md:py-4 md:px-6 relative cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-800"
>
<button type="button">
@ -80,16 +80,15 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
d="M5.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7m0 0a3 3 0 01-3 3m0 3h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008zm-3 6h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008z"
/>
</svg>
<p
<span
class="dark:text-gray-500 pt-1 mb-0 font-sans font-semibold leading-normal uppercase text-sm lg:text-md"
>
ADD SERVICE
</p>
</span>
</button>
</li>
<li
{{current_endpoint}}-add-file
data-{{current_endpoint}}-add-file
class="rounded transition hidden flex-col items-center mx-2 p-2 md:py-4 md:px-6 relative cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-800"
>
<button type="button">
@ -109,11 +108,11 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
/>
</svg>
<p
<span
class="dark:text-gray-500 pt-1 mb-0 font-sans font-semibold leading-normal uppercase text-sm lg:text-md"
>
ADD FILE
</p>
</span>
</button>
</li>
</ul>
@ -121,48 +120,42 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
</div>
<!-- folders-->
<div {{current_endpoint}}-folders
<div data-{{current_endpoint}}-folders
class="grid grid-cols-12 gap-3">
{% for folder in folders %} {% for child in folder['children'] recursive %}
{{loop(child['children'])}}
<!-- folder -->
<div
{{current_endpoint}}-element="{{child['name']}}"
name="{{child['name']}}"
can-create-folder="{{child['can_create_folders']}}"
can-create-file="{{child['can_create_files']}}"
path="{{child['path']}}"
level="{{loop.depth}}"
_type="{{child['type']}}"
data-{{current_endpoint}}-element="{{child['name']}}"
data-name="{{child['name']}}"
data-can-create-folder="{{child['can_create_folders']}}"
data-can-create-file="{{child['can_create_files']}}"
data-path="{{child['path']}}"
data-level="{{loop.depth}}"
data-_type="{{child['type']}}"
class="cursor-pointer {% if loop.depth != 1%} hidden {% endif %} relative min-h-20 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-3 flex justify-center items-center h-full transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800"
>
{% if child['content'] %}
<span
value="{{child['content']}}"
{{current_endpoint}}-content
data-value="{{child['content']}}"
data-{{current_endpoint}}-content
class="hidden"
></span>
{% endif %}
<span>
<div class="pointer-events-none">
<!-- service root-->
{% if child['type'] == "folder" and current_endpoint == "configs" and loop.depth == 1 %}
<svg
class="absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
class=" absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="{1.5}"
stroke="currentColor"
className="w-6 h-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"
/>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
</svg>
@ -171,42 +164,41 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- services folder -->
{% if child['type'] == "folder" and current_endpoint == "configs" and loop.depth != 1 %}
<svg class="absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" /></svg> {% endif %}
<svg class=" absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" /></svg> {% endif %}
<!-- end services folder-->
<!-- services files -->
{% if child['type'] == "file" and current_endpoint == "configs" and loop.depth != 1 %}
<svg class="absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>
<svg class=" absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>
{% endif %}
<!-- end services files-->
<!-- cache folder-->
{% if child['type'] == "folder" and current_endpoint == "cache" and loop.depth == 1 %}
<svg class="absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<svg class=" absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />
</svg>
{% endif %}
<!-- end cache folder -->
<!-- cache file -->
{% if child['type'] == "file" and current_endpoint == "cache" %}
<svg class="absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
<svg class=" absolute left-3 top-5 h-10 w-10 fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 13.5H9m4.06-7.19l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
</svg>
{% endif %}
<!-- end cache file -->
<p
{{current_endpoint}}-element-text
class="transition duration-300 ease-in-out dark:opacity-90 text-center ml-12 mr-7 mb-0 text-sm md:text-base text-slate-700 dark:text-gray-300"
<span
data-{{current_endpoint}}-element-text
class="pointer-events-none transition duration-300 ease-in-out dark:opacity-90 text-center ml-12 mr-7 mb-0 text-sm md:text-base text-slate-700 dark:text-gray-300"
>
{{child['name']}}
</p>
</span>
</div>
<div>
<!-- action button -->
<div
{{current_endpoint}}-action-button="{{child['name']}}"
type="button"
data-{{current_endpoint}}-action-button="{{child['name']}}"
class="dark:brightness-125 dark:hover:brightness-100 flex justify-center items-center absolute h-full w-10 bg-primary fill-white first-letter:absolute top-0 -right-1 font-bold text-center text-white uppercase transition-all rounded-none rounded-r-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem bg-150 bg-x-25 active:opacity-85"
>
<svg
@ -226,20 +218,21 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
</svg>
</div>
<!-- end action button -->
</span>
</div>
<!-- dropdown actions -->
<div
{{current_endpoint}}-action-dropdown="{{child['name']}}"
<div role="tablist"
data-{{current_endpoint}}-action-dropdown="{{child['name']}}"
class="absolute hidden flex-col z-110 w-48 right-0 top-0 translate-y-16"
>
<!-- view button-->
<button
role="tab"
type="button"
value="view"
{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
data-{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 w-full border-t rounded-t border-b border-l border-r hover:bg-gray-100"
>
<div class="flex justify-start items-center">
<span class="flex justify-start items-center">
<svg
class="h-6 w-6 stroke-green-700 dark:brightness-125"
xmlns="http://www.w3.org/2000/svg"
@ -264,7 +257,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase"
>view</span
>
</div>
</span>
</button>
<!-- end view button-->
@ -272,12 +265,13 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
{% if child['type'] == "file" and child['can_edit'] == True or
child['type'] == "folder" and child['can_edit'] == True %}
<button
role="tab"
type="button"
value="edit"
{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
data-{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
class="duration-300 border-gray-300 hover:brightness-90 bg-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 w-full border-b border-l border-r hover:bg-gray-100"
>
<div class="flex justify-start items-center">
<span class="flex justify-start items-center">
<svg class="h-6 w-6 stroke-orange-500"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" />
@ -287,7 +281,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase"
>edit</span
>
</div>
</span>
</button>
{% endif %}
<!-- end edit button -->
@ -296,14 +290,15 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
{% if child['type'] == "file" and child['can_download'] == True %}
{% if current_endpoint == "cache" %}
<button
role="tab"
type="button"
value="download"
{{current_endpoint}}-download="{{child['name'].split('/')[0]}}"
{{current_endpoint}}-file="{{child['name'].split('/')[1]}}"
{{current_endpoint}}-setting-select-dropdown-btn="{{child['name'].split('/')[0]}}"
data-{{current_endpoint}}-download="{{child['name'].split('/')[0]}}"
data-{{current_endpoint}}-file="{{child['name'].split('/')[1]}}"
data-{{current_endpoint}}-setting-select-dropdown-btn="{{child['name'].split('/')[0]}}"
class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 w-full border-b border-l border-r hover:bg-gray-100"
>
<div class="flex justify-start items-center">
<span class="flex justify-start items-center">
<svg class="h-6 w-6 stroke-sky-500"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
@ -314,16 +309,17 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase"
>download</span
>
</div>
</span>
</button>
{%else%}
<button
role="tab"
type="button"
value="download"
{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
data-{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 w-full border-b border-l border-r hover:bg-gray-100"
>
<div class="flex justify-start items-center">
<span class="flex justify-start items-center">
<svg class="h-6 w-6 stroke-sky-500"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
@ -334,7 +330,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase"
>download</span
>
</div>
</span>
</button>
{%endif %}
{% endif %}
@ -343,12 +339,13 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- delete button -->
{% if child['can_delete'] == True %}
<button
role="tab"
type="button"
value="delete"
{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
data-{{current_endpoint}}-action-dropdown-btn="{{child['name']}}"
class="bg-white duration-300 border-gray-300 hover:brightness-90 text-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 w-full border-b border-l border-r hover:bg-gray-100"
>
<div class="flex justify-start items-center">
<span class="flex justify-start items-center">
<svg class="h-6 w-6 stroke-red-500"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
@ -357,7 +354,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase"
>delete</span
>
</div>
</span>
</button>
{% endif %}
<!-- end delete button -->
@ -375,7 +372,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- modal -->
<div
{{current_endpoint}}-modal
data-{{current_endpoint}}-modal
class="hidden w-screen h-screen fixed bg-gray-600/50 z-[1001] top-0 left-0 justify-center items-center"
>
<div
@ -383,24 +380,24 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
>
<div class="w-full flex justify-between">
<p
{{current_endpoint}}-modal-title
data-{{current_endpoint}}-modal-title
class="dark:text-white mb-0 font-sans font-semibold leading-normal uppercase text-sm"
>
TITLE
</p>
</div>
<form
{{current_endpoint}}-modal-form
data-{{current_endpoint}}-modal-form
class="w-full"
id="form-services"
method="POST"
>
<div
class="mb-2 flex flex-col sm:flex-row justify-start align-middle items-start sm:items-center"
{{current_endpoint}}-modal-path
data-{{current_endpoint}}-modal-path
>
<p
{{current_endpoint}}-modal-path-prefix
data-{{current_endpoint}}-modal-path-prefix
class="mb-0 dark:text-white dark:opacity-75 text-gray-700 opacity-50 text-sm"
></p>
<input
@ -412,7 +409,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
required
/>
<p
{{current_endpoint}}-modal-path-suffix
data-{{current_endpoint}}-modal-path-suffix
class="mb-0 dark:text-white dark:opacity-75 text-gray-700 opacity-50 text-sm"
>
suffix
@ -423,10 +420,10 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<input type="hidden" id="path" value="" name="path" />
<input type="hidden" id="old_name" value="" name="old_name" />
<input type="hidden" id="_type" value="file" name="type" />
<textarea class="hidden" id="content" name="content" value=""></textarea>
<textarea class="hidden" id="content" name="content"></textarea>
<!-- editor-->
<div
{{current_endpoint}}-modal-editor
data-{{current_endpoint}}-modal-editor
id="editor"
class="text-base w-full h-48 overflow-hidden overflow-y-auto my-2 border border-gray-300 dark:border-slate-800"
></div>
@ -434,14 +431,14 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<div class="mt-4 w-full justify-end flex">
<button
{{current_endpoint}}-modal-close
data-{{current_endpoint}}-modal-close
type="button"
class="dark:brightness-90 mr-3 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>
Close
</button>
<button
{{current_endpoint}}-modal-submit
data-{{current_endpoint}}-modal-submit
type="submit"
class="dark:brightness-90 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>

View File

@ -1,37 +1,39 @@
<!-- float button-->
{% with messages = get_flashed_messages(with_categories=true) %}
<button
type="button"
flash-sidebar-open
class="transition scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 fixed p-3 text-xl bg-white shadow-sm cursor-pointer top-2 sm:top-3 right-19 sm:right-24 xl:right-24 z-990 rounded-circle text-slate-700"
>
<svg
class="fill-yellow-500 -translate-y-0.4 h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
<div class="fixed top-2 sm:top-3 right-19 sm:right-24 xl:right-24 z-990">
<button
type="button"
data-flash-sidebar-open
class="transition scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 p-3 text-xl bg-white shadow-sm cursor-pointer rounded-circle text-slate-700"
>
<path
d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v18.8c0 47-17.3 92.4-48.5 127.6l-7.4 8.3c-8.4 9.4-10.4 22.9-5.3 34.4S19.4 416 32 416H416c12.6 0 24-7.4 29.2-18.9s3.1-25-5.3-34.4l-7.4-8.3C401.3 319.2 384 273.9 384 226.8V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm45.3 493.3c12-12 18.7-28.3 18.7-45.3H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7z"
/>
</svg>
<svg
class="fill-yellow-500 -translate-y-0.4 h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
>
<path
d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v18.8c0 47-17.3 92.4-48.5 127.6l-7.4 8.3c-8.4 9.4-10.4 22.9-5.3 34.4S19.4 416 32 416H416c12.6 0 24-7.4 29.2-18.9s3.1-25-5.3-34.4l-7.4-8.3C401.3 319.2 384 273.9 384 226.8V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm45.3 493.3c12-12 18.7-28.3 18.7-45.3H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7z"
/>
</svg>
</button>
<div
class="px-2 translate-x-2 bottom-0 right-0 absolute rounded-full bg-white"
>
<p flash-count class="mb-0 text-sm text-bold text-red-500">
<p data-flash-count class="mb-0 text-sm text-bold text-red-500">
{%if messages %} {{messages|length}}{%else%} 0 {%endif%}
</p>
</div>
</button>
</div>
<!-- end float button-->
<!-- right sidebar -->
<aside
flash-sidebar
data-flash-sidebar
class="translate-x-90 -right-0 transition z-sticky dark:bg-slate-850 dark:brightness-110 shadow-3xl max-w-full w-90 ease fixed top-0 left-auto flex h-full min-w-0 flex-col break-words rounded-none border-0 bg-white bg-clip-border px-0.5"
>
<!-- close btn-->
<svg
flash-sidebar-close
data-flash-sidebar-close
class="cursor-pointer fill-gray-600 dark:fill-gray-300 dark:opacity-80 absolute h-8 w-8 top-4 right-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512"
@ -51,7 +53,7 @@
<!-- close button -->
<div class="float-right mt-6">
<button
flash-sidebar-close
data-flash-sidebar-close
class="inline-block p-0 mb-4 text-sm font-bold leading-normal text-center uppercase align-middle transition-all ease-in bg-transparent border-0 rounded-lg shadow-none cursor-pointer hover:-translate-y-px tracking-tight-rem bg-150 bg-x-25 active:opacity-85 dark:text-white text-slate-700"
>
<i class="fa fa-close"></i>
@ -69,7 +71,7 @@
<!-- flash message-->
{% for category, message in messages %}
<div
flash-message
data-flash-message
class="{% if category == 'error' %}bg-red-500 {%else%} bg-green-500 {%endif %} my-2 border relative p-4 w-11/12 min-h-20 rounded-lg hover:scale-102 transition shadow-md break-words dark:brightness-90"
>
<div class="flex justify-between align-top items-start">
@ -79,8 +81,7 @@
<h5 class="text-lg mb-0 text-white">Success</h5>
{%endif%}
<button
close-flash-message
role="close alert message"
data-close-flash-message
type="button"
class="absolute right-8 top-2"
>

View File

@ -1,9 +1,9 @@
{% extends "base.html" %} {% block content %}
<div service-content="settings" class="col-span-12 gap-y-4 grid grid-cols-12">
<div data-service-content="settings" class="col-span-12 gap-y-4 grid grid-cols-12">
<div class="p-4 col-span-12 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<div {{current_endpoint}}-tabs-header class="flex justify-start items-center gap-x-4 gap-y-2 my-3">
<div data-{{current_endpoint}}-tabs-header class="flex justify-start items-center gap-x-4 gap-y-2 my-3">
<h5 class="transition duration-300 ease-in-out dark:opacity-90 ml-2 font-bold text-md uppercase dark:text-white mb-0">CONFIGS</h5>
<!-- search inpt-->
<div class="flex relative col-span-12 sm:col-span-6 lg:col-span-4 3xl:col-span-3">
@ -27,7 +27,7 @@
<!-- form global conf -->
<form
global-config-form
data-global-config-form
id="form-edit-global-configs"
method="POST"
class="flex flex-col justify-between overflow-hidden overflow-y-auto max-h-135 md:max-h-160 dark:brightness-110 col-span-12 break-words bg-white shadow-xl p-4 dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"

View File

@ -2,8 +2,8 @@
%}
<head>
<base href="{{ config["ABSOLUTE_URI"] }}">
<meta charset="utf-8" />
<base href="{{ config["ABSOLUTE_URI"] }}">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
@ -21,41 +21,37 @@
<!-- tailwind style -->
<link rel="stylesheet" type="text/css" href="./css/dashboard.css" />
<script type="module" defer src="./js/global.js"></script>
<script type="module" src="./js/global.js"></script>
<script
type="text/javascript"
charset="utf-8"
defer
src="./js/editor/ace.js"
></script>
{% if current_endpoint == "global_config" %}
<script defer type="module" src="./js/global_config.js"></script>
<script type="module" src="./js/global_config.js"></script>
{% elif current_endpoint == "configs" %}
<script defer type="module" src="./js/configs.js"></script>
<script type="module" src="./js/configs.js"></script>
{% elif current_endpoint == "services" %}
<script defer type="module" src="./js/services.js"></script>
<script type="module" src="./js/services.js"></script>
{% elif current_endpoint == "plugins" %}
<script type="module" defer src="./js/plugins.js"></script>
<script type="module" src="./js/plugins.js"></script>
{% elif current_endpoint == "cache" %}
<script defer type="module" src="./js/cache.js"></script>
<script type="module" src="./js/cache.js"></script>
{% elif current_endpoint == "logs" %}
<link rel="stylesheet" type="text/css" href="./css/flatpickr.css" />
<link rel="stylesheet" type="text/css" href="./css/flatpickr.dark.css" />
<script type="module" defer src="./js/utils/flatpickr.js"></script>
<script type="module" defer src="./js/utils/fr.js"></script>
<script type="module" src="./js/utils/flatpickr.js"></script>
<script type="module" src="./js/utils/fr.js"></script>
<script type="module" defer src="./js/logs.js"></script>
<script type="module" defer src="./js/datepicker/datepicker.js"></script>
<script type="module" src="./js/logs.js"></script>
<script type="module" src="./js/datepicker/datepicker.js"></script>
<link
rel="stylesheet"
type="text/css"
href="./css/datepicker-foundation.css"
/>
{% elif current_endpoint == "jobs" %}
<script defer type="module" src="./js/jobs.js"></script>
<script type="module" src="./js/jobs.js"></script>
{% endif %}
</head>

View File

@ -11,7 +11,7 @@
<nav>
<!-- breadcrumb -->
<h6 class="mb-0 text-lg font-bold text-white capitalize">
{{ current_endpoint}}
{{current_endpoint}}
</h6>
<ol class="flex flex-wrap pt-1 mr-12 bg-transparent rounded-lg sm:mr-16">
<li class="text-sm leading-normal">
@ -23,7 +23,7 @@
class="text-sm pl-2 capitalize leading-normal text-white before:float-left before:pr-2 before:text-white before:content-['/']"
aria-current="page"
>
{{ current_endpoint}}
{{current_endpoint}}
</li>
</ol>
</nav>

View File

@ -10,7 +10,6 @@
instances_batched %}
<!-- instance card -->
<div
href="https://github.com/bunkerity/bunkerweb"
class="overflow-hidden max-h-none sm:max-h- hover:scale-102 transition col-span-12 lg:col-span-6 3xl:col-span-4 flex p-4 justify-between w-full shadow-md break-words bg-white dark:bg-slate-850 dark:brightness-110 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<form class="w-full" id="form-instance-{{ instance._id }}" method="POST">
@ -43,7 +42,7 @@ instances_batched %}
<p
class="transition duration-300 ease-in-out pl-2 col-span-1 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-80"
>
{{ instance._type}}
{{ instance._type }}
</p>
</div>
<!-- end detail -->
@ -57,7 +56,7 @@ instances_batched %}
<p
class="transition duration-300 ease-in-out pl-2 col-span-1 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-90"
>
{{ instance.hostname}}
{{ instance.hostname }}
</p>
</div>
<!-- end detail -->

View File

@ -34,7 +34,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
<!-- filter -->
<div
{{current_endpoint}}-filter
data-{{current_endpoint}}-filter
class="col-span-12 md:col-span-8 2xl:col-span-6 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<h5 class="mb-2 font-bold dark:text-white">FILTER</h5>
@ -66,19 +66,19 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
Success state
</h5>
<button
{{current_endpoint}}-setting-select="success"
data-{{current_endpoint}}-setting-select="success"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
id="{{current_endpoint}}-success"
name="{{current_endpoint}}-success"
{{current_endpoint}}-setting-select-text="success"
data-name="{{current_endpoint}}-success"
data-{{current_endpoint}}-setting-select-text="success"
>all</span
>
<!-- chevron -->
<svg
{{current_endpoint}}-setting-select="success"
data-{{current_endpoint}}-setting-select="success"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -91,11 +91,11 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
<!-- end chevron -->
<!-- dropdown-->
<div
{{current_endpoint}}-setting-select-dropdown="success"
data-{{current_endpoint}}-setting-select-dropdown="success"
class="hidden z-100 absolute h-full flex-col w-full translate-y-16"
>
<button
{{current_endpoint}}-setting-select-dropdown-btn="success"
data-{{current_endpoint}}-setting-select-dropdown-btn="success"
type="button"
value="all"
class="border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 dark:bg-primary bg-primary text-gray-300"
@ -103,7 +103,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
all
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="success"
data-{{current_endpoint}}-setting-select-dropdown-btn="success"
type="button"
value="false"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -111,7 +111,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
false
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="success"
data-{{current_endpoint}}-setting-select-dropdown-btn="success"
type="button"
value="true"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -130,19 +130,19 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
Reload state
</h5>
<button
{{current_endpoint}}-setting-select="reload"
data-{{current_endpoint}}-setting-select="reload"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
id="{{current_endpoint}}-reload"
name="{{current_endpoint}}-reload"
{{current_endpoint}}-setting-select-text="reload"
data-name="{{current_endpoint}}-reload"
data-{{current_endpoint}}-setting-select-text="reload"
>all</span
>
<!-- chevron -->
<svg
{{current_endpoint}}-setting-select="reload"
data-{{current_endpoint}}-setting-select="reload"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -155,11 +155,11 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
<!-- end chevron -->
<!-- dropdown-->
<div
{{current_endpoint}}-setting-select-dropdown="reload"
data-{{current_endpoint}}-setting-select-dropdown="reload"
class="hidden z-100 absolute h-full flex-col w-full translate-y-16"
>
<button
{{current_endpoint}}-setting-select-dropdown-btn="reload"
data-{{current_endpoint}}-setting-select-dropdown-btn="reload"
type="button"
value="all"
class="border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 dark:bg-primary bg-primary text-gray-300"
@ -167,7 +167,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
all
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="reload"
data-{{current_endpoint}}-setting-select-dropdown-btn="reload"
type="button"
value="false"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -175,7 +175,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
false
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="reload"
data-{{current_endpoint}}-setting-select-dropdown-btn="reload"
type="button"
value="true"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -229,7 +229,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
</p>
<!-- end header-->
<!-- list -->
<ul class="col-span-12 w-full" {{current_endpoint}}-list>
<ul class="col-span-12 w-full" data-{{current_endpoint}}-list>
{% for job_name, value in jobs.items() %}
<!-- job item-->
<li
@ -237,26 +237,26 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
>
<p
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-3 m-0 my-1"
{{current_endpoint}}-name
data-{{current_endpoint}}-name
>
{{job_name}}
</p>
<p
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-3 m-0 my-1"
{{current_endpoint}}-last_run
data-{{current_endpoint}}-last_run
>
{{value['last_run']}}
</p>
<p
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
{{current_endpoint}}-every
data-{{current_endpoint}}-every
>
{{value["every"]}}
</p>
{% if value["reload"] %}
<p
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
{{current_endpoint}}-reload="true"
data-{{current_endpoint}}-reload="true"
>
<svg
class="fill-green-500 h-5 w-5"
@ -272,7 +272,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
{%endif %} {% if not value["reload"] %}
<p
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
{{current_endpoint}}-reload="false"
data-{{current_endpoint}}-reload="false"
>
<svg
class="fill-red-500 h-5 w-5"
@ -287,7 +287,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
{% endif %} {% if value["success"] %}
<p
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
{{current_endpoint}}-success="true"
data-{{current_endpoint}}-success="true"
>
<svg
class="fill-green-500 h-5 w-5"
@ -302,7 +302,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
{% elif not value["success"] %}
<p
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
{{current_endpoint}}-success="false"
data-{{current_endpoint}}-success="false"
>
<svg
class="fill-red-500 h-5 w-5"
@ -317,23 +317,23 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
{% endif %}
<div
class="relative dark:text-gray-400 text-sm col-span-3 m-0 my-1"
{{current_endpoint}}-files
data-{{current_endpoint}}-files
>
{% if value['cache']%}
<button
{{current_endpoint}}-setting-select="{{job_name}}"
data-{{current_endpoint}}-setting-select="{{job_name}}"
type="button"
class="py-1 text-sm disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left leading-6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
id="{{current_endpoint}}-{{job_name}}"
name="{{current_endpoint}}-{{job_name}}"
{{current_endpoint}}-setting-select-text="{{job_name}}"
data-name="{{current_endpoint}}-{{job_name}}"
data-{{current_endpoint}}-setting-select-text="{{job_name}}"
>files</span
>
<!-- chevron -->
<svg
{{current_endpoint}}-setting-select="{{job_name}}"
data-{{current_endpoint}}-setting-select="{{job_name}}"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -346,19 +346,19 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
<!-- end chevron -->
<!-- dropdown-->
<div
{{current_endpoint}}-setting-select-dropdown="{{job_name}}"
data-{{current_endpoint}}-setting-select-dropdown="{{job_name}}"
class="hidden z-100 absolute h-full flex-col w-full translate-y-0.5"
>
{% for file in value['cache'] %}
<button
{{current_endpoint}}-download="{{job_name}}"
{{current_endpoint}}-file="{{file['file_name']}}"
{{current_endpoint}}-setting-select-dropdown-btn="{{job_name}}"
data-{{current_endpoint}}-download="{{job_name}}"
data-{{current_endpoint}}-file="{{file['file_name']}}"
data-{{current_endpoint}}-setting-select-dropdown-btn="{{job_name}}"
type="button"
value="list"
class="{% if loop.index == loop.length %}rounded-b-lg {% endif %}{% if loop.first %}rounded-t-lg{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 bg-white dark:bg-slate-700 text-gray-700"
>
<div class="flex justify-start items-center">
<span class="flex justify-start items-center">
<svg
class="h-6 w-6 fill-sky-500"
xmlns="http://www.w3.org/2000/svg"
@ -372,7 +372,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip() %}
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-2"
>{{file['file_name']}}</span
>
</div>
</span>
</button>
{%endfor %}
</div>

View File

@ -17,11 +17,11 @@
</head>
<body>
<div
loader
data-loader
class="fixed z-[10000] transition duration-300 h-screen w-screen bg-primary flex justify-center align-middle items-center"
>
<img
loader-img
data-loader-img
src="images/logo-menu-2.png"
class="duration-300 w-40 h-12 sm:w-50 sm:h-14 md:w-60 md:h-16 lg:w-80 lg:h-24 inline transition-all"
alt="main logo"
@ -32,11 +32,11 @@
<!-- flash message-->
{% for category, message in messages %}
<div
flash-message
data-flash-message
class="p-4 mb-1 md:mb-3 md:mr-3 z-[1001] flex flex-col fixed bottom-0 right-0 w-full md:w-1/2 max-w-[300px] min-h-20 bg-white rounded-lg dark:brightness-110 hover:scale-102 transition shadow-md break-words dark:bg-slate-850 dark:shadow-dark-xl bg-clip-border"
>
<button
close-flash-message
data-close-flash-message
role="close alert message"
type="button"
class="absolute right-7 top-1.5"
@ -164,9 +164,9 @@
<script>
class Loader {
constructor() {
this.menuContainer = document.querySelector("[menu-container]");
this.logoContainer = document.querySelector("[loader]");
this.logoEl = document.querySelector("[loader-img]");
this.menuContainer = document.querySelector("[data-menu-container]");
this.logoContainer = document.querySelector("[data-loader]");
this.logoEl = document.querySelector("[data-loader-img]");
this.isLoading = true;
this.init();
}
@ -209,7 +209,7 @@
init() {
window.addEventListener("DOMContentLoaded", () => {
try {
const flashEl = document.querySelector("[flash-message]");
const flashEl = document.querySelector("[data-flash-message]");
setTimeout(() => {
try {
flashEl.remove();
@ -221,10 +221,10 @@
window.addEventListener("click", (e) => {
try {
if (
e.target.closest("button").hasAttribute("close-flash-message")
e.target.closest("button").hasAttribute("data-close-flash-message")
) {
const closeBtn = e.target.closest("button");
const flashEl = closeBtn.closest("[flash-message]");
const flashEl = closeBtn.closest("[data-flash-message]");
flashEl.remove();
}
} catch (err) {}

View File

@ -3,7 +3,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- settings -->
<div
{{current_endpoint}}-settings
data-{{current_endpoint}}-settings
class="col-span-12 lg:col-span-8 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<h5 class="mb-2 font-bold dark:text-white">SETTINGS</h5>
@ -18,14 +18,14 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
Select instance
</h5>
<button
{{current_endpoint}}-setting-select="instances"
data-{{current_endpoint}}-setting-select="instances"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
id="logs-instance"
name="logs-instance"
{{current_endpoint}}-setting-select-text="instances"
data-name="logs-instance"
data-{{current_endpoint}}-setting-select-text="instances"
>
{% for instance in instances %} {% if loop.first %} {% if
instance.name %} {{instance.name}} {%else%} no instance {%endif%}
@ -33,7 +33,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
</span>
<!-- chevron -->
<svg
{{current_endpoint}}-setting-select="instances"
data-{{current_endpoint}}-setting-select="instances"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -46,15 +46,15 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- end chevron -->
<!-- dropdown-->
<div
{{current_endpoint}}-setting-select-dropdown="instances"
data-{{current_endpoint}}-setting-select-dropdown="instances"
class="hidden z-100 absolute h-full flex-col w-full translate-y-16"
>
{% for instance in instances %}
<button
{{current_endpoint}}-setting-select-dropdown-btn="instances"
data-{{current_endpoint}}-setting-select-dropdown-btn="instances"
type="button"
value="{{instance.name}}"
_type="{{instance._type}}"
data-_type="{{instance._type}}"
class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
>
{{instance.name}}
@ -120,7 +120,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
name="update-delay"
class="disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700 col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
placeholder="2"
pattern="(.*?)"
data-pattern="(.*?)"
required
/>
</div>
@ -134,26 +134,26 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
>
Live update
</h5>
<div checkbox-handler="live-update" class="relative mb-7 md:mb-0">
<div data-checkbox-handler="live-update" class="relative mb-7 md:mb-0">
<input
id="live-update"
name="live-update"
default-method="default"
default-value="no"
data-default-method="default"
data-default-value="no"
class="relative cursor-pointer disabled:cursor-default disabled:pointer-events-none dark:border-slate-600 dark:bg-slate-700 z-10 checked:z-0 w-5 h-5 ease text-base rounded-1.4 checked:bg-primary checked:border-primary dark:checked:bg-primary dark:checked:border-primary duration-250 float-left mt-1 appearance-none border border-gray-300 bg-white bg-contain bg-center bg-no-repeat align-top transition-all disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 disabled:text-gray-700 dark:disabled:text-gray-300"
type="checkbox"
pattern="^(yes|no)$"
data-pattern="^(yes|no)$"
value="no"
/>
<input
type="hidden"
name="live-update"
default-method="default"
default-value="no"
data-default-method="default"
data-default-value="no"
value="no"
/>
<svg
checkbox-handler="live-update"
data-checkbox-handler="live-update"
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -181,7 +181,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- filter -->
<div
{{current_endpoint}}-filter
data-{{current_endpoint}}-filter
class="col-span-12 lg:col-span-4 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<h5 class="mb-2 font-bold dark:text-white">FILTERS</h5>
@ -212,19 +212,19 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
Select types
</h5>
<button
{{current_endpoint}}-setting-select="types"
data-{{current_endpoint}}-setting-select="types"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
id="logs-types"
name="logs-types"
{{current_endpoint}}-setting-select-text="types"
data-name="logs-types"
data-{{current_endpoint}}-setting-select-text="types"
>all</span
>
<!-- chevron -->
<svg
{{current_endpoint}}-setting-select="types"
data-{{current_endpoint}}-setting-select="types"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -237,11 +237,11 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- end chevron -->
<!-- dropdown-->
<div
{{current_endpoint}}-setting-select-dropdown="types"
data-{{current_endpoint}}-setting-select-dropdown="types"
class="hidden z-100 absolute h-full flex-col w-full translate-y-16"
>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="all"
class="border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 dark:bg-primary bg-primary text-gray-300"
@ -249,7 +249,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
all
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="message"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -257,7 +257,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
message
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="error"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -265,7 +265,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
error
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="warn"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -273,7 +273,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
warn
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="info"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -281,7 +281,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
info
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="misc"
class="rounded-b border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -317,7 +317,7 @@ url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- list -->
<ul
class="col-span-12 w-full max-h-100 overflow-y-auto"
{{current_endpoint}}-list
data-{{current_endpoint}}-list
></ul>
<!-- end list-->
</div>

View File

@ -4,7 +4,7 @@
<!-- float button-->
<button
type="button"
sidebar-menu-toggle
data-sidebar-menu-toggle
class="scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 xl:hidden fixed p-3 text-xl bg-white shadow-sm cursor-pointer top-2 sm:top-3 right-5 sm:right-6 z-990 rounded-circle text-slate-700"
>
<svg
@ -22,13 +22,13 @@
<!-- left sidebar -->
<aside
sidebar-menu
data-sidebar-menu
class="fixed flex inset-y-0 flex-wrap justify-between w-full p-0 my-4 overflow-y-auto antialiased transition-transform duration-200 -translate-x-full bg-white border-0 shadow-xl dark:shadow-none dark:bg-slate-850 dark:brightness-110 max-w-64 z-[1000] xl:ml-6 rounded-2xl xl:left-0 xl:translate-x-0"
aria-expanded="false"
>
<!-- close btn-->
<svg
sidebar-menu-close
data-sidebar-menu-close
class="sm:hidden cursor-pointer fill-gray-600 dark:fill-gray-300 dark:opacity-80 absolute h-6 w-6 top-4 right-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512"
@ -435,7 +435,7 @@
value="{{ csrf_token() }}"
/>
<input {% if dark_mode == True %}checked{% endif %} id="darkMode"
dark-toggle class="dark:brightness-125 hover:brightness-75 rounded-10
data-dark-toggle class="dark:brightness-125 hover:brightness-75 rounded-10
duration-300 ease-in-out after:rounded-circle after:shadow-2xl
after:duration-300 checked:after:translate-x-5.3 h-5 mt-0.5 relative
float-left w-10 cursor-pointer appearance-none border border-solid
@ -446,7 +446,7 @@
checked:bg-right" type="checkbox" />
<label
for="darkMode"
dark-toggle-label
data-dark-toggle-label
class="dark:text-white dark:opacity-80 transition inline-block pl-3 mb-0 ml-0 font-normal cursor-pointer select-none text-sm text-slate-700"
>
{% if dark_mode == True %}dark mode{% else %} light mode{% endif %}

View File

@ -1,7 +1,7 @@
<!-- float button-->
<button
type="button"
sidebar-info-open
data-sidebar-info-open
class="scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 fixed p-3 text-xl bg-white shadow-sm cursor-pointer top-16 sm:top-3 right-5 sm:right-40 xl:right-6 z-990 rounded-circle text-slate-700"
>
<svg
@ -18,12 +18,12 @@
<!-- right sidebar -->
<aside
sidebar-info
data-sidebar-info
class="translate-x-90 -right-0 transition z-sticky dark:bg-slate-850 dark:brightness-110 shadow-3xl max-w-full w-90 ease fixed top-0 left-auto flex h-full min-w-0 flex-col break-words rounded-none border-0 bg-white bg-clip-border px-0.5"
>
<!-- close btn-->
<svg
sidebar-info-close
data-sidebar-info-close
class="cursor-pointer fill-gray-600 dark:fill-gray-300 dark:opacity-80 absolute h-8 w-8 top-4 right-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512"
@ -43,7 +43,7 @@
<!-- close button -->
<div class="float-right mt-6">
<button
sidebar-info-close
data-sidebar-info-close
class="inline-block p-0 mb-4 text-sm font-bold leading-normal text-center uppercase align-middle transition-all ease-in bg-transparent border-0 rounded-lg shadow-none cursor-pointer hover:-translate-y-px tracking-tight-rem bg-150 bg-x-25 active:opacity-85 dark:text-white text-slate-700"
>
<i class="fa fa-close"></i>
@ -56,7 +56,7 @@
/>
<!-- end header -->
<!-- news-->
<div news-container class="flex-auto overflow-auto">
<div data-news-container class="flex-auto overflow-auto">
<p
class="text-center col-span-12 relative w-full p-4 text-blue-500 rounded-lg"
>
@ -90,16 +90,16 @@
</div>
<div class="block mt-2 mb-4">
<div class="relative">
<div checkbox-handler="newsletter-check" class="relative mb-7 md:mb-0">
<div data-checkbox-handler="newsletter-check" class="relative mb-7 md:mb-0">
<input
id="newsletter-check"
class="mr-2 relative cursor-pointer dark:border-slate-600 dark:bg-slate-700 z-10 checked:z-0 w-5 h-5 ease text-base rounded-1.4 checked:bg-primary checked:border-primary dark:checked:bg-primary dark:checked:border-primary duration-250 float-left mt-1 appearance-none border border-gray-300 bg-white bg-contain bg-center bg-no-repeat align-top transition-all disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 disabled:text-gray-700 dark:disabled:text-gray-300"
type="checkbox"
pattern="^(yes|no)$"
data-pattern="^(yes|no)$"
value="no"
/>
<svg
checkbox-handler="newsletter-check"
data-checkbox-handler="newsletter-check"
class="pointer-events-none cursor-pointer absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -115,7 +115,7 @@
<a
class="italic"
href="https://www.bunkerity.com/privacy-policy/"
_target="_blank"
target="_blank"
>privacy policy</a
>
</label>

View File

@ -1,6 +1,6 @@
{% extends "base.html" %} {% block content %}{% set current_endpoint =
url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %} {%
include "plugins-modal.html" %}
include "plugins_modal.html" %}
<!-- info -->
<div
@ -60,7 +60,7 @@ include "plugins-modal.html" %}
<!-- upload layout -->
<div
{{current_endpoint}}-upload
data-{{current_endpoint}}-upload
class="p-4 col-span-12 md:col-span-7 2xl:col-span-4 grid grid-cols-12 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<h5 class="col-span-12 mb-4 font-bold dark:text-white">UPLOAD / RELOAD</h5>
@ -74,7 +74,6 @@ include "plugins-modal.html" %}
>
<input
type="hidden"
id="csrf_token"
name="csrf_token"
value="{{ csrf_token() }}"
/>
@ -90,8 +89,8 @@ include "plugins-modal.html" %}
click or drag and drop
</p>
</form>
<section class="col-span-12 progress-area"></section>
<section class="col-span-12 uploaded-area"></section>
<div class="col-span-12 progress-area"></div>
<div class="col-span-12 uploaded-area"></div>
<!-- end dropzone -->
<div class="col-span-12 flex flex-col justify-center items-center mt-2">
@ -102,7 +101,7 @@ include "plugins-modal.html" %}
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<button
plugin-reload-btn
data-plugin-reload-btn
disabled
type="submit"
class="disabled:hover:translate-y-0 disabled:cursor-not-allowed disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 tracking-wide dark:brightness-125 hover:brightness-75 w-full inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-gradient-to-tl bg-primary leading-normal text-xs ease-in shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
@ -117,7 +116,7 @@ include "plugins-modal.html" %}
<!-- filter -->
<div
{{current_endpoint}}-filter
data-{{current_endpoint}}-filter
class="p-4 col-span-12 2xl:col-span-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<h5 class="mb-2 font-bold dark:text-white">FILTER</h5>
@ -148,19 +147,19 @@ include "plugins-modal.html" %}
Select types
</h5>
<button
{{current_endpoint}}-setting-select="types"
data-{{current_endpoint}}-setting-select="types"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
id="types"
name="types"
{{current_endpoint}}-setting-select-text="types"
data-name="types"
data-{{current_endpoint}}-setting-select-text="types"
>all</span
>
<!-- chevron -->
<svg
{{current_endpoint}}-setting-select="types"
data-{{current_endpoint}}-setting-select="types"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -173,11 +172,11 @@ include "plugins-modal.html" %}
<!-- end chevron -->
<!-- dropdown-->
<div
{{current_endpoint}}-setting-select-dropdown="types"
data-{{current_endpoint}}-setting-select-dropdown="types"
class="hidden z-100 absolute h-full flex-col w-full translate-y-16"
>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="all"
class="border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 dark:bg-primary bg-primary text-gray-300"
@ -185,7 +184,7 @@ include "plugins-modal.html" %}
all
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="internal"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -193,7 +192,7 @@ include "plugins-modal.html" %}
internal
</button>
<button
{{current_endpoint}}-setting-select-dropdown-btn="types"
data-{{current_endpoint}}-setting-select-dropdown-btn="types"
type="button"
value="external"
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
@ -213,14 +212,14 @@ include "plugins-modal.html" %}
>
<h5 class="mb-4 mt-2 font-bold dark:text-white mx-2">LIST</h5>
<div {{current_endpoint}}-list class="grid grid-cols-12 gap-3">
<div data-{{current_endpoint}}-list class="grid grid-cols-12 gap-3">
{% for plugin in plugins %} {% if plugin['external'] %}
<div
{{current_endpoint}}-external="{% if plugin['external'] %} external {% else %} internal {% endif %}"
data-{{current_endpoint}}-external="{% if plugin['external'] %} external {% else %} internal {% endif %}"
class="py-3 min-h-12 relative col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 p-1 flex justify-between items-center transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800"
>
<p
{{current_endpoint}}-content
data-{{current_endpoint}}-content
class="ml-3 mr-2 mb-0 transition duration-300 ease-in-out dark:opacity-90 text-left text-sm md:text-base text-slate-700 dark:text-gray-200"
>
{{plugin['name']}}
@ -243,7 +242,7 @@ include "plugins-modal.html" %}
</a>
{%endif%}
<button
{{current_endpoint}}-action="delete"
data-{{current_endpoint}}-action="delete"
name="{{plugin['id']}}"
type="button"
class="z-20 mx-2 inline-block font-bold text-left text-white uppercase align-middle transition-all cursor-pointer text-xs ease-in tracking-tight-rem hover:-translate-y-px"
@ -262,11 +261,11 @@ include "plugins-modal.html" %}
</div>
{% else %}
<div
{{current_endpoint}}-external="{% if plugin['external'] %} external {%else%} internal {%endif%}"
data-{{current_endpoint}}-external="{% if plugin['external'] %} external {%else%} internal {%endif%}"
class="py-3 min-h-12 relative col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 p-1 flex justify-between items-center transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800"
>
<p
{{current_endpoint}}-content
data-{{current_endpoint}}-content
class="ml-3 mb-0 transition duration-300 ease-in-out dark:opacity-90 text-left text-sm md:text-base text-slate-700 dark:text-gray-200"
>
{{plugin['name']}}

View File

@ -1,20 +1,20 @@
<!-- modal -->
<div
plugins-modal
data-plugins-modal
class="dark:brightness-110 w-screen h-screen fixed bg-gray-600/50 z-[1001] top-0 left-0 hidden justify-center items-center"
>
<div
plugins-modal-card
data-plugins-modal-card
class="min-w-[500px ]overflow-y-auto mx-3 ml-2 mr-6 sm:mx-6 lg:mx-8 my-3 px-4 pt-4 pb-8 w-full max-w-[400px] flex flex-col break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<div class="w-full flex justify-between mb-2">
<p
plugins-modal-title
data-plugins-modal-title
class="transition duration-300 ease-in-out dark:opacity-90 dark:text-gray-300 mb-2 font-sans font-semibold leading-normal uppercase text-md"
>
DELETE PLUGINS
</p>
<button class="-translate-y-1" type="button" plugins-modal-close>
<button class="-translate-y-1" type="button" data-plugins-modal-close>
<svg
class="transition duration-300 ease-in-out dark:opacity-90 h-6 w-6 sm:h-7 sm:w-7 fill-slate-800 dark:fill-gray-300"
xmlns="http://www.w3.org/2000/svg"
@ -28,7 +28,7 @@
</div>
<!-- delete form-->
<form
plugins-modal-form-delete
data-plugins-modal-form-delete
class="w-full h-full flex flex-col justify-between"
id="form-delete-plugin"
method="POST"
@ -39,14 +39,14 @@
<input type="hidden" value="delete" name="operation" id="operation" />
<div>
<p
plugins-modal-text
data-plugins-modal-text
class="text-center mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm"
></p>
</div>
<!-- action button -->
<div class="w-full justify-center flex mt-10">
<button
plugins-modal-close
data-plugins-modal-close
type="button"
class="dark:brightness-90 mr-3 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>

View File

@ -4,8 +4,8 @@
class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border"
>
<button
services-action="new"
services-name="service"
data-services-action="new"
data-services-name="service"
type="button"
class="dark:bg-green-500/90 duration-300 dark:opacity-90 w-80 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-base ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>
@ -28,10 +28,10 @@
{% else %}{% for services_batched in services|batch(3) %} {% for service in
services_batched %} {% set id_server_name =
service["SERVER_NAME"]['value'].replace(".", "-") %}
<div services-service
<div data-services-service
class="dark:brightness-110 overflow-hidden hover:scale-102 transition col-span-12 lg:col-span-6 3xl:col-span-4 p-4 w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<div services-settings class="hidden" value="{{service['settings']}}"></div>
<div data-services-settings class="hidden" data-value="{{service['settings']}}"></div>
<h5 class="transition duration-300 ease-in-out dark:opacity-90 text-center sm:text-left mb-1 font-bold dark:text-white">
{{ service["SERVER_NAME"]['value'] }}
</h5>
@ -339,9 +339,9 @@
<button
services-action="edit"
data-services-action="edit"
type="button"
services-name="{{service["SERVER_NAME"]['value']}}"
data-services-name="{{service["SERVER_NAME"]['value']}}"
class="dark:brightness-90 z-20 mx-1 bg-blue-500 hover:bg-blue-500/80 focus:bg-yellow-500/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md"
>
@ -354,9 +354,9 @@
{% if service["SERVER_NAME"]['method'] == "ui" %}
<button
services-action="delete"
data-services-action="delete"
type="button"
services-name="{{service["SERVER_NAME"]['value']}}"
data-services-name="{{service["SERVER_NAME"]['value']}}"
class="dark:brightness-90 z-20 mx-1 bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md"
>
<svg
@ -379,5 +379,5 @@
<!-- end services container-->
<!-- modal -->
{% include "services-modal.html" %}
{% include "services_modal.html" %}
{% endblock %}

View File

@ -1,21 +1,21 @@
<!-- modal -->
<div
service-content="settings"
services-modal
data-service-content="settings"
data-services-modal
class="dark:brightness-110 hidden w-screen h-screen fixed bg-gray-600/50 z-[1001] top-0 left-0 justify-center items-center"
>
<div
services-modal-card
data-services-modal-card
class="overflow-y-auto mx-3 ml-2 mr-6 sm:mx-6 lg:mx-8 my-3 px-4 pt-4 pb-8 w-full min-w-[500px] h-[90vh] flex flex-col break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<div class="w-full flex justify-between mb-2">
<p
services-modal-title
data-services-modal-title
class="transition duration-300 ease-in-out dark:opacity-90 dark:text-gray-200 mb-2 font-sans font-semibold leading-normal uppercase text-md"
>
SERVICE MODAL
</p>
<button class="-translate-y-1" type="button" services-modal-close>
<button class="-translate-y-1" type="button" data-services-modal-close>
<svg
class="transition duration-300 ease-in-out dark:opacity-90 h-6 w-6 sm:h-7 sm:w-7 fill-slate-800 dark:fill-gray-300"
xmlns="http://www.w3.org/2000/svg"
@ -28,7 +28,7 @@
</button>
</div>
<div
services-tabs-header
data-services-tabs-header
class="flex justify-start items-center gap-x-4 gap-y-2 my-3"
>
<h5
@ -55,7 +55,7 @@
{% include "settings_tabs.html" %}
<!-- new and edit form -->
<form
services-modal-form
data-services-modal-form
class="w-full h-full flex flex-col justify-between"
id="form-new"
method="POST"
@ -69,14 +69,14 @@
<!-- action button -->
<div class="w-full justify-center flex mt-10">
<button
services-modal-close
data-services-modal-close
type="button"
class="dark:brightness-90 mb-4 mr-3 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>
Close
</button>
<button
services-modal-submit
data-services-modal-submit
type="submit"
class="dark:brightness-90 mb-4 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>
@ -88,7 +88,7 @@
<!-- end new and edit form -->
<!-- delete form-->
<form
services-modal-form-delete
data-services-modal-form-delete
class="w-full h-full flex flex-col justify-between"
id="form-delete-server_name"
method="POST"
@ -99,14 +99,14 @@
<div class="flex justify-center">
<p
services-modal-text
data-services-modal-text
class="mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm"
></p>
</div>
<!-- action button -->
<div class="w-full justify-center flex mt-10">
<button
services-modal-close
data-services-modal-close
type="button"
class="dark:brightness-90 mr-3 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md"
>

View File

@ -6,12 +6,12 @@
{% for plugin in plugins %}
<div
plugin-item="{{plugin['id']}}"
data-plugin-item="{{plugin['id']}}"
id="{{plugin['id']}}"
class="{% if loop.index != 1 %}hidden{%endif%} w-full"
>
<!-- title and desc -->
<div class="col-span-12" setting-header>
<div class="col-span-12" data-setting-header>
<h5
class="transition duration-300 ease-in-out dark:opacity-90 ml-2 font-bold text-md uppercase dark:text-white mb-0"
>
@ -24,14 +24,13 @@
</div>
</div>
<!-- end title and desc -->
<div plugin-settings class="w-full grid grid-cols-12">
<div data-plugin-settings class="w-full grid grid-cols-12">
<!-- plugin settings not multiple -->
{% for setting, value in plugin["settings"].items() %}{% if setting != "IS_LOADING" and current_endpoint
== "global-config" and value['context'] == "global" and not value['multiple'] or current_endpoint ==
"services" and value['context'] == "multisite" and not value['multiple'] %}
<div setting-container
class="
mx-0 sm:mx-4 my-2 col-span-12 md:mx-6 md:my-3 md:col-span-6 2xl:mx-6 2xl:my-3 2xl:col-span-4"
<div data-setting-container
class="mx-0 sm:mx-4 my-2 col-span-12 md:mx-6 md:my-3 md:col-span-6 2xl:mx-6 2xl:my-3 2xl:col-span-4"
id="form-edit-{{current_endpoint}}-{{ value["id"] }}">
<!-- title and info -->
<div class="flex items-center my-1 relative">
@ -41,7 +40,7 @@
{{value["label"]}}
</h5>
<svg
popover-btn="{{ value["label"] }}"
data-popover-btn="{{ value["label"] }}"
class="cursor-pointer fill-blue-500 h-5 w-5 ml-2 hover:brightness-75"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -52,7 +51,7 @@
</svg>
<!-- popover -->
<div class="hidden transition z-50 rounded-md p-3 left-0 -translate-y-7 bottom-0 absolute bg-blue-500"
popover-content="{{ value["label"] }}"
data-popover-content="{{ value["label"] }}"
>
<p class="transition duration-300 ease-in-out dark:opacity-90 font-bold text-sm text-white m-0" >{{value['help']}}
</p>
@ -66,17 +65,17 @@
<div class="relative flex items-center">
<input
{% if setting == "SERVER_NAME" %}required{%endif%}
default-value="{{global_config[setting]['value']}}" default-method="{{global_config[setting]['method']}}"
data-default-value="{{global_config[setting]['value']}}" data-default-method="{{global_config[setting]['method']}}"
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %} id="{{setting}}" name="{{setting}}"
class="outline-none dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:border-gray-300/0 focus:ring-1 focus:valid:ring-green-500 focus:invalid:ring-red-500 text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700"
value="{% if global_config[setting]['value'] %} {{global_config[setting]['value']}} {% else %} {{value['default']}} {% endif %}" type="{{value['type']}}" pattern="{{value['regex']|safe}}" />
{% if value['type'] == "password" %}
<div setting-password-container class="absolute flex right-2 h-5 w-5">
<button type="button" setting-password="visible" class="h-5 w-5 flex items-center align-middle" type="button">
<div data-setting-password-container class="absolute flex right-2 h-5 w-5">
<button type="button" data-setting-password="visible" class="h-5 w-5 flex items-center align-middle" type="button">
<svg class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg>
</button>
<button type="button" setting-password="invisible" class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
<button type="button" data-setting-password="invisible" class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
<svg class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg>
</button>
</div>
@ -89,8 +88,8 @@
<!-- select -->
{% if value["type"] == "select" %}
<!-- default hidden-->
<select default-method="{{global_config[setting]['method']}}" default-value="{{value['default']}}"
id="{{setting}}" name="{{setting}}" setting-select-default="{{value['id']}}" type="form-select" id="{{setting}}" name="{{setting}}"
<select data-default-method="{{global_config[setting]['method']}}" data-default-value="{{value['default']}}"
id="{{setting}}" name="{{setting}}" data-setting-select-default="{{value['id']}}" data-type="form-select" id="{{setting}}" name="{{setting}}"
class="hidden">
{% for item in value['select'] %}
<option value="{{item}}" {% if global_config[setting]['value'] and global_config[setting]['value'] == item or not global_config[setting]['value'] and value['default'] == item %} selected{% endif %}>{{item}}</option>
@ -99,30 +98,30 @@
<!-- end default hidden-->
<!--custom-->
<div select-container class="relative">
<div data-select-container class="relative">
<button
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %} setting-select="{{value['id']}}"
default-value="{{global_config[setting]['value']}}"
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %} data-setting-select="{{value['id']}}"
data-default-value="{{global_config[setting]['value']}}"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-primary flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
{% for item in value['select'] %} {% if global_config[setting]['value'] and
global_config[setting]['value'] == item %}
<span
setting-select-text="{{value['id']}}"
value="{{global_config[setting]['value']}}"
data-setting-select-text="{{value['id']}}"
data-value="{{global_config[setting]['value']}}"
>{{global_config[setting]['value']}}</span
>
{% elif not global_config[setting]['value'] and value['default'] == item %}
<span
setting-select-text="{{value['id']}}"
value="{{value['default']}}"
data-setting-select-text="{{value['id']}}"
data-value="{{value['default']}}"
>{{value['default']}}</span
>
{% endif %} {% endfor %}
<!-- chevron -->
<svg
setting-select="{{value['id']}}"
data-setting-select="{{value['id']}}"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -135,7 +134,7 @@
</button>
<!-- dropdown-->
<div
setting-select-dropdown="{{value['id']}}"
data-setting-select-dropdown="{{value['id']}}"
class="hidden z-[20] absolute h-full flex-col w-full mt-2"
>
{% for item in value['select'] %} {% if global_config[setting]['value'] and
@ -144,7 +143,7 @@
<button
type="button"
value="{{item}}"
setting-select-dropdown-btn="{{value['id']}}"
data-setting-select-dropdown-btn="{{value['id']}}"
type="button"
class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 hover:brightness-90 bg-primary text-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
>
@ -154,7 +153,7 @@
<button
type="button"
value="{{item}}"
setting-select-dropdown-btn="{{value['id']}}"
data-setting-select-dropdown-btn="{{value['id']}}"
type="button"
class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 hover:brightness-90 bg-white text-gray-700 my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
>
@ -169,10 +168,10 @@
<!-- checkbox -->
{% if value["type"] == "check" %}
<div checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<div data-checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<input id="{{setting}}" name="{{setting}}"
default-method="{{global_config[setting]['method']}}"
default-value="{{global_config[setting]['value']}}" {% if
data-default-method="{{global_config[setting]['method']}}"
data-default-value="{{global_config[setting]['value']}}" {% if
setting in ["AUTOCONF_MODE", "SWARM_MODE", "KUBERNETES_MODE"] or global_config[setting]['method'] != 'ui' and global_config[setting]['method']
!= 'default' %} disabled {% endif %} {% if global_config[setting]['value'] and
global_config[setting]['value'] == 'yes' or not
@ -185,17 +184,17 @@
bg-no-repeat align-top transition-all disabled:bg-gray-400
disabled:border-gray-400 dark:disabled:bg-gray-800
dark:disabled:border-gray-800 disabled:text-gray-700
dark:disabled:text-gray-300" type="checkbox" pattern="{{value['regex']|safe}}"
dark:disabled:text-gray-300" type="checkbox" data-pattern="{{value['regex']|safe}}"
value="{% if global_config[setting]['value'] %}
{{global_config[setting]['value']}} {% else %} {{value['default']}} {% endif
%}" />
<input type="hidden" name="{{setting}}" value="{% if
setting in ["AUTOCONF_MODE", "SWARM_MODE", "KUBERNETES_MODE"] or global_config[setting]['method'] != 'ui' and global_config[setting]['method']
!= 'default' %}{{global_config[setting]['value']}}{% else %}no{% endif %}" default-value="{% if
!= 'default' %}{{global_config[setting]['value']}}{% else %}no{% endif %}" data-default-value="{% if
setting in ["AUTOCONF_MODE", "SWARM_MODE", "KUBERNETES_MODE"] or global_config[setting]['method'] != 'ui' and global_config[setting]['method']
!= 'default' %}{{global_config[setting]['value']}}{% else %}no{% endif %}" default-method="default" />
!= 'default' %}{{global_config[setting]['value']}}{% else %}no{% endif %}" data-default-method="default" />
<svg
checkbox-handler="{{value['id']}}"
data-checkbox-handler="{{value['id']}}"
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -232,32 +231,32 @@
{%for multiple in multList %}
<!-- plugin multiple handler -->
<div multiple-handler class="flex items-center mx-0 sm:mx-4 md:mx-6 md:my-3 my-2 2xl:mx-6 2xl:my-3 col-span-12 ">
<div data-multiple-handler class="flex items-center mx-0 sm:mx-4 md:mx-6 md:my-3 my-2 2xl:mx-6 2xl:my-3 col-span-12 ">
<h5
class="transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300"
>
{{multiple}}
</h5>
<button {{current_endpoint}}-multiple-add="{{multiple}}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
<button data-{{current_endpoint}}-multiple-add="{{multiple}}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
Add
</button>
<button {{current_endpoint}}-multiple-toggle="{{multiple}}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
<button data-{{current_endpoint}}-multiple-toggle="{{multiple}}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
SHOW / HIDE
</button>
</div>
<!-- end plugin multiple handler-->
<!-- multiple settings -->
<div {{current_endpoint}}-settings-multiple="{{multiple}}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full mb-8 grid-cols-12 border dark:border-gray-700 rounded">
<div data-{{current_endpoint}}-settings-multiple="{{multiple}}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full mb-8 grid-cols-12 border dark:border-gray-700 rounded">
{% for setting, value in plugin["settings"].items() %}
{# render only setting that match the multiple id and context #}
{% if current_endpoint
== "global-config" and value['context'] == "global" and value['multiple'] == multiple or current_endpoint ==
"services" and value['context'] == "multisite" and value['multiple'] == multiple %}
<div setting-container="{{setting}}_SCHEMA"
<div data-setting-container="{{setting}}_SCHEMA"
class="
mx-0 sm:mx-4 my-2 col-span-12 md:mx-6 md:my-3 md:col-span-6 2xl:mx-6 2xl:my-3 2xl:col-span-4"
id="form-edit-{{current_endpoint}}-{{ value["id"] }}">
id="form-edit-{{current_endpoint}}-{{ value["id"] }}_SCHEMA">
<!-- title and info -->
<div class="flex items-center my-1 relative">
<h5
@ -266,7 +265,7 @@
{{value["label"]}}
</h5>
<svg
popover-btn="{{ value["label"] }}"
data-popover-btn="{{ value["label"] }}"
class="cursor-pointer fill-blue-500 h-5 w-5 ml-2 hover:brightness-75"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -277,7 +276,7 @@
</svg>
<!-- popover -->
<div class="hidden transition z-50 rounded-md p-3 left-0 -translate-y-7 bottom-0 absolute bg-blue-500"
popover-content="{{ value["label"] }}"
data-popover-content="{{ value["label"] }}"
>
<p class="transition duration-300 ease-in-out dark:opacity-90 font-bold text-sm text-white m-0" >{{value['help']}}
</p>
@ -290,16 +289,16 @@
{% if value["type"] != "select" and value["type"] != "check" %}
<div class="relative flex items-center">
<input
default-value="{{value['default']}}" default-method="default" id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA"
data-default-value="{{value['default']}}" data-default-method="default" id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA"
class="outline-none dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:border-gray-300/0 focus:ring-1 focus:valid:ring-green-500 focus:invalid:ring-red-500 text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700"
value="{{value['default']}}" type="{{value['type']}}" pattern="{{value['regex']|safe}}" />
{% if value['type'] == "password" %}
<div setting-password-container class="absolute flex right-2 h-5 w-5">
<button type="button" setting-password="visible" class="h-5 w-5 flex items-center align-middle" type="button">
<div data-setting-password-container class="absolute flex right-2 h-5 w-5">
<button type="button"data- setting-password="visible" class="h-5 w-5 flex items-center align-middle" type="button">
<svg class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg>
</button>
<button type="button" setting-password="invisible" class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
<button type="button" data-setting-password="invisible" class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
<svg class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg>
</button>
</div>
@ -311,8 +310,8 @@
<!-- select -->
{% if value["type"] == "select" %}
<!-- default hidden-->
<select default-method="default" default-value="{{value['default']}}"
id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA" select-default="{{value['id']}}" type="form-select" id="{{setting}}" name="{{setting}}"
<select data-default-method="default" data-default-value="{{value['default']}}"
id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA" data-select-default="{{value['id']}}" data-type="form-select" id="{{setting}}" name="{{setting}}"
class="hidden">
{% for item in value['select'] %}
<option value="{{item}}" {% if value['default'] == item %} selected {% endif %}>{{item}}</option>
@ -321,23 +320,23 @@
<!-- end default hidden-->
<!--custom-->
<div select-container class="relative">
<div data-select-container class="relative">
<button
setting-select="{{value['id']}}"
default-value="{{value['default']}}"
data-setting-select="{{value['id']}}"
data-default-value="{{value['default']}}"
type="button"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-primary flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
{% for item in value['select'] %} {% if value['default'] == item %}
<span
setting-select-text="{{value['id']}}"
value="{{value['default']}}"
data-setting-select-text="{{value['id']}}"
data-value="{{value['default']}}"
>{{value['default']}}</span
>
{% endif %} {% endfor %}
<!-- chevron -->
<svg
setting-select="{{value['id']}}"
data-setting-select="{{value['id']}}"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -350,14 +349,14 @@
</button>
<!-- dropdown-->
<div
setting-select-dropdown="{{value['id']}}"
data-setting-select-dropdown="{{value['id']}}"
class="hidden z-[20] absolute h-full flex-col w-full mt-2"
>
{% for item in value['select'] %} {% if value['default'] == item %}
<button
type="button"
value="{{item}}"
setting-select-dropdown-btn="{{value['id']}}"
data-setting-select-dropdown-btn="{{value['id']}}"
type="button"
class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 hover:brightness-90 bg-primary text-white my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
>
@ -367,7 +366,7 @@
<button
type="button"
value="{{item}}"
setting-select-dropdown-btn="{{value['id']}}"
data-setting-select-dropdown-btn="{{value['id']}}"
type="button"
class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 hover:brightness-90 bg-white text-gray-700 my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
>
@ -382,10 +381,10 @@
<!-- checkbox -->
{% if value["type"] == "check" %}
<div checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<div data-checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<input id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA"
default-method="default"
default-value="{{value['default']}}" {% if value['default'] == 'yes' %} checked {%
data-default-method="default"
data-default-value="{{value['default']}}" {% if value['default'] == 'yes' %} checked {%
endif %} id="checkbox-{{value['id']}}" class="relative cursor-pointer disabled:cursor-default disabled:pointer-events-none
dark:border-slate-600 dark:bg-slate-700 z-10 checked:z-0 w-5 h-5 ease
text-base rounded-1.4 checked:bg-primary checked:border-primary
@ -394,11 +393,11 @@
bg-no-repeat align-top transition-all disabled:bg-gray-400
disabled:border-gray-400 dark:disabled:bg-gray-800
dark:disabled:border-gray-800 disabled:text-gray-700
dark:disabled:text-gray-300" type="checkbox" pattern="{{value['regex']|safe}}"
dark:disabled:text-gray-300" type="checkbox" data-pattern="{{value['regex']|safe}}"
value="{{value['default']}}" />
<input type="hidden" name="{{setting}}_SCHEMA" value="no" default-value="no" default-method="default" />
<input type="hidden" name="{{setting}}_SCHEMA" value="no" data-default-value="no" data-default-method="default" />
<svg
checkbox-handler="{{value['id']}}"
data-checkbox-handler="{{value['id']}}"
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -419,8 +418,8 @@
<!--end invalid feedback-->
</div>
{% endif %} {% endfor %}
<div multiple-delete-container class="col-span-12 flex justify-center my-4">
<button {{current_endpoint}}-multiple-delete="{{plugin['name']}}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
<div data-multiple-delete-container class="col-span-12 flex justify-center my-4">
<button data-{{current_endpoint}}-multiple-delete="{{plugin['name']}}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
Remove
</button>
</div>

View File

@ -2,23 +2,23 @@
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-')
%}
{% set plugins = config["CONFIG"].get_plugins() %}
<div {{current_endpoint}}-tabs class="col-span-12 grid grid-cols-12 {% if current_endpoint == 'services' %}mb-4{% endif %}">
<div data-{{current_endpoint}}-tabs class="col-span-12 grid grid-cols-12 {% if current_endpoint == 'services' %}mb-4{% endif %}">
<!-- desktop tabs -->
<div {{current_endpoint}}-tabs-desktop class="hidden md:block col-span-12">
<div role="tablist" data-{{current_endpoint}}-tabs-desktop class="hidden md:block col-span-12">
<!-- tabs -->
{% for plugin in plugins %} {% if current_endpoint == "services" and plugin["settings"]
and check_settings(plugin["settings"], "multisite") or current_endpoint == "global-config" and plugin["settings"]
and check_settings(plugin["settings"], "global") %}
<button
tab-handler="{{ plugin['id'] }}"
<button role="tab"
data-tab-handler="{{ plugin['id'] }}"
type="button"
class="{% if loop.first %} brightness-90 z-[1001]{%else %} {% endif %} border-primary dark:hover:bg-slate-800 dark:border-slate-600 dark:bg-slate-700 border my-1 relative inline-block px-3 py-3 font-bold text-center uppercase align-middle transition-all rounded-none cursor-pointer bg-white hover:bg-gray-100 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md"
>
<div class="w-full flex justify-between items-center">
<span class="w-full flex justify-between items-center">
<!-- text and icon -->
<span class="text-primary transition duration-300 ease-in-out dark:opacity-90 pl-3 pr-2 dark:text-gray-300"> {{ plugin["name"] }} </span>
<svg
popover-btn="{{ plugin["name"] }}"
data-popover-btn="{{ plugin["name"] }}"
class=" fill-blue-500 h-5 w-5 mr-2 hover:brightness-95"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
@ -29,14 +29,14 @@
</svg>
<!-- end text and icon -->
<!-- popover -->
<div
popover-content="{{ plugin["name"] }}"
<span
data-popover-content="{{ plugin["name"] }}"
class="top-[60px] min-w-[150px] dark:brightness-90 bg-blue-500 hidden transition z-50 rounded-md p-3 left-0 absolute"
>
<p class="font-bold text-sm text-white m-0">{{ plugin['description'] }}</p>
</div>
<span class="font-bold text-sm text-white m-0">{{ plugin['description'] }}</span>
</span>
<!-- end popover -->
</div>
</span>
</button>
{% endif %} {% endfor %}
<!--end tabs-->
@ -45,7 +45,7 @@
<!-- mobile tabs -->
<div class="md:hidden relative col-span-12 h-full">
<button
tab-dropdown-btn
data-tab-dropdown-btn
type="button"
class="dark:hover:brightness-95 dark:border-slate-600 dark:bg-slate-700 border-primary border w-full flex items-center justify-between rounded-lg hover:-translate-y-px my-1 px-6 py-3 font-bold text-center uppercase align-middle transition-all cursor-pointer bg-white hover:bg-gray-50 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md"
>
@ -65,7 +65,7 @@
</button>
<!-- dropdown-->
<div
tab-dropdown
data-tab-dropdown
class="hidden z-100 absolute flex-col w-full overflow-hidden overflow-y-auto max-h-90"
>
{% set first_el = "True" %}
@ -75,7 +75,7 @@
{% if loop.first %}
<button
tab-handler-mobile="{{ plugin['id'] }}"
data-tab-handler-mobile="{{ plugin['id'] }}"
type="button"
data-select="false"
id="edit-{{current_endpoint}}-{{ plugin['id'] }}-tab"
@ -84,7 +84,7 @@
</button>
{% else %}
<button
tab-handler-mobile="{{ plugin['id'] }}"
data-tab-handler-mobile="{{ plugin['id'] }}"
type="button"
data-select="false"
id="edit-{{current_endpoint}}-{{ plugin['id'] }}-tab"