Update tsparticles in the UI + remove unused static files
This commit is contained in:
parent
685cb9809d
commit
1c71572f44
|
@ -10,5 +10,9 @@ CONTRIBUTING.md
|
|||
LICENSE.md
|
||||
README.md
|
||||
SECURITY.md
|
||||
src/ui/static
|
||||
examples/*
|
||||
tsparticles.bundle.min.js
|
||||
flatpickr.*
|
||||
src/ui/static/js/editor/*
|
||||
src/ui/templates/*
|
||||
datepicker-foundation.css
|
||||
examples/*
|
||||
|
|
|
@ -2590,15 +2590,34 @@ h6 {
|
|||
}
|
||||
|
||||
.transition {
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
@ -3310,15 +3329,34 @@ h6 {
|
|||
font-size: 0.875rem;
|
||||
line-height: 1.5rem;
|
||||
font-weight: 700;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 300ms;
|
||||
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
|
||||
|
@ -3343,15 +3381,34 @@ h6 {
|
|||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(94 114 228 / var(--tw-bg-opacity));
|
||||
padding: 0.75rem;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
@ -3370,15 +3427,34 @@ h6 {
|
|||
font-weight: 700;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 300ms;
|
||||
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
|
||||
|
@ -3539,15 +3615,34 @@ h6 {
|
|||
padding-right: 0.5rem;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(8 85 119 / var(--tw-text-opacity));
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 300ms;
|
||||
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
|
||||
|
@ -3569,15 +3664,34 @@ h6 {
|
|||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(94 114 228 / var(--tw-bg-opacity));
|
||||
padding: 0.75rem;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
@ -3666,15 +3780,34 @@ h6 {
|
|||
.settings-tabs-mobile-btn-text {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(8 85 119 / var(--tw-text-opacity));
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter;
|
||||
transition-property: color, background-color, border-color,
|
||||
text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
|
||||
backdrop-filter, -webkit-backdrop-filter;
|
||||
transition-property:
|
||||
color,
|
||||
background-color,
|
||||
border-color,
|
||||
text-decoration-color,
|
||||
fill,
|
||||
stroke,
|
||||
opacity,
|
||||
box-shadow,
|
||||
transform,
|
||||
filter,
|
||||
backdrop-filter,
|
||||
-webkit-backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
transition-duration: 300ms;
|
||||
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
.datepicker{display:none}.datepicker.active{display:block}.datepicker-dropdown{left:0;padding-top:4px;position:absolute;top:0;z-index:10}.datepicker-dropdown.datepicker-orient-top{padding-bottom:4px;padding-top:0}.datepicker-picker{background-color:#fefefe;border-radius:0;display:inline-block}.datepicker-dropdown .datepicker-picker{box-shadow:0 0 0 1px #cacaca}.datepicker-picker span{-webkit-touch-callout:none;border:0;border-radius:0;cursor:default;display:block;flex:1;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker-main{padding:2px}.datepicker-footer{background-color:#e6e6e6;box-shadow:inset 0 1px 1px hsla(0,0%,4%,.1)}.datepicker-controls,.datepicker-grid,.datepicker-view,.datepicker-view .days-of-week{display:flex}.datepicker-grid{flex-wrap:wrap}.datepicker-view .days .datepicker-cell,.datepicker-view .dow{flex-basis:14.2857142857%}.datepicker-view.datepicker-grid .datepicker-cell{flex-basis:25%}.datepicker-cell,.datepicker-view .week{height:2.25rem;line-height:2.25rem}.datepicker-title{background-color:#e6e6e6;box-shadow:inset 0 -1px 1px hsla(0,0%,4%,.1);font-weight:700;padding:.375rem .75rem;text-align:center}.datepicker-header .datepicker-controls{padding:2px 2px 0}.datepicker-controls .button{background-color:#fefefe;color:#0a0a0a;margin:0}.datepicker-controls .button:focus,.datepicker-controls .button:hover{background-color:#d8d8d8}.datepicker-controls .button:focus[disabled],.datepicker-controls .button:hover[disabled]{background-color:#fefefe;color:#0a0a0a;opacity:.25}.datepicker-header .datepicker-controls .button{border-color:transparent;font-weight:700}.datepicker-footer .datepicker-controls .button{border-radius:0;font-size:.75rem;margin:calc(.375rem - 1px) .375rem;width:100%}.datepicker-controls .view-switch{flex:auto}.datepicker-controls .next-btn,.datepicker-controls .prev-btn{padding-left:.375rem;padding-right:.375rem;width:2.25rem}.datepicker-controls .next-btn.disabled,.datepicker-controls .prev-btn.disabled{visibility:hidden}.datepicker-view .dow{font-size:.875rem;font-weight:700;height:1.5rem;line-height:1.5rem}.datepicker-view .week{color:#8a8a8a;font-size:.75rem;width:2.25rem}@media (max-width:22.5rem){.datepicker-view .week{width:1.96875rem}}.datepicker-grid{width:15.75rem}@media (max-width:22.5rem){.calendar-weeks+.days .datepicker-grid{width:13.78125rem}}.datepicker-cell:not(.disabled):hover{background-color:#f8f8f8;cursor:pointer}.datepicker-cell.focused:not(.selected){background-color:#f1f1f1}.datepicker-cell.selected,.datepicker-cell.selected:hover{background-color:#1779ba;color:#fefefe;font-weight:semibold}.datepicker-cell.disabled{color:#e6e6e6}.datepicker-cell.next:not(.disabled),.datepicker-cell.prev:not(.disabled){color:#cacaca}.datepicker-cell.next.selected,.datepicker-cell.prev.selected{color:#e5e5e5}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today){background-color:#f7f7f7;border-radius:0}.datepicker-cell.highlighted:not(.selected):not(.range):not(.today).focused,.datepicker-cell.highlighted:not(.selected):not(.range):not(.today):not(.disabled):hover{background-color:#f1f1f1}.datepicker-cell.today:not(.selected){background-color:#d7ecfa}.datepicker-cell.today:not(.selected):not(.disabled){color:#8a8a8a}.datepicker-cell.today.focused:not(.selected){background-color:#cbe7f9}.datepicker-cell.range-end:not(.selected),.datepicker-cell.range-start:not(.selected){background-color:#767676;color:#fefefe}.datepicker-cell.range-end.focused:not(.selected),.datepicker-cell.range-start.focused:not(.selected){background-color:#707070}.datepicker-cell.range-end,.datepicker-cell.range-start{border-radius:0 0 0 0}.datepicker-cell.range{background-color:#e6e6e6;border-radius:0}.datepicker-cell.range:not(.disabled):not(.focused):not(.today):hover{background-color:#e0e0e0}.datepicker-cell.range.disabled{color:#cdcdcd}.datepicker-cell.range.focused{background-color:#d9d9d9}.datepicker-cell.range.today{background-color:#b3dbf6}.datepicker-view.datepicker-grid .datepicker-cell{height:4.5rem;line-height:4.5rem}.datepicker-input.in-edit{border-color:#a4a4a4}.datepicker-input.in-edit:active,.datepicker-input.in-edit:focus{box-shadow:0 0 .25em .25em hsla(0,0%,64%,.2)}
|
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,9 @@ class Download {
|
|||
this.listContainer.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute(`data-${this.prefix}-download`)
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-download`)
|
||||
) {
|
||||
const btnEl = e.target.closest("button");
|
||||
const jobName = btnEl.getAttribute("data-cache-download");
|
||||
|
@ -31,8 +33,8 @@ class Download {
|
|||
window.open(
|
||||
`${location.href.replace(
|
||||
"cache",
|
||||
"jobs"
|
||||
)}/download?job_name=${jobName}&file_name=${fileName}`
|
||||
"jobs",
|
||||
)}/download?job_name=${jobName}&file_name=${fileName}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {
|
||||
FolderNav,
|
||||
FolderEditor,
|
||||
FolderModal,
|
||||
FolderDropdown,
|
||||
} from "./utils/file.manager.js";
|
||||
|
||||
const setModal = new FolderModal("configs");
|
||||
const setEditor = new FolderEditor();
|
||||
const setFolderNav = new FolderNav("configs");
|
||||
const setDropdown = new FolderDropdown("configs");
|
||||
import {
|
||||
FolderNav,
|
||||
FolderEditor,
|
||||
FolderModal,
|
||||
FolderDropdown,
|
||||
} from "./utils/file.manager.js";
|
||||
|
||||
const setModal = new FolderModal("configs");
|
||||
const setEditor = new FolderEditor();
|
||||
const setFolderNav = new FolderNav("configs");
|
||||
const setDropdown = new FolderDropdown("configs");
|
||||
|
|
|
@ -1,317 +1,317 @@
|
|||
import { Checkbox, Select, Password, DisabledPop } from "./utils/form.js";
|
||||
|
||||
class Menu {
|
||||
constructor() {
|
||||
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));
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("aside").hasAttribute("data-sidebar-menu") &&
|
||||
e.target.closest("button").getAttribute("role") === "tab"
|
||||
) {
|
||||
this.close();
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.sidebarEl.classList.toggle("-translate-x-full");
|
||||
}
|
||||
|
||||
close() {
|
||||
this.sidebarEl.classList.add("-translate-x-full");
|
||||
}
|
||||
}
|
||||
|
||||
class News {
|
||||
constructor() {
|
||||
this.BASE_URL = "https://www.bunkerweb.io/";
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("load", async () => {
|
||||
try {
|
||||
const res = await fetch("https://www.bunkerweb.io/api/posts/0/2", {
|
||||
headers: {
|
||||
method: "GET",
|
||||
},
|
||||
});
|
||||
return await this.render(res);
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
render(lastNews) {
|
||||
const newsContainer = document.querySelector("[data-news-container]");
|
||||
//remove default message
|
||||
newsContainer.textContent = "";
|
||||
//render last news
|
||||
lastNews.forEach((news) => {
|
||||
//get info
|
||||
const slug = news.slug;
|
||||
const img = news.photo.url;
|
||||
const excerpt = news.excerpt;
|
||||
const tags = news.tags;
|
||||
const date = news.date;
|
||||
const lastUpdate = news.lastUpdate;
|
||||
//create html card from infos
|
||||
const cardHTML = this.template(
|
||||
slug,
|
||||
img,
|
||||
excerpt,
|
||||
tags,
|
||||
date,
|
||||
lastUpdate
|
||||
);
|
||||
//add to DOM
|
||||
document
|
||||
.querySelector("[data-news-container]")
|
||||
.insertAdjacentHTML("afterbegin", cardHTML);
|
||||
});
|
||||
}
|
||||
|
||||
template(slug, img, excerpt, tags, date, lastUpdate) {
|
||||
//loop on tags to get list
|
||||
let tagList = "";
|
||||
tags.forEach((tag) => {
|
||||
tagList += ` <a
|
||||
href="${this.BASE_URL}/blog/tag/${tag.slug}"
|
||||
class="my-0 mr-1 rounded bg-secondary hover:brightness-90 hover:-translate-y-0.4 text-white py-1 px-2 text-sm"
|
||||
>
|
||||
${tag.name}
|
||||
</a>`;
|
||||
});
|
||||
//create card
|
||||
const card = `
|
||||
<div
|
||||
class="min-h-[400px] w-full col-span-12 transition hover:-translate-y-2 bg-gray-100 dark:bg-slate-900 rounded px-6 py-4 m-2 flex flex-col justify-between"
|
||||
>
|
||||
<div>
|
||||
<img role="link"
|
||||
onclick="window.location.href='${this.BASE_URL}/blog/post/${slug}'"
|
||||
class="cursor-pointer rounded w-full h-40 m-0 object-cover"
|
||||
src="${img}"
|
||||
alt="image"
|
||||
/>
|
||||
<h3 role="link"
|
||||
onclick="window.location.href='${this.BASE_URL}/blog/post/${slug}'"
|
||||
class="cursor-pointer mt-3 mb-1 text-3xl dark:text-white tracking-wide">{{ post['title'] }}</h3>
|
||||
</div>
|
||||
<div>
|
||||
<div role="link"
|
||||
onclick="window.location.href='${this.BASE_URL}/blog/post/${slug}'"
|
||||
class="cursor-pointer min-h-[130px] mb-3 text-lg dark:text-gray-300 text-gray-600 pt-3">
|
||||
${excerpt}
|
||||
</div>
|
||||
<div class="min-h-[75px] mt-2 flex flex-wrap justify-start items-end align-bottom">
|
||||
${tagList}
|
||||
</div>
|
||||
|
||||
<div class="mt-2 flex flex-col justify-start items-start">
|
||||
<span class="text-xs dark:text-gray-300 text-gray-600"
|
||||
>Posted on : ${date}</span
|
||||
>
|
||||
{% if post["updatedAt"] %}
|
||||
<span class="text-xs dark:text-gray-300 text-gray-600"
|
||||
>Last update : ${lastUpdate}</span
|
||||
>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
</div> `;
|
||||
return card;
|
||||
}
|
||||
}
|
||||
|
||||
class Sidebar {
|
||||
constructor(elAtt, btnOpenAtt, btnCloseAtt) {
|
||||
this.sidebarEl = document.querySelector(elAtt);
|
||||
this.openBtn = document.querySelector(btnOpenAtt);
|
||||
this.closeBtn = document.querySelector(btnCloseAtt);
|
||||
this.openBtn.addEventListener("click", this.open.bind(this));
|
||||
this.closeBtn.addEventListener("click", this.close.bind(this));
|
||||
}
|
||||
|
||||
open() {
|
||||
this.sidebarEl.classList.add("translate-x-0");
|
||||
this.sidebarEl.classList.remove("translate-x-90");
|
||||
}
|
||||
|
||||
close() {
|
||||
this.sidebarEl.classList.add("translate-x-90");
|
||||
this.sidebarEl.classList.remove("translate-x-0");
|
||||
}
|
||||
}
|
||||
|
||||
class darkMode {
|
||||
constructor() {
|
||||
this.htmlEl = document.querySelector("html");
|
||||
this.darkToggleEl = document.querySelector("[data-dark-toggle]");
|
||||
this.darkToggleLabel = document.querySelector("[data-dark-toggle-label]");
|
||||
this.csrf = document.querySelector("input#csrf_token");
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.darkToggleEl.addEventListener("change", (e) => {
|
||||
this.toggle();
|
||||
this.saveMode();
|
||||
});
|
||||
}
|
||||
|
||||
toggle() {
|
||||
document.querySelector("html").classList.toggle("dark");
|
||||
this.darkToggleLabel.textContent = this.darkToggleEl.checked
|
||||
? "dark mode"
|
||||
: "light mode";
|
||||
}
|
||||
|
||||
async saveMode() {
|
||||
const isDark = this.darkToggleEl.checked ? "true" : "false";
|
||||
const data = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": this.csrf.value,
|
||||
},
|
||||
body: JSON.stringify({ darkmode: isDark }),
|
||||
};
|
||||
const send = await fetch(
|
||||
`${location.href.split("/").slice(0, -1).join("/")}/darkmode`,
|
||||
data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FlashMsg {
|
||||
constructor() {
|
||||
this.openBtn = document.querySelector("[data-flash-sidebar-open]");
|
||||
this.flashCount = document.querySelector("[data-flash-count]");
|
||||
this.isMsgCheck = false;
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
//animate message button if message + never opened
|
||||
window.addEventListener("load", (e) => {
|
||||
if (Number(this.flashCount.textContent) > 0) this.animeBtn();
|
||||
});
|
||||
//stop animate if clicked once
|
||||
this.openBtn.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute("data-flash-sidebar-open")
|
||||
) {
|
||||
this.isMsgCheck = true;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
//remove flash message and change count
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute("data-close-flash-message")
|
||||
) {
|
||||
//remove logic
|
||||
const closeBtn = e.target.closest("button");
|
||||
const flashEl = closeBtn.closest("[data-flash-message]");
|
||||
flashEl.remove();
|
||||
//update count
|
||||
this.flashCount.textContent = document.querySelectorAll(
|
||||
"[data-flash-message]"
|
||||
).length;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
animeBtn() {
|
||||
this.openBtn.classList.add("rotate-12");
|
||||
|
||||
setTimeout(() => {
|
||||
this.openBtn.classList.remove("rotate-12");
|
||||
this.openBtn.classList.add("-rotate-12");
|
||||
}, 150);
|
||||
|
||||
setTimeout(() => {
|
||||
this.openBtn.classList.remove("-rotate-12");
|
||||
}, 300);
|
||||
|
||||
setTimeout(() => {
|
||||
if (!this.isMsgCheck) {
|
||||
this.animeBtn();
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
class Loader {
|
||||
constructor() {
|
||||
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();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.loading();
|
||||
window.addEventListener("load", (e) => {
|
||||
setTimeout(() => {
|
||||
this.logoContainer.classList.add("opacity-0");
|
||||
}, 350);
|
||||
|
||||
setTimeout(() => {
|
||||
this.isLoading = false;
|
||||
this.logoContainer.classList.add("hidden");
|
||||
}, 650);
|
||||
|
||||
setTimeout(() => {
|
||||
this.logoContainer.remove();
|
||||
}, 800);
|
||||
});
|
||||
}
|
||||
|
||||
loading() {
|
||||
if ((this.isLoading = true)) {
|
||||
setTimeout(() => {
|
||||
this.logoEl.classList.toggle("scale-105");
|
||||
this.loading();
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setLoader = new Loader();
|
||||
const setMenu = new Menu();
|
||||
const setNewsSidebar = new Sidebar(
|
||||
"[data-sidebar-info]",
|
||||
"[data-sidebar-info-open]",
|
||||
"[data-sidebar-info-close]"
|
||||
);
|
||||
|
||||
const setCheckbox = new Checkbox();
|
||||
const setSelect = new Select();
|
||||
const setPassword = new Password();
|
||||
const setDisabledPop = new DisabledPop();
|
||||
|
||||
const setFlashSidebar = new Sidebar(
|
||||
"[data-flash-sidebar]",
|
||||
"[data-flash-sidebar-open]",
|
||||
"[data-flash-sidebar-close]"
|
||||
);
|
||||
const setNews = new News();
|
||||
const setDarkM = new darkMode();
|
||||
const setFlash = new FlashMsg();
|
||||
import { Checkbox, Select, Password, DisabledPop } from "./utils/form.js";
|
||||
|
||||
class Menu {
|
||||
constructor() {
|
||||
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));
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("aside").hasAttribute("data-sidebar-menu") &&
|
||||
e.target.closest("button").getAttribute("role") === "tab"
|
||||
) {
|
||||
this.close();
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.sidebarEl.classList.toggle("-translate-x-full");
|
||||
}
|
||||
|
||||
close() {
|
||||
this.sidebarEl.classList.add("-translate-x-full");
|
||||
}
|
||||
}
|
||||
|
||||
class News {
|
||||
constructor() {
|
||||
this.BASE_URL = "https://www.bunkerweb.io/";
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("load", async () => {
|
||||
try {
|
||||
const res = await fetch("https://www.bunkerweb.io/api/posts/0/2", {
|
||||
headers: {
|
||||
method: "GET",
|
||||
},
|
||||
});
|
||||
return await this.render(res);
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
render(lastNews) {
|
||||
const newsContainer = document.querySelector("[data-news-container]");
|
||||
//remove default message
|
||||
newsContainer.textContent = "";
|
||||
//render last news
|
||||
lastNews.forEach((news) => {
|
||||
//get info
|
||||
const slug = news.slug;
|
||||
const img = news.photo.url;
|
||||
const excerpt = news.excerpt;
|
||||
const tags = news.tags;
|
||||
const date = news.date;
|
||||
const lastUpdate = news.lastUpdate;
|
||||
//create html card from infos
|
||||
const cardHTML = this.template(
|
||||
slug,
|
||||
img,
|
||||
excerpt,
|
||||
tags,
|
||||
date,
|
||||
lastUpdate,
|
||||
);
|
||||
//add to DOM
|
||||
document
|
||||
.querySelector("[data-news-container]")
|
||||
.insertAdjacentHTML("afterbegin", cardHTML);
|
||||
});
|
||||
}
|
||||
|
||||
template(slug, img, excerpt, tags, date, lastUpdate) {
|
||||
//loop on tags to get list
|
||||
let tagList = "";
|
||||
tags.forEach((tag) => {
|
||||
tagList += ` <a
|
||||
href="${this.BASE_URL}/blog/tag/${tag.slug}"
|
||||
class="my-0 mr-1 rounded bg-secondary hover:brightness-90 hover:-translate-y-0.4 text-white py-1 px-2 text-sm"
|
||||
>
|
||||
${tag.name}
|
||||
</a>`;
|
||||
});
|
||||
//create card
|
||||
const card = `
|
||||
<div
|
||||
class="min-h-[400px] w-full col-span-12 transition hover:-translate-y-2 bg-gray-100 dark:bg-slate-900 rounded px-6 py-4 m-2 flex flex-col justify-between"
|
||||
>
|
||||
<div>
|
||||
<img role="link"
|
||||
onclick="window.location.href='${this.BASE_URL}/blog/post/${slug}'"
|
||||
class="cursor-pointer rounded w-full h-40 m-0 object-cover"
|
||||
src="${img}"
|
||||
alt="image"
|
||||
/>
|
||||
<h3 role="link"
|
||||
onclick="window.location.href='${this.BASE_URL}/blog/post/${slug}'"
|
||||
class="cursor-pointer mt-3 mb-1 text-3xl dark:text-white tracking-wide">{{ post['title'] }}</h3>
|
||||
</div>
|
||||
<div>
|
||||
<div role="link"
|
||||
onclick="window.location.href='${this.BASE_URL}/blog/post/${slug}'"
|
||||
class="cursor-pointer min-h-[130px] mb-3 text-lg dark:text-gray-300 text-gray-600 pt-3">
|
||||
${excerpt}
|
||||
</div>
|
||||
<div class="min-h-[75px] mt-2 flex flex-wrap justify-start items-end align-bottom">
|
||||
${tagList}
|
||||
</div>
|
||||
|
||||
<div class="mt-2 flex flex-col justify-start items-start">
|
||||
<span class="text-xs dark:text-gray-300 text-gray-600"
|
||||
>Posted on : ${date}</span
|
||||
>
|
||||
{% if post["updatedAt"] %}
|
||||
<span class="text-xs dark:text-gray-300 text-gray-600"
|
||||
>Last update : ${lastUpdate}</span
|
||||
>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
</div> `;
|
||||
return card;
|
||||
}
|
||||
}
|
||||
|
||||
class Sidebar {
|
||||
constructor(elAtt, btnOpenAtt, btnCloseAtt) {
|
||||
this.sidebarEl = document.querySelector(elAtt);
|
||||
this.openBtn = document.querySelector(btnOpenAtt);
|
||||
this.closeBtn = document.querySelector(btnCloseAtt);
|
||||
this.openBtn.addEventListener("click", this.open.bind(this));
|
||||
this.closeBtn.addEventListener("click", this.close.bind(this));
|
||||
}
|
||||
|
||||
open() {
|
||||
this.sidebarEl.classList.add("translate-x-0");
|
||||
this.sidebarEl.classList.remove("translate-x-90");
|
||||
}
|
||||
|
||||
close() {
|
||||
this.sidebarEl.classList.add("translate-x-90");
|
||||
this.sidebarEl.classList.remove("translate-x-0");
|
||||
}
|
||||
}
|
||||
|
||||
class darkMode {
|
||||
constructor() {
|
||||
this.htmlEl = document.querySelector("html");
|
||||
this.darkToggleEl = document.querySelector("[data-dark-toggle]");
|
||||
this.darkToggleLabel = document.querySelector("[data-dark-toggle-label]");
|
||||
this.csrf = document.querySelector("input#csrf_token");
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.darkToggleEl.addEventListener("change", (e) => {
|
||||
this.toggle();
|
||||
this.saveMode();
|
||||
});
|
||||
}
|
||||
|
||||
toggle() {
|
||||
document.querySelector("html").classList.toggle("dark");
|
||||
this.darkToggleLabel.textContent = this.darkToggleEl.checked
|
||||
? "dark mode"
|
||||
: "light mode";
|
||||
}
|
||||
|
||||
async saveMode() {
|
||||
const isDark = this.darkToggleEl.checked ? "true" : "false";
|
||||
const data = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-Token": this.csrf.value,
|
||||
},
|
||||
body: JSON.stringify({ darkmode: isDark }),
|
||||
};
|
||||
const send = await fetch(
|
||||
`${location.href.split("/").slice(0, -1).join("/")}/darkmode`,
|
||||
data,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FlashMsg {
|
||||
constructor() {
|
||||
this.openBtn = document.querySelector("[data-flash-sidebar-open]");
|
||||
this.flashCount = document.querySelector("[data-flash-count]");
|
||||
this.isMsgCheck = false;
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
//animate message button if message + never opened
|
||||
window.addEventListener("load", (e) => {
|
||||
if (Number(this.flashCount.textContent) > 0) this.animeBtn();
|
||||
});
|
||||
//stop animate if clicked once
|
||||
this.openBtn.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute("data-flash-sidebar-open")
|
||||
) {
|
||||
this.isMsgCheck = true;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
//remove flash message and change count
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute("data-close-flash-message")
|
||||
) {
|
||||
//remove logic
|
||||
const closeBtn = e.target.closest("button");
|
||||
const flashEl = closeBtn.closest("[data-flash-message]");
|
||||
flashEl.remove();
|
||||
//update count
|
||||
this.flashCount.textContent = document.querySelectorAll(
|
||||
"[data-flash-message]",
|
||||
).length;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
animeBtn() {
|
||||
this.openBtn.classList.add("rotate-12");
|
||||
|
||||
setTimeout(() => {
|
||||
this.openBtn.classList.remove("rotate-12");
|
||||
this.openBtn.classList.add("-rotate-12");
|
||||
}, 150);
|
||||
|
||||
setTimeout(() => {
|
||||
this.openBtn.classList.remove("-rotate-12");
|
||||
}, 300);
|
||||
|
||||
setTimeout(() => {
|
||||
if (!this.isMsgCheck) {
|
||||
this.animeBtn();
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
class Loader {
|
||||
constructor() {
|
||||
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();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.loading();
|
||||
window.addEventListener("load", (e) => {
|
||||
setTimeout(() => {
|
||||
this.logoContainer.classList.add("opacity-0");
|
||||
}, 350);
|
||||
|
||||
setTimeout(() => {
|
||||
this.isLoading = false;
|
||||
this.logoContainer.classList.add("hidden");
|
||||
}, 650);
|
||||
|
||||
setTimeout(() => {
|
||||
this.logoContainer.remove();
|
||||
}, 800);
|
||||
});
|
||||
}
|
||||
|
||||
loading() {
|
||||
if ((this.isLoading = true)) {
|
||||
setTimeout(() => {
|
||||
this.logoEl.classList.toggle("scale-105");
|
||||
this.loading();
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setLoader = new Loader();
|
||||
const setMenu = new Menu();
|
||||
const setNewsSidebar = new Sidebar(
|
||||
"[data-sidebar-info]",
|
||||
"[data-sidebar-info-open]",
|
||||
"[data-sidebar-info-close]",
|
||||
);
|
||||
|
||||
const setCheckbox = new Checkbox();
|
||||
const setSelect = new Select();
|
||||
const setPassword = new Password();
|
||||
const setDisabledPop = new DisabledPop();
|
||||
|
||||
const setFlashSidebar = new Sidebar(
|
||||
"[data-flash-sidebar]",
|
||||
"[data-flash-sidebar-open]",
|
||||
"[data-flash-sidebar-close]",
|
||||
);
|
||||
const setNews = new News();
|
||||
const setDarkM = new darkMode();
|
||||
const setFlash = new FlashMsg();
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
import {
|
||||
Popover,
|
||||
Tabs,
|
||||
FormatValue,
|
||||
FilterSettings,
|
||||
} from "./utils/settings.js";
|
||||
|
||||
class Multiple {
|
||||
constructor(prefix) {
|
||||
this.prefix = prefix;
|
||||
this.init();
|
||||
}
|
||||
//hide multiples handler if no multiple setting on plugin
|
||||
init() {
|
||||
//hide multiple btn if no multiple exist on a plugin
|
||||
const multiples = document.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple]`
|
||||
);
|
||||
multiples.forEach((container) => {
|
||||
if (container.querySelectorAll(`[data-setting-container]`).length <= 0)
|
||||
container.parentElement
|
||||
.querySelector("[data-multiple-handler]")
|
||||
.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const setPopover = new Popover("main", "global-config");
|
||||
const setTabs = new Tabs("[global-config-tabs]", "global-config");
|
||||
const format = new FormatValue();
|
||||
const setMultiple = new Multiple("global-config");
|
||||
const setFilterGlobal = new FilterSettings(
|
||||
"settings-filter",
|
||||
"[data-service-content='settings']"
|
||||
);
|
||||
import {
|
||||
Popover,
|
||||
Tabs,
|
||||
FormatValue,
|
||||
FilterSettings,
|
||||
} from "./utils/settings.js";
|
||||
|
||||
class Multiple {
|
||||
constructor(prefix) {
|
||||
this.prefix = prefix;
|
||||
this.init();
|
||||
}
|
||||
//hide multiples handler if no multiple setting on plugin
|
||||
init() {
|
||||
//hide multiple btn if no multiple exist on a plugin
|
||||
const multiples = document.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple]`,
|
||||
);
|
||||
multiples.forEach((container) => {
|
||||
if (container.querySelectorAll(`[data-setting-container]`).length <= 0)
|
||||
container.parentElement
|
||||
.querySelector("[data-multiple-handler]")
|
||||
.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const setPopover = new Popover("main", "global-config");
|
||||
const setTabs = new Tabs("[global-config-tabs]", "global-config");
|
||||
const format = new FormatValue();
|
||||
const setMultiple = new Multiple("global-config");
|
||||
const setFilterGlobal = new FilterSettings(
|
||||
"settings-filter",
|
||||
"[data-service-content='settings']",
|
||||
);
|
||||
|
|
|
@ -37,7 +37,7 @@ class Dropdown {
|
|||
const btn = e.target.closest("button");
|
||||
const btnValue = btn.getAttribute("value");
|
||||
const btnSetting = btn.getAttribute(
|
||||
`data-${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);
|
||||
|
@ -61,7 +61,7 @@ class Dropdown {
|
|||
|
||||
closeAllDrop() {
|
||||
const drops = document.querySelectorAll(
|
||||
`[data-${this.prefix}-setting-select-dropdown]`
|
||||
`[data-${this.prefix}-setting-select-dropdown]`,
|
||||
);
|
||||
drops.forEach((drop) => {
|
||||
drop.classList.add("hidden");
|
||||
|
@ -69,8 +69,8 @@ class Dropdown {
|
|||
document
|
||||
.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown`
|
||||
)}"]`
|
||||
`data-${this.prefix}-setting-select-dropdown`,
|
||||
)}"]`,
|
||||
)
|
||||
.classList.remove("rotate-180");
|
||||
});
|
||||
|
@ -78,7 +78,7 @@ class Dropdown {
|
|||
|
||||
isSameValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`,
|
||||
);
|
||||
const currVal = selectCustom.textContent;
|
||||
return currVal === value ? true : false;
|
||||
|
@ -86,30 +86,30 @@ class Dropdown {
|
|||
|
||||
setSelectNewValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
selectCustom.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text]`
|
||||
`[data-${this.prefix}-setting-select-text]`,
|
||||
).textContent = value;
|
||||
}
|
||||
|
||||
hideDropdown(btnSetting) {
|
||||
//hide dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${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[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
}
|
||||
|
||||
changeDropBtnStyle(btnSetting, selectedBtn) {
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
@ -119,7 +119,7 @@ class Dropdown {
|
|||
"bg-primary",
|
||||
"dark:bg-primary",
|
||||
"text-gray-300",
|
||||
"text-gray-300"
|
||||
"text-gray-300",
|
||||
);
|
||||
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
|
||||
});
|
||||
|
@ -127,7 +127,7 @@ class Dropdown {
|
|||
selectedBtn.classList.remove(
|
||||
"bg-white",
|
||||
"dark:bg-slate-700",
|
||||
"text-gray-700"
|
||||
"text-gray-700",
|
||||
);
|
||||
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
|
||||
}
|
||||
|
@ -138,10 +138,10 @@ class Dropdown {
|
|||
.getAttribute(`data-${this.prefix}-setting-select`);
|
||||
//toggle dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`,
|
||||
);
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${attribut}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${attribut}"]`,
|
||||
);
|
||||
dropdownEl.classList.toggle("hidden");
|
||||
dropdownEl.classList.toggle("flex");
|
||||
|
@ -197,7 +197,7 @@ class Filter {
|
|||
setTimeout(() => {
|
||||
const value = document
|
||||
.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="success"]`
|
||||
`[data-${this.prefix}-setting-select-text="success"]`,
|
||||
)
|
||||
.textContent.trim();
|
||||
|
||||
|
@ -220,7 +220,7 @@ class Filter {
|
|||
setTimeout(() => {
|
||||
const value = document
|
||||
.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="reload"]`
|
||||
`[data-${this.prefix}-setting-select-text="reload"]`,
|
||||
)
|
||||
.textContent.trim();
|
||||
|
||||
|
@ -329,7 +329,7 @@ class Download {
|
|||
|
||||
async sendFileToDL(jobName, fileName) {
|
||||
window.open(
|
||||
`${location.href}/download?job_name=${jobName}&file_name=${fileName}`
|
||||
`${location.href}/download?job_name=${jobName}&file_name=${fileName}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class Dropdown {
|
|||
const btn = e.target.closest("button");
|
||||
const btnValue = btn.getAttribute("value");
|
||||
const btnSetting = btn.getAttribute(
|
||||
`data-${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);
|
||||
|
@ -58,7 +58,7 @@ class Dropdown {
|
|||
|
||||
closeAllDrop() {
|
||||
const drops = document.querySelectorAll(
|
||||
`[data-${this.prefix}-setting-select-dropdown]`
|
||||
`[data-${this.prefix}-setting-select-dropdown]`,
|
||||
);
|
||||
drops.forEach((drop) => {
|
||||
drop.classList.add("hidden");
|
||||
|
@ -66,8 +66,8 @@ class Dropdown {
|
|||
document
|
||||
.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown`
|
||||
)}"]`
|
||||
`data-${this.prefix}-setting-select-dropdown`,
|
||||
)}"]`,
|
||||
)
|
||||
.classList.remove("rotate-180");
|
||||
});
|
||||
|
@ -75,7 +75,7 @@ class Dropdown {
|
|||
|
||||
isSameValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${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(
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
selectCustom.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text]`
|
||||
`[data-${this.prefix}-setting-select-text]`,
|
||||
).textContent = value;
|
||||
}
|
||||
|
||||
hideDropdown(btnSetting) {
|
||||
//hide dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${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[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
}
|
||||
|
||||
changeDropBtnStyle(btnSetting, selectedBtn) {
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
@ -116,7 +116,7 @@ class Dropdown {
|
|||
"bg-primary",
|
||||
"dark:bg-primary",
|
||||
"text-gray-300",
|
||||
"text-gray-300"
|
||||
"text-gray-300",
|
||||
);
|
||||
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
|
||||
});
|
||||
|
@ -124,7 +124,7 @@ class Dropdown {
|
|||
selectedBtn.classList.remove(
|
||||
"bg-white",
|
||||
"dark:bg-slate-700",
|
||||
"text-gray-700"
|
||||
"text-gray-700",
|
||||
);
|
||||
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
|
||||
}
|
||||
|
@ -135,10 +135,10 @@ class Dropdown {
|
|||
.getAttribute(`data-${this.prefix}-setting-select`);
|
||||
//toggle dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`,
|
||||
);
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${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 FetchLogs {
|
|||
constructor(prefix = "logs") {
|
||||
this.prefix = prefix;
|
||||
this.instance = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="instances"]`
|
||||
`[data-${this.prefix}-setting-select-text="instances"]`,
|
||||
);
|
||||
this.instanceName = "";
|
||||
this.updateInp = document.querySelector("input#update-date");
|
||||
|
@ -188,7 +188,7 @@ class FetchLogs {
|
|||
this.lastUpdate = Date.now() - 86400000;
|
||||
this.container = document.querySelector(`[data-${this.prefix}-settings]`);
|
||||
this.logListContainer = document.querySelector(
|
||||
`[data-${this.prefix}-list]`
|
||||
`[data-${this.prefix}-list]`,
|
||||
);
|
||||
this.submitDate = document.querySelector("button[data-submit-date]");
|
||||
this.submitLive = document.querySelector("button[data-submit-live]");
|
||||
|
@ -218,7 +218,7 @@ class FetchLogs {
|
|||
"data-submit-live",
|
||||
this.submitLive.getAttribute("data-submit-live") === "yes"
|
||||
? "no"
|
||||
: "yes"
|
||||
: "yes",
|
||||
);
|
||||
|
||||
if (this.submitLive.getAttribute("data-submit-live") === "yes") {
|
||||
|
@ -314,7 +314,7 @@ class FetchLogs {
|
|||
.querySelector(`[data-${this.prefix}-list]`)
|
||||
.scrollTo(
|
||||
0,
|
||||
document.querySelector(`[data-${this.prefix}-list]`).scrollHeight
|
||||
document.querySelector(`[data-${this.prefix}-list]`).scrollHeight,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,7 @@ class FetchLogs {
|
|||
//case from date defined only
|
||||
if (this.toDate) {
|
||||
res = await fetch(
|
||||
`${location.href}/${this.instanceName}?from_date=${this.fromDate}&to_date=${this.toDate}`
|
||||
`${location.href}/${this.instanceName}?from_date=${this.fromDate}&to_date=${this.toDate}`,
|
||||
);
|
||||
const data = await res.json();
|
||||
return await this.showLogsDate(data);
|
||||
|
@ -331,7 +331,7 @@ class FetchLogs {
|
|||
//case from date and to date defined
|
||||
if (!this.toDate) {
|
||||
res = await fetch(
|
||||
`${location.href}/${this.instanceName}?from_date=${this.fromDate}`
|
||||
`${location.href}/${this.instanceName}?from_date=${this.fromDate}`,
|
||||
);
|
||||
const data = await res.json();
|
||||
return await this.showLogsDate(data);
|
||||
|
@ -341,7 +341,7 @@ class FetchLogs {
|
|||
async getLogsSinceLastUpdate() {
|
||||
const response = await fetch(
|
||||
`${location.href}/${this.instanceName}` +
|
||||
(this.lastUpdate ? `?last_update=${this.lastUpdate}` : "")
|
||||
(this.lastUpdate ? `?last_update=${this.lastUpdate}` : ""),
|
||||
);
|
||||
const data = await response.json();
|
||||
return await this.showLogsLive(data);
|
||||
|
@ -437,7 +437,7 @@ class Filter {
|
|||
const btn = e.target.closest("button");
|
||||
const btnValue = btn.getAttribute("value");
|
||||
const btnSetting = btn.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown-btn`
|
||||
`data-${this.prefix}-setting-select-dropdown-btn`,
|
||||
);
|
||||
|
||||
this.lastType = btnValue;
|
||||
|
|
|
@ -36,7 +36,7 @@ class Dropdown {
|
|||
const btn = e.target.closest("button");
|
||||
const btnValue = btn.getAttribute("value");
|
||||
const btnSetting = btn.getAttribute(
|
||||
`data-${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);
|
||||
|
@ -57,7 +57,7 @@ class Dropdown {
|
|||
|
||||
closeAllDrop() {
|
||||
const drops = document.querySelectorAll(
|
||||
`[data-${this.prefix}-setting-select-dropdown]`
|
||||
`[data-${this.prefix}-setting-select-dropdown]`,
|
||||
);
|
||||
drops.forEach((drop) => {
|
||||
drop.classList.add("hidden");
|
||||
|
@ -65,8 +65,8 @@ class Dropdown {
|
|||
document
|
||||
.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown`
|
||||
)}"]`
|
||||
`data-${this.prefix}-setting-select-dropdown`,
|
||||
)}"]`,
|
||||
)
|
||||
.classList.remove("rotate-180");
|
||||
});
|
||||
|
@ -74,7 +74,7 @@ class Dropdown {
|
|||
|
||||
isSameValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${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(
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
selectCustom.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text]`
|
||||
`[data-${this.prefix}-setting-select-text]`,
|
||||
).textContent = value;
|
||||
}
|
||||
|
||||
hideDropdown(btnSetting) {
|
||||
//hide dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${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[data-${this.prefix}-setting-select="${btnSetting}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
}
|
||||
|
||||
changeDropBtnStyle(btnSetting, selectedBtn) {
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
@ -116,7 +116,7 @@ class Dropdown {
|
|||
"bg-primary",
|
||||
"bg-primary",
|
||||
"text-gray-300",
|
||||
"text-gray-300"
|
||||
"text-gray-300",
|
||||
);
|
||||
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
|
||||
});
|
||||
|
@ -124,7 +124,7 @@ class Dropdown {
|
|||
selectedBtn.classList.remove(
|
||||
"bg-white",
|
||||
"dark:bg-slate-700",
|
||||
"text-gray-700"
|
||||
"text-gray-700",
|
||||
);
|
||||
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
|
||||
}
|
||||
|
@ -135,10 +135,10 @@ class Dropdown {
|
|||
.getAttribute(`data-${this.prefix}-setting-select`);
|
||||
//toggle dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribut}"]`,
|
||||
);
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${attribut}"]`
|
||||
`svg[data-${this.prefix}-setting-select="${attribut}"]`,
|
||||
);
|
||||
dropdownEl.classList.toggle("hidden");
|
||||
dropdownEl.classList.toggle("flex");
|
||||
|
@ -286,7 +286,9 @@ class Upload {
|
|||
//close fail/success log
|
||||
this.container.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-upload-message-delete")) {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute("data-upload-message-delete")
|
||||
) {
|
||||
const message = e.target.closest("div[data-upload-message]");
|
||||
message.remove();
|
||||
}
|
||||
|
@ -298,7 +300,7 @@ class Upload {
|
|||
this.dropZoneElement.classList.remove(
|
||||
"border-solid",
|
||||
"bg-gray-100",
|
||||
"dark:bg-slate-700/50"
|
||||
"dark:bg-slate-700/50",
|
||||
);
|
||||
this.dropZoneElement.classList.add("border-dashed");
|
||||
}
|
||||
|
@ -307,7 +309,7 @@ class Upload {
|
|||
this.dropZoneElement.classList.add(
|
||||
"border-solid",
|
||||
"bg-gray-100",
|
||||
"dark:bg-slate-700/50"
|
||||
"dark:bg-slate-700/50",
|
||||
);
|
||||
this.dropZoneElement.classList.remove("border-dashed");
|
||||
}
|
||||
|
@ -343,13 +345,13 @@ class Upload {
|
|||
if (xhr.status == 201) {
|
||||
this.uploadedArea.insertAdjacentHTML(
|
||||
"afterbegin",
|
||||
this.fileSuccess(name, fileSize)
|
||||
this.fileSuccess(name, fileSize),
|
||||
);
|
||||
this.allowReload();
|
||||
} else {
|
||||
this.uploadedArea.insertAdjacentHTML(
|
||||
"afterbegin",
|
||||
this.fileFail(name, fileSize)
|
||||
this.fileFail(name, fileSize),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -445,8 +447,12 @@ class Modal {
|
|||
this.modalNameInp = this.modal.querySelector("input#name");
|
||||
this.modalExtInp = this.modal.querySelector("input#external");
|
||||
|
||||
this.modalTitle = this.modal.querySelector(`[data-${this.prefix}-modal-title]`);
|
||||
this.modalTxt = this.modal.querySelector(`[data-${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();
|
||||
}
|
||||
|
||||
|
@ -455,8 +461,9 @@ class Modal {
|
|||
//DELETE HANDLER
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").getAttribute(`data-${this.prefix}-action`) ===
|
||||
"delete"
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-action`) === "delete"
|
||||
) {
|
||||
const btnEl = e.target.closest("button");
|
||||
this.setModal(btnEl);
|
||||
|
@ -469,7 +476,9 @@ class Modal {
|
|||
//CLOSE MODAL HANDLER
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute(`data-${this.prefix}-modal-close`)
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-modal-close`)
|
||||
) {
|
||||
this.hideModal();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -1,262 +1,262 @@
|
|||
class Checkbox {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
//prevent default checkbox behavior
|
||||
try {
|
||||
//case a related checkbox element is clicked and checkbox is enabled
|
||||
if (
|
||||
e.target.closest("div").hasAttribute("data-checkbox-handler") &&
|
||||
!e.target
|
||||
.closest("div")
|
||||
.querySelector('input[type="checkbox"]')
|
||||
.hasAttribute("disabled")
|
||||
) {
|
||||
//get related checkbox
|
||||
const checkboxEl = e.target
|
||||
.closest("div")
|
||||
.querySelector('input[type="checkbox"]');
|
||||
|
||||
const prevValue = checkboxEl.getAttribute("value");
|
||||
|
||||
//set attribute value for new state
|
||||
prevValue === "no"
|
||||
? checkboxEl.setAttribute("value", "yes")
|
||||
: checkboxEl.setAttribute("value", "no");
|
||||
|
||||
//set custom input hidden value
|
||||
const newValue = checkboxEl.getAttribute("value");
|
||||
newValue === "yes"
|
||||
? checkboxEl.setAttribute("aria-checked", "true")
|
||||
: checkboxEl.setAttribute("aria-checked", "false");
|
||||
|
||||
//force checked for submit
|
||||
checkboxEl.checked = true;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Select {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
//CASE NO BTN SELECT CLICKED
|
||||
try {
|
||||
if (!e.target.closest("button")) {
|
||||
const selectEls = document.querySelectorAll(
|
||||
"div[data-setting-select-dropdown]"
|
||||
);
|
||||
selectEls.forEach((select) => {
|
||||
select.classList.add("hidden");
|
||||
select.classList.remove("flex");
|
||||
});
|
||||
const btnEls = document.querySelectorAll(
|
||||
"button[data-setting-select]"
|
||||
);
|
||||
btnEls.forEach((btn) => {
|
||||
const dropdownChevron = btn.querySelector(
|
||||
`svg[data-setting-select]`
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
});
|
||||
}
|
||||
} catch (err) {}
|
||||
//SELECT BTN LOGIC
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute(`data-setting-select`) &&
|
||||
!e.target.closest("button").hasAttribute(`disabled`)
|
||||
) {
|
||||
const btnEl = e.target.closest("button");
|
||||
this.toggleSelectBtn(btnEl);
|
||||
}
|
||||
} catch (err) {}
|
||||
//SELECT DROPDOWN BTN LOGIC
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-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[data-select-container]")
|
||||
.querySelector(`button[data-setting-select]`);
|
||||
|
||||
selectCustom.querySelector(`[data-setting-select-text]`).textContent =
|
||||
btnValue;
|
||||
//add selected to new value
|
||||
|
||||
//change style
|
||||
const dropdownEl = btn.closest(`div[data-setting-select-dropdown]`);
|
||||
dropdownEl.classList.add("hidden");
|
||||
dropdownEl.classList.remove("flex");
|
||||
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
btn.classList.remove("active");
|
||||
});
|
||||
//highlight clicked btn
|
||||
btn.classList.add("active");
|
||||
|
||||
//close dropdown
|
||||
const dropdownChevron = selectCustom.querySelector(
|
||||
`svg[data-setting-select]`
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
|
||||
//update real select element
|
||||
const realSel = btn
|
||||
.closest("div[data-setting-container]")
|
||||
.querySelector("select");
|
||||
this.updateSelected(realSel, btnValue);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
updateSelected(selectEl, selectedValue) {
|
||||
const options = selectEl.querySelectorAll("option");
|
||||
//remove selected to all
|
||||
options.forEach((option) => {
|
||||
option.removeAttribute("selected");
|
||||
option.selected = false;
|
||||
});
|
||||
//select new one
|
||||
const newOption = selectEl.querySelector(
|
||||
`option[value="${selectedValue}"]`
|
||||
);
|
||||
newOption.selected = true;
|
||||
newOption.setAttribute("selected", "");
|
||||
}
|
||||
|
||||
toggleSelectBtn(btn) {
|
||||
//toggle dropdown
|
||||
const dropdownEl = btn
|
||||
.closest("div")
|
||||
.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");
|
||||
}
|
||||
}
|
||||
|
||||
class Password {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-setting-password")) {
|
||||
const btn = e.target.closest("button");
|
||||
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);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
showOppositeBtn(btnEl, action) {
|
||||
const btnEls = this.getBtns(btnEl);
|
||||
const opposite = action === "visible" ? "invisible" : "visible";
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
const action = btn.getAttribute("data-setting-password");
|
||||
|
||||
if (action === opposite) {
|
||||
btn.classList.add("flex");
|
||||
btn.classList.remove("hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setValDisplay(action, inp) {
|
||||
if (action === "visible") inp.setAttribute("type", "text");
|
||||
if (action === "invisible") inp.setAttribute("type", "password");
|
||||
}
|
||||
|
||||
hiddenBtns(btnEl) {
|
||||
const btnEls = this.getBtns(btnEl);
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
btn.classList.add("hidden");
|
||||
btn.classList.remove("flex");
|
||||
});
|
||||
}
|
||||
|
||||
getBtns(btnEl) {
|
||||
return btnEl
|
||||
.closest("[data-setting-container]")
|
||||
.querySelectorAll("button[data-setting-password]");
|
||||
}
|
||||
}
|
||||
|
||||
class DisabledPop {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("pointerover", (e) => {
|
||||
//for checkbox and regular inputs
|
||||
if (e.target.tagName === "INPUT") {
|
||||
const el = e.target;
|
||||
this.showPopup(el, "input");
|
||||
}
|
||||
//for select custom
|
||||
if (
|
||||
e.target.tagName === "BUTTON" &&
|
||||
e.target.hasAttribute("data-setting-select")
|
||||
) {
|
||||
const el = e.target;
|
||||
this.showPopup(el, "select");
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("pointerout", (e) => {
|
||||
try {
|
||||
const popupEl = e.target
|
||||
.closest("div")
|
||||
.querySelector("div[data-disabled-info]");
|
||||
popupEl.remove();
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
showPopup(el, type = "input") {
|
||||
if (!el.hasAttribute("disabled")) return;
|
||||
const method = el.getAttribute("data-default-method");
|
||||
const popupHTML = `
|
||||
<div data-disabled-info class="${
|
||||
type === "select" ? "translate-y-2" : ""
|
||||
} bg-blue-500 absolute right-2 rounded-lg px-2 py-1 z-20 dark:brightness-90">
|
||||
<p class="m-0 text-xs text-white dark:text-gray-100">disabled by ${method}</p>
|
||||
</div>`;
|
||||
el.insertAdjacentHTML("beforebegin", popupHTML);
|
||||
}
|
||||
}
|
||||
|
||||
export { Checkbox, Select, Password, DisabledPop };
|
||||
class Checkbox {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
//prevent default checkbox behavior
|
||||
try {
|
||||
//case a related checkbox element is clicked and checkbox is enabled
|
||||
if (
|
||||
e.target.closest("div").hasAttribute("data-checkbox-handler") &&
|
||||
!e.target
|
||||
.closest("div")
|
||||
.querySelector('input[type="checkbox"]')
|
||||
.hasAttribute("disabled")
|
||||
) {
|
||||
//get related checkbox
|
||||
const checkboxEl = e.target
|
||||
.closest("div")
|
||||
.querySelector('input[type="checkbox"]');
|
||||
|
||||
const prevValue = checkboxEl.getAttribute("value");
|
||||
|
||||
//set attribute value for new state
|
||||
prevValue === "no"
|
||||
? checkboxEl.setAttribute("value", "yes")
|
||||
: checkboxEl.setAttribute("value", "no");
|
||||
|
||||
//set custom input hidden value
|
||||
const newValue = checkboxEl.getAttribute("value");
|
||||
newValue === "yes"
|
||||
? checkboxEl.setAttribute("aria-checked", "true")
|
||||
: checkboxEl.setAttribute("aria-checked", "false");
|
||||
|
||||
//force checked for submit
|
||||
checkboxEl.checked = true;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Select {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
//CASE NO BTN SELECT CLICKED
|
||||
try {
|
||||
if (!e.target.closest("button")) {
|
||||
const selectEls = document.querySelectorAll(
|
||||
"div[data-setting-select-dropdown]",
|
||||
);
|
||||
selectEls.forEach((select) => {
|
||||
select.classList.add("hidden");
|
||||
select.classList.remove("flex");
|
||||
});
|
||||
const btnEls = document.querySelectorAll(
|
||||
"button[data-setting-select]",
|
||||
);
|
||||
btnEls.forEach((btn) => {
|
||||
const dropdownChevron = btn.querySelector(
|
||||
`svg[data-setting-select]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
});
|
||||
}
|
||||
} catch (err) {}
|
||||
//SELECT BTN LOGIC
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute(`data-setting-select`) &&
|
||||
!e.target.closest("button").hasAttribute(`disabled`)
|
||||
) {
|
||||
const btnEl = e.target.closest("button");
|
||||
this.toggleSelectBtn(btnEl);
|
||||
}
|
||||
} catch (err) {}
|
||||
//SELECT DROPDOWN BTN LOGIC
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-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[data-select-container]")
|
||||
.querySelector(`button[data-setting-select]`);
|
||||
|
||||
selectCustom.querySelector(`[data-setting-select-text]`).textContent =
|
||||
btnValue;
|
||||
//add selected to new value
|
||||
|
||||
//change style
|
||||
const dropdownEl = btn.closest(`div[data-setting-select-dropdown]`);
|
||||
dropdownEl.classList.add("hidden");
|
||||
dropdownEl.classList.remove("flex");
|
||||
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
btn.classList.remove("active");
|
||||
});
|
||||
//highlight clicked btn
|
||||
btn.classList.add("active");
|
||||
|
||||
//close dropdown
|
||||
const dropdownChevron = selectCustom.querySelector(
|
||||
`svg[data-setting-select]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
|
||||
//update real select element
|
||||
const realSel = btn
|
||||
.closest("div[data-setting-container]")
|
||||
.querySelector("select");
|
||||
this.updateSelected(realSel, btnValue);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
updateSelected(selectEl, selectedValue) {
|
||||
const options = selectEl.querySelectorAll("option");
|
||||
//remove selected to all
|
||||
options.forEach((option) => {
|
||||
option.removeAttribute("selected");
|
||||
option.selected = false;
|
||||
});
|
||||
//select new one
|
||||
const newOption = selectEl.querySelector(
|
||||
`option[value="${selectedValue}"]`,
|
||||
);
|
||||
newOption.selected = true;
|
||||
newOption.setAttribute("selected", "");
|
||||
}
|
||||
|
||||
toggleSelectBtn(btn) {
|
||||
//toggle dropdown
|
||||
const dropdownEl = btn
|
||||
.closest("div")
|
||||
.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");
|
||||
}
|
||||
}
|
||||
|
||||
class Password {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-setting-password")) {
|
||||
const btn = e.target.closest("button");
|
||||
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);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
showOppositeBtn(btnEl, action) {
|
||||
const btnEls = this.getBtns(btnEl);
|
||||
const opposite = action === "visible" ? "invisible" : "visible";
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
const action = btn.getAttribute("data-setting-password");
|
||||
|
||||
if (action === opposite) {
|
||||
btn.classList.add("flex");
|
||||
btn.classList.remove("hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setValDisplay(action, inp) {
|
||||
if (action === "visible") inp.setAttribute("type", "text");
|
||||
if (action === "invisible") inp.setAttribute("type", "password");
|
||||
}
|
||||
|
||||
hiddenBtns(btnEl) {
|
||||
const btnEls = this.getBtns(btnEl);
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
btn.classList.add("hidden");
|
||||
btn.classList.remove("flex");
|
||||
});
|
||||
}
|
||||
|
||||
getBtns(btnEl) {
|
||||
return btnEl
|
||||
.closest("[data-setting-container]")
|
||||
.querySelectorAll("button[data-setting-password]");
|
||||
}
|
||||
}
|
||||
|
||||
class DisabledPop {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("pointerover", (e) => {
|
||||
//for checkbox and regular inputs
|
||||
if (e.target.tagName === "INPUT") {
|
||||
const el = e.target;
|
||||
this.showPopup(el, "input");
|
||||
}
|
||||
//for select custom
|
||||
if (
|
||||
e.target.tagName === "BUTTON" &&
|
||||
e.target.hasAttribute("data-setting-select")
|
||||
) {
|
||||
const el = e.target;
|
||||
this.showPopup(el, "select");
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("pointerout", (e) => {
|
||||
try {
|
||||
const popupEl = e.target
|
||||
.closest("div")
|
||||
.querySelector("div[data-disabled-info]");
|
||||
popupEl.remove();
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
showPopup(el, type = "input") {
|
||||
if (!el.hasAttribute("disabled")) return;
|
||||
const method = el.getAttribute("data-default-method");
|
||||
const popupHTML = `
|
||||
<div data-disabled-info class="${
|
||||
type === "select" ? "translate-y-2" : ""
|
||||
} bg-blue-500 absolute right-2 rounded-lg px-2 py-1 z-20 dark:brightness-90">
|
||||
<p class="m-0 text-xs text-white dark:text-gray-100">disabled by ${method}</p>
|
||||
</div>`;
|
||||
el.insertAdjacentHTML("beforebegin", popupHTML);
|
||||
}
|
||||
}
|
||||
|
||||
export { Checkbox, Select, Password, DisabledPop };
|
||||
|
|
|
@ -1,239 +1,239 @@
|
|||
class Popover {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("pointerover", (e) => {
|
||||
//POPOVER LOGIC
|
||||
try {
|
||||
if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) {
|
||||
this.showPopover(e.target);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
|
||||
window.addEventListener("pointerout", (e) => {
|
||||
//POPOVER LOGIC
|
||||
try {
|
||||
if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) {
|
||||
this.hidePopover(e.target);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
showPopover(el) {
|
||||
const btn = el.closest("svg");
|
||||
//toggle curr popover
|
||||
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(`[data-popover-content]`);
|
||||
popover.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
class Tabs {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
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("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);
|
||||
//show content
|
||||
this.hideAllSettings(container);
|
||||
this.showSettingClicked(container, tabAtt);
|
||||
//close dropdown and change btn textcontent on mobile
|
||||
this.setDropBtnText(container, tabAtt);
|
||||
this.closeDropdown(container);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-tab-dropdown-btn")) {
|
||||
const dropBtn = e.target.closest("button");
|
||||
const container = dropBtn.closest("div[data-service-content]");
|
||||
this.toggleDropdown(container);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
resetTabsStyle(container) {
|
||||
//reset desktop style
|
||||
const tabsDesktop = container.querySelectorAll("button[data-tab-handler]");
|
||||
tabsDesktop.forEach((tab) => {
|
||||
tab.classList.remove("active");
|
||||
});
|
||||
//reset mobile style
|
||||
const tabsMobile = container.querySelectorAll(
|
||||
"button[data-tab-handler-mobile]"
|
||||
);
|
||||
tabsMobile.forEach((tab) => {
|
||||
tab.classList.remove("active");
|
||||
});
|
||||
}
|
||||
|
||||
highlightClicked(container, tabAtt) {
|
||||
//desktop case
|
||||
const tabDesktop = container.querySelector(
|
||||
`button[data-tab-handler='${tabAtt}']`
|
||||
);
|
||||
tabDesktop.classList.add("active");
|
||||
|
||||
//mobile case
|
||||
const tabMobile = container.querySelector(
|
||||
`button[data-tab-handler-mobile='${tabAtt}']`
|
||||
);
|
||||
tabMobile.classList.add("active");
|
||||
}
|
||||
|
||||
hideAllSettings(container) {
|
||||
const plugins = container.querySelectorAll("[data-plugin-item]");
|
||||
plugins.forEach((plugin) => {
|
||||
plugin.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
showSettingClicked(container, tabAtt) {
|
||||
const plugin = container.querySelector(`[data-plugin-item='${tabAtt}']`);
|
||||
plugin.classList.remove("hidden");
|
||||
}
|
||||
|
||||
setDropBtnText(container, tabAtt) {
|
||||
const dropBtn = container.querySelector("[data-tab-dropdown-btn]");
|
||||
dropBtn.querySelector("span").textContent = tabAtt;
|
||||
}
|
||||
|
||||
closeDropdown(container) {
|
||||
const dropdown = container.querySelector("[data-tab-dropdown]");
|
||||
dropdown.classList.add("hidden");
|
||||
dropdown.classList.remove("flex");
|
||||
}
|
||||
|
||||
toggleDropdown(container) {
|
||||
const dropdown = container.querySelector("[data-tab-dropdown]");
|
||||
dropdown.classList.toggle("hidden");
|
||||
dropdown.classList.toggle("flex");
|
||||
}
|
||||
}
|
||||
|
||||
class FormatValue {
|
||||
constructor() {
|
||||
this.inputs = document.querySelectorAll("input");
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.inputs.forEach((inp) => {
|
||||
try {
|
||||
inp.setAttribute("value", inp.getAttribute("value").trim());
|
||||
inp.value = inp.value.trim();
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class FilterSettings {
|
||||
constructor(inputID, container) {
|
||||
this.input = document.querySelector(`input#${inputID}`);
|
||||
//DESKTOP
|
||||
this.container = document.querySelector(container);
|
||||
this.deskTabs = this.container.querySelectorAll(`[data-tab-handler]`);
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.input.addEventListener("input", () => {
|
||||
this.resetFilter();
|
||||
//get inp format
|
||||
const inpValue = this.input.value.trim().toLowerCase();
|
||||
//loop all tabs
|
||||
this.deskTabs.forEach((tab) => {
|
||||
//get settings of tabs except multiples
|
||||
const settings = this.getSettingsFromTab(tab);
|
||||
|
||||
//compare total count to currCount to determine
|
||||
//if tabs need to be hidden
|
||||
const settingCount = settings.length;
|
||||
let hiddenCount = 0;
|
||||
settings.forEach((setting) => {
|
||||
try {
|
||||
const title = setting
|
||||
.querySelector("h5")
|
||||
.textContent.trim()
|
||||
.toLowerCase();
|
||||
if (!title.includes(inpValue)) {
|
||||
setting.classList.add("hidden");
|
||||
hiddenCount++;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
//case no setting match, hidden tab and content
|
||||
if (settingCount === hiddenCount) {
|
||||
const tabName = tab.getAttribute(`data-tab-handler`);
|
||||
//hide mobile and desk tabs
|
||||
tab.classList.add("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-tab-handler-mobile="${tabName}"]`)
|
||||
.classList.add("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-plugin-item=${tabName}]`)
|
||||
.querySelector("[data-setting-header]")
|
||||
.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
resetFilter() {
|
||||
this.deskTabs.forEach((tab) => {
|
||||
const tabName = tab.getAttribute(`data-tab-handler`);
|
||||
//hide mobile and desk tabs
|
||||
tab.classList.remove("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-tab-handler-mobile="${tabName}"]`)
|
||||
.classList.remove("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-plugin-item=${tabName}]`)
|
||||
.querySelector("[data-setting-header]")
|
||||
.classList.remove("hidden");
|
||||
const settings = this.getSettingsFromTab(tab);
|
||||
settings.forEach((setting) => {
|
||||
setting.classList.remove("hidden");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getSettingsFromTab(tabEl) {
|
||||
const tabName = tabEl.getAttribute(`data-tab-handler`);
|
||||
const settingContainer = this.container
|
||||
.querySelector(`[data-plugin-item="${tabName}"]`)
|
||||
.querySelector(`[data-plugin-settings]`);
|
||||
const settings = settingContainer.querySelectorAll(
|
||||
"[data-setting-container]"
|
||||
);
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
export { Popover, Tabs, FormatValue, FilterSettings };
|
||||
class Popover {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("pointerover", (e) => {
|
||||
//POPOVER LOGIC
|
||||
try {
|
||||
if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) {
|
||||
this.showPopover(e.target);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
|
||||
window.addEventListener("pointerout", (e) => {
|
||||
//POPOVER LOGIC
|
||||
try {
|
||||
if (e.target.closest("svg").hasAttribute(`data-popover-btn`)) {
|
||||
this.hidePopover(e.target);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
showPopover(el) {
|
||||
const btn = el.closest("svg");
|
||||
//toggle curr popover
|
||||
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(`[data-popover-content]`);
|
||||
popover.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
class Tabs {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
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("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);
|
||||
//show content
|
||||
this.hideAllSettings(container);
|
||||
this.showSettingClicked(container, tabAtt);
|
||||
//close dropdown and change btn textcontent on mobile
|
||||
this.setDropBtnText(container, tabAtt);
|
||||
this.closeDropdown(container);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-tab-dropdown-btn")) {
|
||||
const dropBtn = e.target.closest("button");
|
||||
const container = dropBtn.closest("div[data-service-content]");
|
||||
this.toggleDropdown(container);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
resetTabsStyle(container) {
|
||||
//reset desktop style
|
||||
const tabsDesktop = container.querySelectorAll("button[data-tab-handler]");
|
||||
tabsDesktop.forEach((tab) => {
|
||||
tab.classList.remove("active");
|
||||
});
|
||||
//reset mobile style
|
||||
const tabsMobile = container.querySelectorAll(
|
||||
"button[data-tab-handler-mobile]",
|
||||
);
|
||||
tabsMobile.forEach((tab) => {
|
||||
tab.classList.remove("active");
|
||||
});
|
||||
}
|
||||
|
||||
highlightClicked(container, tabAtt) {
|
||||
//desktop case
|
||||
const tabDesktop = container.querySelector(
|
||||
`button[data-tab-handler='${tabAtt}']`,
|
||||
);
|
||||
tabDesktop.classList.add("active");
|
||||
|
||||
//mobile case
|
||||
const tabMobile = container.querySelector(
|
||||
`button[data-tab-handler-mobile='${tabAtt}']`,
|
||||
);
|
||||
tabMobile.classList.add("active");
|
||||
}
|
||||
|
||||
hideAllSettings(container) {
|
||||
const plugins = container.querySelectorAll("[data-plugin-item]");
|
||||
plugins.forEach((plugin) => {
|
||||
plugin.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
showSettingClicked(container, tabAtt) {
|
||||
const plugin = container.querySelector(`[data-plugin-item='${tabAtt}']`);
|
||||
plugin.classList.remove("hidden");
|
||||
}
|
||||
|
||||
setDropBtnText(container, tabAtt) {
|
||||
const dropBtn = container.querySelector("[data-tab-dropdown-btn]");
|
||||
dropBtn.querySelector("span").textContent = tabAtt;
|
||||
}
|
||||
|
||||
closeDropdown(container) {
|
||||
const dropdown = container.querySelector("[data-tab-dropdown]");
|
||||
dropdown.classList.add("hidden");
|
||||
dropdown.classList.remove("flex");
|
||||
}
|
||||
|
||||
toggleDropdown(container) {
|
||||
const dropdown = container.querySelector("[data-tab-dropdown]");
|
||||
dropdown.classList.toggle("hidden");
|
||||
dropdown.classList.toggle("flex");
|
||||
}
|
||||
}
|
||||
|
||||
class FormatValue {
|
||||
constructor() {
|
||||
this.inputs = document.querySelectorAll("input");
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.inputs.forEach((inp) => {
|
||||
try {
|
||||
inp.setAttribute("value", inp.getAttribute("value").trim());
|
||||
inp.value = inp.value.trim();
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class FilterSettings {
|
||||
constructor(inputID, container) {
|
||||
this.input = document.querySelector(`input#${inputID}`);
|
||||
//DESKTOP
|
||||
this.container = document.querySelector(container);
|
||||
this.deskTabs = this.container.querySelectorAll(`[data-tab-handler]`);
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.input.addEventListener("input", () => {
|
||||
this.resetFilter();
|
||||
//get inp format
|
||||
const inpValue = this.input.value.trim().toLowerCase();
|
||||
//loop all tabs
|
||||
this.deskTabs.forEach((tab) => {
|
||||
//get settings of tabs except multiples
|
||||
const settings = this.getSettingsFromTab(tab);
|
||||
|
||||
//compare total count to currCount to determine
|
||||
//if tabs need to be hidden
|
||||
const settingCount = settings.length;
|
||||
let hiddenCount = 0;
|
||||
settings.forEach((setting) => {
|
||||
try {
|
||||
const title = setting
|
||||
.querySelector("h5")
|
||||
.textContent.trim()
|
||||
.toLowerCase();
|
||||
if (!title.includes(inpValue)) {
|
||||
setting.classList.add("hidden");
|
||||
hiddenCount++;
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
//case no setting match, hidden tab and content
|
||||
if (settingCount === hiddenCount) {
|
||||
const tabName = tab.getAttribute(`data-tab-handler`);
|
||||
//hide mobile and desk tabs
|
||||
tab.classList.add("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-tab-handler-mobile="${tabName}"]`)
|
||||
.classList.add("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-plugin-item=${tabName}]`)
|
||||
.querySelector("[data-setting-header]")
|
||||
.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
resetFilter() {
|
||||
this.deskTabs.forEach((tab) => {
|
||||
const tabName = tab.getAttribute(`data-tab-handler`);
|
||||
//hide mobile and desk tabs
|
||||
tab.classList.remove("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-tab-handler-mobile="${tabName}"]`)
|
||||
.classList.remove("hidden");
|
||||
this.container
|
||||
.querySelector(`[data-plugin-item=${tabName}]`)
|
||||
.querySelector("[data-setting-header]")
|
||||
.classList.remove("hidden");
|
||||
const settings = this.getSettingsFromTab(tab);
|
||||
settings.forEach((setting) => {
|
||||
setting.classList.remove("hidden");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getSettingsFromTab(tabEl) {
|
||||
const tabName = tabEl.getAttribute(`data-tab-handler`);
|
||||
const settingContainer = this.container
|
||||
.querySelector(`[data-plugin-item="${tabName}"]`)
|
||||
.querySelector(`[data-plugin-settings]`);
|
||||
const settings = settingContainer.querySelectorAll(
|
||||
"[data-setting-container]",
|
||||
);
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
export { Popover, Tabs, FormatValue, FilterSettings };
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@font-face {
|
||||
font-family: "bootstrap-icons";
|
||||
src: url("./bootstrap-icons.woff2?524846017b983fc8ded9325d94ed40f3")
|
||||
src:
|
||||
url("./bootstrap-icons.woff2?524846017b983fc8ded9325d94ed40f3")
|
||||
format("woff2"),
|
||||
url("./bootstrap-icons.woff?524846017b983fc8ded9325d94ed40f3")
|
||||
format("woff");
|
||||
|
|
Loading…
Reference in New Issue