update no matchinf logic

* no matching script is now a class and can be instanciate easily
* no matching script now handle select filter
* add no matching message and handler on bans, global config, jobs, plugins, reports and services pages
This commit is contained in:
Jordan Blasenhauer 2024-02-26 13:54:36 +01:00
parent 91359394e2
commit 2650273618
12 changed files with 243 additions and 101 deletions

View file

@ -1,3 +1,5 @@
import { CheckNoMatchFilter } from "./utils/settings.js";
class Filter {
constructor(prefix = "bans") {
this.prefix = prefix;
@ -605,3 +607,23 @@ const setDropdown = new Dropdown();
const setFilter = new Filter();
const setUnban = new Unban();
const setModal = new AddBanModal();
const checkPluginKeyword = new CheckNoMatchFilter(
document.querySelector("input#keyword"),
"input",
document
.querySelector("[data-bans-list]")
.querySelectorAll("[data-bans-item]"),
document.querySelector("[data-bans-list-container]"),
document.querySelector("[data-bans-nomatch]"),
);
const checkPluginSelect = new CheckNoMatchFilter(
document.querySelectorAll("button[data-bans-setting-select-dropdown-btn]"),
"select",
document
.querySelector("[data-bans-list]")
.querySelectorAll("[data-bans-item]"),
document.querySelector("[data-bans-list-container]"),
document.querySelector("[data-bans-nomatch]"),
);

View file

@ -3,6 +3,7 @@ import {
Tabs,
FormatValue,
FilterSettings,
CheckNoMatchFilter,
} from "./utils/settings.js";
class Multiple {
@ -34,34 +35,12 @@ const setFilterGlobal = new FilterSettings(
"[data-service-content='settings']",
);
// Hide completely configs card in all plugins hidden
document
.querySelector("input#settings-filter")
.addEventListener("input", () => {
setTimeout(() => {
const tabs = document
.querySelector("[data-global-config-tabs-desktop]")
.querySelectorAll("[data-tab-handler]");
let isAllHidden = true;
for (let i = 0; i < tabs.length; i++) {
const plugin = tabs[i];
if (!plugin.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
const formEl = document.querySelector("[data-global-config-form]");
const noMatchEl = document.querySelector("[data-global-config-nomatch]");
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
}, 20);
});
const checkServiceModalKeyword = new CheckNoMatchFilter(
document.querySelector("input#settings-filter"),
"input",
document
.querySelector("[data-global-config-tabs]")
.querySelectorAll("[data-tab-handler]"),
document.querySelector("[data-global-config-form]"),
document.querySelector("[data-global-config-nomatch]"),
);

View file

@ -1,3 +1,5 @@
import { CheckNoMatchFilter } from "./utils/settings.js";
class Dropdown {
constructor(prefix = "jobs") {
this.prefix = prefix;
@ -376,3 +378,23 @@ class Download {
const setDropdown = new Dropdown("jobs");
const setFilter = new Filter("jobs");
const setDownload = new Download();
const checkPluginKeyword = new CheckNoMatchFilter(
document.querySelector("input#keyword"),
"input",
document
.querySelector("[data-jobs-list]")
.querySelectorAll("[data-jobs-item]"),
document.querySelector("[data-jobs-list-container]"),
document.querySelector("[data-jobs-nomatch]"),
);
const checkPluginSelect = new CheckNoMatchFilter(
document.querySelectorAll("button[data-jobs-setting-select-dropdown-btn]"),
"select",
document
.querySelector("[data-jobs-list]")
.querySelectorAll("[data-jobs-item]"),
document.querySelector("[data-jobs-list-container]"),
document.querySelector("[data-jobs-nomatch]"),
);

View file

@ -1,3 +1,5 @@
import { CheckNoMatchFilter } from "./utils/settings.js";
class Dropdown {
constructor(prefix = "plugins") {
this.prefix = prefix;
@ -512,3 +514,23 @@ const setDropdown = new Dropdown("plugins");
const setFilter = new Filter("plugins");
const setUpload = new Upload();
const setModal = new Modal("plugins");
const checkPluginKeyword = new CheckNoMatchFilter(
document.querySelector("input#keyword"),
"input",
document
.querySelector("[data-plugins-list]")
.querySelectorAll("[data-plugins-type]"),
document.querySelector("[data-plugins-list-container]"),
document.querySelector("[data-plugins-nomatch]"),
);
const checkPluginSelect = new CheckNoMatchFilter(
document.querySelectorAll("button[data-plugins-setting-select-dropdown-btn"),
"select",
document
.querySelector("[data-plugins-list]")
.querySelectorAll("[data-plugins-type]"),
document.querySelector("[data-plugins-list-container]"),
document.querySelector("[data-plugins-nomatch]"),
);

View file

@ -1,3 +1,5 @@
import { CheckNoMatchFilter } from "./utils/settings.js";
class Filter {
constructor(prefix = "reports") {
this.prefix = prefix;
@ -374,3 +376,23 @@ class Dropdown {
const setDropdown = new Dropdown();
const setFilter = new Filter();
const checkPluginKeyword = new CheckNoMatchFilter(
document.querySelector("input#keyword"),
"input",
document
.querySelector("[data-reports-list]")
.querySelectorAll("[data-reports-item]"),
document.querySelector("[data-reports-list-container]"),
document.querySelector("[data-reports-nomatch]"),
);
const checkPluginSelect = new CheckNoMatchFilter(
document.querySelectorAll("button[data-reports-setting-select-dropdown-btn]"),
"select",
document
.querySelector("[data-reports-list]")
.querySelectorAll("[data-reports-item]"),
document.querySelector("[data-reports-list-container]"),
document.querySelector("[data-reports-nomatch]"),
);

View file

@ -3,6 +3,7 @@ import {
Tabs,
FormatValue,
FilterSettings,
CheckNoMatchFilter,
} from "./utils/settings.js";
class ServiceModal {
@ -1356,68 +1357,32 @@ const setFilterGlobal = new FilterSettings(
const setMultiple = new Multiple("services");
// Hide / Show no matching message on service modal
document
.querySelector("input#settings-filter")
.addEventListener("input", () => {
setTimeout(() => {
const tabs = document
.querySelector("[data-services-tabs-desktop]")
.querySelectorAll("[data-tab-handler]");
let isAllHidden = true;
for (let i = 0; i < tabs.length; i++) {
const plugin = tabs[i];
if (!plugin.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
const formEl = document.querySelector("[data-services-modal-form]");
const noMatchEl = document.querySelector("[data-services-nomatch]");
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
}, 20);
});
// Hide / Show no matching message for services card
try {
const checkServiceModalKeyword = new CheckNoMatchFilter(
document.querySelector("input#settings-filter"),
"input",
document
.querySelector("input#service-name-keyword")
.addEventListener("input", () => {
setTimeout(() => {
const cards = document.querySelectorAll("[data-services-card]");
let isAllHidden = true;
for (let i = 0; i < cards.length; i++) {
const card = cards[i];
if (!card.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
.querySelector("[data-services-tabs-desktop]")
.querySelectorAll("[data-tab-handler]"),
document.querySelector("[data-services-modal-form]"),
document.querySelector("[data-services-nomatch]"),
);
const formEl = document.querySelector("[data-services-modal-form]");
const noMatchEl = document.querySelector(
"[data-services-nomatch-card]",
);
try {
const checkServiceCardKeyword = new CheckNoMatchFilter(
document.querySelectorAll("input#service-name-keyword"),
"input",
document.querySelectorAll("[data-services-card]"),
false,
document.querySelector("[data-services-nomatch-card]"),
);
if (isAllHidden) {
noMatchEl.classList.remove("hidden");
formEl.classList.add("hidden");
}
if (!isAllHidden) {
formEl.classList.remove("hidden");
noMatchEl.classList.add("hidden");
}
}, 20);
});
const checkServiceCardSelect = new CheckNoMatchFilter(
document.querySelectorAll(
"button[data-services-setting-select-dropdown-btn]",
),
"select",
document.querySelectorAll("[data-services-card]"),
false,
document.querySelector("[data-services-nomatch-card]"),
);
} catch (e) {}

View file

@ -241,4 +241,58 @@ class FilterSettings {
}
}
export { Popover, Tabs, FormatValue, FilterSettings };
class CheckNoMatchFilter {
constructor(input, type, elsToCheck, elContainer, noMatchEl) {
this.input = input;
this.type = type;
this.elsToCheck = elsToCheck;
this.elContainer = elContainer;
this.noMatchEl = noMatchEl;
this.init();
}
init() {
if (!this.input || !this.elsToCheck || !this.noMatchEl) return;
const event = this.type === "input" ? "input" : "click";
if (!this.input.length) {
this.input.addEventListener(event, () => {
this.check();
});
}
if (this.input.length) {
this.input.forEach((inp) => {
inp.addEventListener(event, () => {
this.check();
});
});
}
}
check() {
setTimeout(() => {
let isAllHidden = true;
for (let i = 0; i < this.elsToCheck.length; i++) {
const el = this.elsToCheck[i];
if (!el.classList.contains("hidden")) {
isAllHidden = false;
break;
}
}
if (isAllHidden) {
this.noMatchEl.classList.remove("hidden");
this.elContainer ? this.elContainer.classList.add("hidden") : false;
}
if (!isAllHidden) {
this.elContainer ? this.elContainer.classList.remove("hidden") : false;
this.noMatchEl.classList.add("hidden");
}
}, 20);
}
}
export { Popover, Tabs, FormatValue, FilterSettings, CheckNoMatchFilter };

View file

@ -150,7 +150,21 @@
</div>
</div>
<!-- end filter -->
<div class=" {% if bans|length == 0 %}hidden{% endif %} w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-bans-nomatch
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 stroke-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No bans match</h5>
</div>
</div>
<div data-bans-list-container class=" {% if bans|length == 0 %}hidden{% endif %} w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div class="col-span-12">
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">BANS LIST</h5>
</div>
@ -198,7 +212,7 @@
<!-- list -->
<ul class="col-span-12 w-full" data-bans-list>
{% for ban in bans %}
<li data-bans-list-item="{{ ban }}"
<li data-bans-item data-bans-list-item="{{ ban }}"
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
<div data-bans-ban-select
data-checkbox-handler="ban-item-{{ loop.index }}"

View file

@ -131,7 +131,21 @@
</div>
</div>
<!-- end filter -->
<div class="w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-jobs-nomatch
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 stroke-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No jobs match</h5>
</div>
</div>
<div data-jobs-list-container class="w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div class="col-span-12">
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">JOBS LIST</h5>
</div>
@ -183,7 +197,7 @@
{"type" : "check", "filter_name" : "success", "value" : value['success'], "custom_class" : "col-span-1"},
{"type" : "select", "filter_name" : "success", "value" : value['success'], "custom_class" : "col-span-3"},
] %}
<li class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
<li data-jobs-item class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
{% for data in jobs_data %}
{% if data['type'] == "text" %}
<p class="{{ data['custom_class'] }} dark:text-gray-400 dark:opacity-80 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="{{data['value']}}">

View file

@ -148,7 +148,7 @@
</div>
</div>
<!-- end filter -->
<div class="min-h-[55vh] max-h-80 overflow-hidden overflow-y-auto p-4 col-span-12 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-plugins-list-container class="min-h-[55vh] max-h-80 overflow-hidden overflow-y-auto p-4 col-span-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="mb-4 mt-2 font-bold dark:text-white/90 mx-2">LIST</h5>
<div data-plugins-list class="grid grid-cols-12 gap-3">
{% for plugin in plugins %}
@ -225,4 +225,18 @@
{% endif %}
</div>
</div>
<div data-plugins-nomatch
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 stroke-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No plugins match</h5>
</div>
</div>
{% endblock %}

View file

@ -157,7 +157,21 @@
</div>
</div>
<!-- end filter -->
<div class="w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-reports-nomatch
class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div class="col-span-12 flex flex-col justify-center items-center h-fit">
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 stroke-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No reports match</h5>
</div>
</div>
<div data-reports-list-container class="w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div class="col-span-12">
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">REPORTING</h5>
</div>
@ -212,7 +226,7 @@
<!-- list -->
<ul class="col-span-12 w-full" data-reports-list>
{% for report in reports %}
<li class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
<li data-reports-item class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
<p class="text-center flex justify-center dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
data-reports-date="{{ report['date'] }}">{{ report['date'] }}</p>
<p class="flex justify-center dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"

View file

@ -174,7 +174,7 @@ class="hidden w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 c
class="mb-2 w-8 h-8 stroke-white">
<path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6" />
</svg>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No settings match</h5>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No services match</h5>
</div>
</div>
{% endif %}