mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
commit
710a3bf39f
28 changed files with 897 additions and 1292 deletions
1
.github/workflows/tests-ui-linux.yml
vendored
1
.github/workflows/tests-ui-linux.yml
vendored
|
|
@ -88,7 +88,6 @@ jobs:
|
|||
echo "USE_BUNKERNET=no" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "USE_BLACKLIST=no" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "SEND_ANONYMOUS_REPORT=no" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "DISABLE_DEFAULT_SERVER=yes" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "USE_CLIENT_CACHE=yes" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "USE_GZIP=yes" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo "DATASTORE_MEMORY_SIZE=384m" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
|
|
|
|||
|
|
@ -719,8 +719,7 @@ if __name__ == "__main__":
|
|||
changes = db.check_changes()
|
||||
|
||||
if isinstance(changes, str):
|
||||
logger.error(f"An error occurred when checking for changes in the database : {changes}")
|
||||
stop(1)
|
||||
raise Exception(f"An error occurred when checking for changes in the database : {changes}")
|
||||
|
||||
# check if the plugins have changed since last time
|
||||
if changes["pro_plugins_changed"]:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -20,6 +20,9 @@ class ServiceModal {
|
|||
"[data-services-modal-error-msg]",
|
||||
);
|
||||
this.modalCard = this.modal.querySelector("[data-services-modal-card]");
|
||||
this.switchModeBtn = this.modal.querySelector(
|
||||
"[data-toggle-settings-mode-btn]",
|
||||
);
|
||||
//modal forms
|
||||
this.formNewEdit = this.modal.querySelector("[data-services-modal-form]");
|
||||
this.formDelete = this.modal.querySelector(
|
||||
|
|
@ -88,6 +91,15 @@ class ServiceModal {
|
|||
} catch (err) {}
|
||||
});
|
||||
|
||||
this.switchModeBtn.addEventListener("click", () => {
|
||||
const currMode = this.switchModeBtn.getAttribute(
|
||||
"data-toggle-settings-mode-btn",
|
||||
);
|
||||
const switchMode = currMode === "advanced" ? "simple" : "advanced";
|
||||
|
||||
this.setSettingMode(switchMode);
|
||||
});
|
||||
|
||||
this.container.addEventListener("click", (e) => {
|
||||
//edit action
|
||||
try {
|
||||
|
|
@ -409,6 +421,34 @@ class ServiceModal {
|
|||
});
|
||||
}
|
||||
|
||||
// Switch settings mode and update button
|
||||
setSettingMode(mode) {
|
||||
const elsToShow =
|
||||
mode === "advanced"
|
||||
? document.querySelectorAll("[data-advanced]")
|
||||
: document.querySelectorAll("[data-simple]");
|
||||
const elsToHide =
|
||||
mode === "advanced"
|
||||
? document.querySelectorAll("[data-simple]")
|
||||
: document.querySelectorAll("[data-advanced]");
|
||||
elsToHide.forEach((setting) => {
|
||||
setting.classList.add("!hidden");
|
||||
});
|
||||
elsToShow.forEach((setting) => {
|
||||
setting.classList.remove("!hidden");
|
||||
});
|
||||
// button
|
||||
this.switchModeBtn.setAttribute("data-toggle-settings-mode-btn", mode);
|
||||
const switchEls = this.switchModeBtn.querySelectorAll(
|
||||
"[data-toggle-settings-mode]",
|
||||
);
|
||||
switchEls.forEach((el) => {
|
||||
el.getAttribute("data-toggle-settings-mode") === mode
|
||||
? el.classList.remove("hidden")
|
||||
: el.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
checkServNameInput() {
|
||||
const serverNameInput = document.querySelector('input[name="SERVER_NAME"]');
|
||||
|
||||
|
|
@ -582,8 +622,10 @@ class ServiceModal {
|
|||
}
|
||||
|
||||
openModal() {
|
||||
//switch to first setting
|
||||
document.querySelector("button[data-tab-select-handler]").click();
|
||||
try {
|
||||
//switch to first setting
|
||||
document.querySelector("button[data-tab-select-handler]").click();
|
||||
} catch (e) {}
|
||||
//show modal el
|
||||
this.modal.classList.add("flex");
|
||||
this.modal.classList.remove("hidden");
|
||||
|
|
|
|||
309
src/ui/templates/bans.html
vendored
309
src/ui/templates/bans.html
vendored
|
|
@ -10,6 +10,8 @@
|
|||
{% if terms.append(ban["term"]) %}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set attribute_name = "bans" %}
|
||||
|
||||
<!-- actions -->
|
||||
<div class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border">
|
||||
<button data-add-ban
|
||||
|
|
@ -41,22 +43,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- info-->
|
||||
{% set bans_info = [
|
||||
{% set infos = [
|
||||
{"name" : "BANS TOTAL", "data" : bans|length|string},
|
||||
{"name" : "TOP REASON", "data" : top_reason|string},
|
||||
] %}
|
||||
<div class="{% if bans|length == 0 %}hidden{% endif %} h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in bans_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
{% set is_info_hidden = True if bans|length == 0 else False %}
|
||||
{% include "card_info.html" %}
|
||||
<!-- filter -->
|
||||
{% set filters = [
|
||||
{
|
||||
|
|
@ -82,190 +74,115 @@
|
|||
"values": terms
|
||||
}
|
||||
] %}
|
||||
<div data-bans-filter
|
||||
class="{% if bans|length == 0 %}hidden{% endif %} h-fit col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-5 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-bans-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="bans-{{ filter['id'] }}"
|
||||
data-name="bans-{{ filter['id'] }}"
|
||||
data-bans-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-bans-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-bans-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-bans-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end filter -->
|
||||
<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 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">
|
||||
{% include "card_filter.html" %}
|
||||
{% include "filter_nomatch.html" %}
|
||||
|
||||
<div data-{{attribute_name}}-list-container class="{% if bans|length == 0 %}hidden{% endif %} overflow-auto w-full 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>
|
||||
<h5 class="mx-2 font-bold dark:text-white/90 mx-2">BANS LIST</h5>
|
||||
</div>
|
||||
<div class=" max-h-100 sm:max-h-125 col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<div data-bans-bans-list>
|
||||
<!-- list container-->
|
||||
{% set bans_headers = [
|
||||
{
|
||||
"name": "Select",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "IP",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Reason",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Ban start",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Ban end",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Remain",
|
||||
"position": "col-span-3"
|
||||
},
|
||||
{
|
||||
"name": "Term",
|
||||
"position": "hidden"
|
||||
}
|
||||
] %}
|
||||
<div class="overflow-hidden min-w-[1150px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
{% for header in bans_headers %}
|
||||
<p class="dark:text-gray-100 h-8 text-sm font-bold {{ header['position'] }} m-0 pb-2 border-b border-gray-400">
|
||||
{{ header['name'] }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-bans-list>
|
||||
{% for ban in bans %}
|
||||
<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 }}"
|
||||
class="relative mb-7 md:mb-0 z-10 ml-2">
|
||||
<label class="sr-only" for="ban-item-{{ loop.index }}">Ban ip {{ loop.index }}</label>
|
||||
<input id="ban-item-{{ loop.index }}"
|
||||
name="ban-item-{{ loop.index }}"
|
||||
data-default-method="ui"
|
||||
data-default-value="no"
|
||||
data-checked="false"
|
||||
id="checkbox-ban-item-{{ loop.index }}"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
value="no" />
|
||||
<svg data-checkbox-handler="ban-item-{{ loop.index }}"
|
||||
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path class="pointer-events-none" d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-bans-ip="{{ ban['ip'] }}">{{ ban['ip'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-bans-reason="{{ ban['reason'] }}">{{ ban['reason'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-bans-ban_start="{{ ban['ban_start'] }}">{{ ban['ban_start'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-bans-ban_end="{{ ban['ban_end'] }}">{{ ban['ban_end'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-3 m-0 my-1"
|
||||
data-bans-remain="{{ ban['remain'] }}">{{ ban['remain'] }}</p>
|
||||
<p class="hidden" data-bans-term="{{ ban['term'] }}">{{ ban['term'] }}</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
<form id="unban-items"
|
||||
action="bans"
|
||||
method="post"
|
||||
class="w-full col-span-12 justify-center flex mt-6 mb-3">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="operation" value="unban">
|
||||
<input data-unban-inp type="hidden" name="data" value="">
|
||||
<button data-unban-btn
|
||||
disabled
|
||||
type="submit"
|
||||
class="valid-btn mr-3 text-base">UNBAN</button>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
class="w-full overflow-auto grid grid-cols-12 col-span-12 p-4 relative">
|
||||
<div class=" max-h-100 sm:max-h-125 col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<div data-{{attribute_name}}-bans-list>
|
||||
<!-- list container-->
|
||||
{% set bans_headers = [
|
||||
{
|
||||
"name": "Select",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "IP",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Reason",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Ban start",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Ban end",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Remain",
|
||||
"position": "col-span-3"
|
||||
},
|
||||
{
|
||||
"name": "Term",
|
||||
"position": "hidden"
|
||||
}
|
||||
] %}
|
||||
<div class="overflow-hidden min-w-[1150px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
{% for header in bans_headers %}
|
||||
<p class="dark:text-gray-100 h-8 text-sm font-bold {{ header['position'] }} m-0 pb-2 border-b border-gray-400">
|
||||
{{ header['name'] }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-{{attribute_name}}-list>
|
||||
{% for ban in bans %}
|
||||
<li data-{{attribute_name}}-item
|
||||
data-{{attribute_name}}-list-item="{{ ban }}"
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5">
|
||||
<div data-{{attribute_name}}-ban-select
|
||||
data-checkbox-handler="ban-item-{{ loop.index }}"
|
||||
class="relative mb-7 md:mb-0 z-10 ml-2">
|
||||
<label class="sr-only" for="ban-item-{{ loop.index }}">Ban ip {{ loop.index }}</label>
|
||||
<input id="ban-item-{{ loop.index }}"
|
||||
name="ban-item-{{ loop.index }}"
|
||||
data-default-method="ui"
|
||||
data-default-value="no"
|
||||
data-checked="false"
|
||||
id="checkbox-ban-item-{{ loop.index }}"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
value="no" />
|
||||
<svg data-checkbox-handler="ban-item-{{ loop.index }}"
|
||||
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path class="pointer-events-none" d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-{{attribute_name}}-ip="{{ ban['ip'] }}">{{ ban['ip'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-{{attribute_name}}-reason="{{ ban['reason'] }}">{{ ban['reason'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-{{attribute_name}}-ban_start="{{ ban['ban_start'] }}">{{ ban['ban_start'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-{{attribute_name}}-ban_end="{{ ban['ban_end'] }}">{{ ban['ban_end'] }}</p>
|
||||
<p class="dark:text-gray-400 text-sm col-span-3 m-0 my-1"
|
||||
data-{{attribute_name}}-remain="{{ ban['remain'] }}">{{ ban['remain'] }}</p>
|
||||
<p class="hidden" data-{{attribute_name}}-term="{{ ban['term'] }}">{{ ban['term'] }}</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
<form id="unban-items"
|
||||
action="bans"
|
||||
method="post"
|
||||
class="w-full col-span-12 justify-center flex mt-6 mb-3">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="operation" value="unban">
|
||||
<input data-unban-inp type="hidden" name="data" value="">
|
||||
<button data-unban-btn
|
||||
disabled
|
||||
type="submit"
|
||||
class="valid-btn mr-3 text-base">UNBAN</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% include "bans_modal.html" %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
65
src/ui/templates/card_filter.html
vendored
Normal file
65
src/ui/templates/card_filter.html
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<div data-{{attribute_name}}-filter
|
||||
class="h-fit col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-4 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-4">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-{{attribute_name}}-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="services-{{ filter['id'] }}"
|
||||
data-name="services-{{ filter['id'] }}"
|
||||
data-{{attribute_name}}-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-{{attribute_name}}-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-{{attribute_name}}-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-{{attribute_name}}-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
15
src/ui/templates/card_info.html
vendored
Normal file
15
src/ui/templates/card_info.html
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{% if not is_info_hidden %}
|
||||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in infos %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p data-info-{{ info['id'] }} role="gridcell" class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
88
src/ui/templates/configs.html
vendored
88
src/ui/templates/configs.html
vendored
|
|
@ -1,6 +1,8 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set configs_info = [
|
||||
{% set attribute_name = "configs" %}
|
||||
|
||||
{% set infos = [
|
||||
{
|
||||
"id": "total-conf",
|
||||
"name": "CONFIGS TOTAL",
|
||||
|
|
@ -12,19 +14,8 @@
|
|||
"data": "unknown"
|
||||
}
|
||||
] %}
|
||||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in configs_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p data-info-{{ info['id'] }} role="gridcell" class="card-detail-item-subtitle">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "card_info.html" %}
|
||||
<!-- end info -->
|
||||
<!-- filter -->
|
||||
{% set filters = [
|
||||
|
|
@ -48,72 +39,9 @@
|
|||
"true"
|
||||
]
|
||||
}
|
||||
] %}
|
||||
<div data-configs-filter
|
||||
class="h-fit col-span-12 md:col-span-8 lg:col-span-5 2xl:col-span-4 3xl:col-span-3 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-configs-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="configs{{ filter['id'] }}"
|
||||
data-name="configs{{ filter['id'] }}"
|
||||
data-configs-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-configs-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-configs-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-configs-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
]
|
||||
%}
|
||||
{% include "card_filter.html" %}
|
||||
<!-- end filter -->
|
||||
{% include "file_manager.html" %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
14
src/ui/templates/filter_nomatch.html
vendored
Normal file
14
src/ui/templates/filter_nomatch.html
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<div data-{{attribute_name}}-nomatch-card data-{{attribute_name}}-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 {{attribute_name.replace('-', ' ').replace('_', ' ')|lower}} match</h5>
|
||||
</div>
|
||||
</div>
|
||||
84
src/ui/templates/global_config.html
vendored
84
src/ui/templates/global_config.html
vendored
|
|
@ -1,5 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set attribute_name = "global-config" %}
|
||||
|
||||
<div data-global-config-tabs-select-container
|
||||
class="z-100 w-full grid grid-cols-12 h-fit max-h-100 sm:max-h-125 col-span-12 md:col-span-6 lg:col-span-4 p-4 relative break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<div data-{{ current_endpoint }}-tabs-select-header class="col-span-12">
|
||||
|
|
@ -43,71 +45,8 @@
|
|||
]
|
||||
}
|
||||
] %}
|
||||
<div data-global-config-filter
|
||||
class="h-fit p-4 col-span-12 md:col-span-6 3xl:col-span-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-global-config-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="global-config-{{ filter['id'] }}"
|
||||
data-name="global-config-{{ filter['id'] }}"
|
||||
data-global-config-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-global-config-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-global-config-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-global-config-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% include "card_filter.html" %}
|
||||
|
||||
<!-- end filter -->
|
||||
<div data-global-config-plugins-container
|
||||
class="col-span-12 gap-y-4 grid grid-cols-12">
|
||||
|
|
@ -130,19 +69,6 @@
|
|||
<!-- end submit -->
|
||||
</form>
|
||||
<!--end form global conf -->
|
||||
<div data-global-config-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 settings match</h5>
|
||||
</div>
|
||||
</div>
|
||||
{% include "filter_nomatch.html" %}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
|
|||
2
src/ui/templates/head.html
vendored
2
src/ui/templates/head.html
vendored
|
|
@ -34,7 +34,7 @@
|
|||
<script defer src="js/utils/flatpickr.js" nonce="{{ script_nonce }}"></script>
|
||||
<script type="module" src="js/logs.js" nonce="{{ script_nonce }}"></script>
|
||||
<link rel="stylesheet"
|
||||
|
||||
|
||||
href="css/datepicker-foundation.css" />
|
||||
{% elif current_endpoint == "jobs" %}
|
||||
<script type="module" src="js/jobs.js" nonce="{{ script_nonce }}"></script>
|
||||
|
|
|
|||
139
src/ui/templates/jobs.html
vendored
139
src/ui/templates/jobs.html
vendored
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set attribute_name = "jobs" %}
|
||||
{% set run_times = ["all"] %}
|
||||
{% for job_name, value in jobs.items() %}
|
||||
{% if value['every'] not in run_times %}
|
||||
|
|
@ -7,22 +8,13 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- info-->
|
||||
{% set jobs_info = [
|
||||
{% set infos = [
|
||||
{"name" : "JOBS TOTAL", "data" : jobs|length|string},
|
||||
{"name" : "JOBS ERRORS", "data" : jobs_errors|string},
|
||||
] %}
|
||||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in jobs_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
]
|
||||
%}
|
||||
{% include "card_info.html" %}
|
||||
|
||||
<!-- filter -->
|
||||
{% set filters = [
|
||||
{
|
||||
|
|
@ -63,91 +55,14 @@
|
|||
"values": run_times
|
||||
}
|
||||
] %}
|
||||
<div data-jobs-filter
|
||||
class="h-fit col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-5 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-jobs-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="jobs-{{ filter['id'] }}"
|
||||
data-name="jobs-{{ filter['id'] }}"
|
||||
data-jobs-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-jobs-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-jobs-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-jobs-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end filter -->
|
||||
<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 class="overflow-auto w-full 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">
|
||||
{% include "card_filter.html" %}
|
||||
{% include "filter_nomatch.html" %}
|
||||
|
||||
<div data-{{attribute_name}}-list-container class="overflow-auto w-full 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="mx-4 mt-2 font-bold dark:text-white/90 mx-2">JOBS LIST</h5>
|
||||
<h5 class="mx-2 font-bold dark:text-white/90 mx-2">JOBS LIST</h5>
|
||||
</div>
|
||||
<div data-jobs-list-container
|
||||
<div
|
||||
class="relative min-w-[900px] w-full overflow-auto grid grid-cols-12 max-h-100 sm:max-h-125">
|
||||
|
||||
<div class="col-span-12">
|
||||
|
|
@ -187,7 +102,7 @@
|
|||
{% endfor %}
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-jobs-list>
|
||||
<ul class="col-span-12 w-full" data-{{attribute_name}}-list>
|
||||
{% for job_name, value in jobs.items() %}
|
||||
<!-- job item-->
|
||||
{% set jobs_data = [
|
||||
|
|
@ -198,16 +113,16 @@
|
|||
{"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 data-jobs-item
|
||||
<li data-{{attribute_name}}-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 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="{{ data['value'] }}">
|
||||
<p class="{{ data['custom_class'] }} dark:text-gray-400 text-sm m-0 my-1" data-{{attribute_name}}-{{ data['filter_name'] }}="{{ data['value'] }}">
|
||||
{{ data['value'] }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "check" and data['value'] %}
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="true">
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-{{attribute_name}}-{{ data['filter_name'] }}="true">
|
||||
<svg class="fill-green-500 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
|
|
@ -216,7 +131,7 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
{% if data['type'] == "check" and not data['value'] %}
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-jobs-{{ data['filter_name'] }}="false">
|
||||
<p class="{{ data['custom_class'] }} flex justify-center dark:text-gray-400 text-sm m-0 my-1" data-{{attribute_name}}-{{ data['filter_name'] }}="false">
|
||||
<svg class="fill-red-500 h-5 w-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
|
|
@ -226,15 +141,15 @@
|
|||
{% endif %}
|
||||
{% if data['type'] == "select" %}
|
||||
<div class="{{ data['custom_class'] }} relative dark:text-gray-400 text-sm m-0 my-1"
|
||||
data-jobs-files>
|
||||
data-{{attribute_name}}-files>
|
||||
{% if value['cache'] %}
|
||||
<button data-jobs-setting-select="{{ job_name }}"
|
||||
<button data-{{attribute_name}}-setting-select="{{ job_name }}"
|
||||
class="py-1 text-sm disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left leading-6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span id="jobs-{{ job_name }}"
|
||||
data-name="jobs-{{ job_name }}"
|
||||
data-jobs-setting-select-text="{{ job_name }}">files</span>
|
||||
data-{{attribute_name}}-setting-select-text="{{ job_name }}">files</span>
|
||||
<!-- chevron -->
|
||||
<svg data-jobs-setting-select="{{ job_name }}"
|
||||
<svg data-{{attribute_name}}-setting-select="{{ job_name }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
|
|
@ -243,13 +158,13 @@
|
|||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div data-jobs-setting-select-dropdown="{{ job_name }}"
|
||||
<div data-{{attribute_name}}-setting-select-dropdown="{{ job_name }}"
|
||||
class="hidden z-100 absolute h-full flex-col w-full translate-y-0.5">
|
||||
{% for file in value['cache'] %}
|
||||
<button data-jobs-plugin="{{ value['plugin_id'] }}"
|
||||
data-jobs-download="{{ job_name }}"
|
||||
data-jobs-file="{{ file['file_name'] }}"
|
||||
data-jobs-setting-select-dropdown-btn="{{ job_name }}"
|
||||
<button data-{{attribute_name}}-plugin="{{ value['plugin_id'] }}"
|
||||
data-{{attribute_name}}-download="{{ job_name }}"
|
||||
data-{{attribute_name}}-file="{{ file['file_name'] }}"
|
||||
data-{{attribute_name}}-setting-select-dropdown-btn="{{ job_name }}"
|
||||
value="files"
|
||||
class="{% if loop.index == loop.length %}rounded-b-lg {% endif %}{% if loop.first %}rounded-t-lg{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 bg-white dark:bg-slate-700 text-gray-700">
|
||||
<span class="flex justify-start items-center">
|
||||
|
|
@ -281,5 +196,5 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock content %}
|
||||
|
|
|
|||
1
src/ui/templates/logs.html
vendored
1
src/ui/templates/logs.html
vendored
|
|
@ -256,6 +256,7 @@
|
|||
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No logs to show</h5>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-logs-card
|
||||
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 bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<div class="col-span-12">
|
||||
|
|
|
|||
214
src/ui/templates/plugins.html
vendored
214
src/ui/templates/plugins.html
vendored
|
|
@ -1,28 +1,20 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set attribute_name = "plugins" %}
|
||||
|
||||
{%
|
||||
include "plugins_modal.html" %}
|
||||
<!-- info -->
|
||||
{% set plugins_info = [
|
||||
{% set infos = [
|
||||
{"name" : "TOTAL PLUGINS", "data" : plugins|length|string},
|
||||
{"name" : "INTERNAL PLUGINS", "data" : plugins_count_internal|string},
|
||||
{"name" : "EXTERNAL PLUGINS", "data" : plugins_count_external|string},
|
||||
{"name" : "PRO PLUGINS", "data" : plugins_count_pro|string if is_pro_version else plugins_count_pro|string + ' (preview)'},
|
||||
] %}
|
||||
<div class="h-fit p-4 col-span-12 md:col-span-5 2xl:col-span-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="col-span-12 mb-4 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in plugins_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
{% include "card_info.html" %}
|
||||
|
||||
<!-- upload layout -->
|
||||
<div data-plugins-upload
|
||||
<div data-{{attribute_name}}-upload
|
||||
class="p-4 col-span-12 md:col-span-7 2xl:col-span-4 grid grid-cols-12 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="col-span-12 mb-4 font-bold dark:text-gray-100">UPLOAD / RELOAD</h5>
|
||||
<div class="mx-2 p-0 col-span-12 grid grid-cols-12">
|
||||
|
|
@ -80,139 +72,67 @@
|
|||
]
|
||||
}
|
||||
] %}
|
||||
<div data-plugins-filter
|
||||
class="h-fit p-4 col-span-12 md:col-span-6 2xl:col-span-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-plugins-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="plugins-{{ filter['id'] }}"
|
||||
data-name="plugins-{{ filter['id'] }}"
|
||||
data-plugins-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-plugins-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-plugins-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-plugins-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end filter -->
|
||||
<div data-plugins-list-container
|
||||
class="min-h-[55vh] max-h-80 overflow-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 %}
|
||||
<div data-plugins-type="{{ plugin['type'] }}"
|
||||
class="py-3 min-h-12 relative col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 p-1 flex justify-between items-center transition rounded {% if plugin['type'] != 'pro' or plugin['type'] == 'pro' and is_pro_version %} bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800 {% else %} cursor-not-allowed bg-gray-300 dark:bg-gray-800 {% endif %}">
|
||||
<p data-plugins-content
|
||||
class="{% if plugin['type'] == 'pro' and not is_pro_version %} opacity-80 dark:opacity-60 {% endif %} ml-3 mr-2 break-words mb-0 transition duration-300 ease-in-out text-left text-sm md:text-base text-slate-700 dark:text-gray-200">
|
||||
{{ plugin['name'] }}
|
||||
</p>
|
||||
<div class="flex items-center">
|
||||
{% if plugin['page'] and plugin['type'] != "pro" or (plugin['page'] and plugin['type'] == "pro" and is_pro_version) %}
|
||||
<a aria-label="plugin page link"
|
||||
class="hover:-translate-y-px mx-1"
|
||||
href="{{ request.url_root }}plugins/{{ plugin['id'] }}">
|
||||
<svg class="h-6 w-6 fill-sky-500 dark dark:brightness-90"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512">
|
||||
<path d="M288 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h50.7L169.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L384 141.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H288zM80 64C35.8 64 0 99.8 0 144V400c0 44.2 35.8 80 80 80H336c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v80c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if plugin['type'] == "external" %}
|
||||
<button data-plugins-action="delete"
|
||||
name="{{ plugin['id'] }}"
|
||||
aria-label="delete plugin"
|
||||
class="z-20 mx-2 inline-block font-bold text-left text-white uppercase align-middle transition-all cursor-pointer text-xs ease-in tracking-tight-rem hover:-translate-y-px">
|
||||
<svg class="h-5 w-5 fill-red-500 dark:brightness-90"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512">
|
||||
<path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z" />
|
||||
</svg>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if plugin['type'] == "pro" %}
|
||||
<a {% if not is_pro_version %}target="_blank" rel="noopener"{% endif %}
|
||||
aria-label="pro plugin"
|
||||
class="hover:-translate-y-px mx-1 -translate-y-0.5"
|
||||
href="{% if not is_pro_version %}https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro{% else %}javascript:void(0){% endif %}">
|
||||
<svg class="h-6 w-6 dark:brightness-90"
|
||||
viewBox="0 0 48 46"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="fill-yellow-500" d="M43.218 28.2327L43.6765 23.971C43.921 21.6973 44.0825 20.1957 43.9557 19.2497L44 19.25C46.071 19.25 47.75 17.5711 47.75 15.5C47.75 13.4289 46.071 11.75 44 11.75C41.929 11.75 40.25 13.4289 40.25 15.5C40.25 16.4366 40.5935 17.2931 41.1613 17.9503C40.346 18.4535 39.2805 19.515 37.6763 21.1128C36.4405 22.3438 35.8225 22.9593 35.1333 23.0548C34.7513 23.1075 34.3622 23.0532 34.0095 22.898C33.373 22.6175 32.9485 21.8567 32.0997 20.335L27.6262 12.3135C27.1025 11.3747 26.6642 10.5889 26.2692 9.95662C27.89 9.12967 29 7.44445 29 5.5C29 2.73857 26.7615 0.5 24 0.5C21.2385 0.5 19 2.73857 19 5.5C19 7.44445 20.11 9.12967 21.7308 9.95662C21.3358 10.589 20.8975 11.3746 20.3738 12.3135L15.9002 20.335C15.0514 21.8567 14.627 22.6175 13.9905 22.898C13.6379 23.0532 13.2487 23.1075 12.8668 23.0548C12.1774 22.9593 11.5595 22.3438 10.3238 21.1128C8.71968 19.515 7.6539 18.4535 6.83882 17.9503C7.4066 17.2931 7.75 16.4366 7.75 15.5C7.75 13.4289 6.07107 11.75 4 11.75C1.92893 11.75 0.25 13.4289 0.25 15.5C0.25 17.5711 1.92893 19.25 4 19.25L4.04428 19.2497C3.91755 20.1957 4.07905 21.6973 4.32362 23.971L4.782 28.2327C5.03645 30.5982 5.24802 32.849 5.50717 34.875H42.4928C42.752 32.849 42.9635 30.5982 43.218 28.2327Z" fill="#1C274C" />
|
||||
<path class="fill-yellow-500" d="M21.2803 45.5H26.7198C33.8098 45.5 37.3545 45.5 39.7198 43.383C40.7523 42.4588 41.4057 40.793 41.8775 38.625H6.1224C6.59413 40.793 7.24783 42.4588 8.2802 43.383C10.6454 45.5 14.1903 45.5 21.2803 45.5Z" fill="#1C274C" />
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</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>
|
||||
{% include "card_filter.html" %}
|
||||
{% include "filter_nomatch.html" %}
|
||||
|
||||
<div data-{{attribute_name}}-list-container class="overflow-auto w-full 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="mx-2 font-bold dark:text-white/90 mx-2">PLUGINS LIST</h5>
|
||||
</div>
|
||||
<div
|
||||
class="min-h-[55vh] max-h-80 overflow-auto p-2 col-span-12 relative">
|
||||
<div data-{{attribute_name}}-list class="grid grid-cols-12 gap-3">
|
||||
{% for plugin in plugins %}
|
||||
<div data-{{attribute_name}}-type="{{ plugin['type'] }}"
|
||||
class="py-3 min-h-12 relative col-span-12 sm:col-span-6 2xl:col-span-4 3xl:col-span-3 p-1 flex justify-between items-center transition rounded {% if plugin['type'] != 'pro' or plugin['type'] == 'pro' and is_pro_version %} bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800 {% else %} cursor-not-allowed bg-gray-300 dark:bg-gray-800 {% endif %}">
|
||||
<p data-{{attribute_name}}-content
|
||||
class="{% if plugin['type'] == 'pro' and not is_pro_version %} opacity-80 dark:opacity-60 {% endif %} ml-3 mr-2 break-words mb-0 transition duration-300 ease-in-out text-left text-sm md:text-base text-slate-700 dark:text-gray-200">
|
||||
{{ plugin['name'] }}
|
||||
</p>
|
||||
<div class="flex items-center">
|
||||
{% if plugin['page'] and plugin['type'] != "pro" or (plugin['page'] and plugin['type'] == "pro" and is_pro_version) %}
|
||||
<a aria-label="plugin page link"
|
||||
class="hover:-translate-y-px mx-1"
|
||||
href="{{ request.url_root }}plugins/{{ plugin['id'] }}">
|
||||
<svg class="h-6 w-6 fill-sky-500 dark dark:brightness-90"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512">
|
||||
<path d="M288 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h50.7L169.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L384 141.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H288zM80 64C35.8 64 0 99.8 0 144V400c0 44.2 35.8 80 80 80H336c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v80c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if plugin['type'] == "external" %}
|
||||
<button data-{{attribute_name}}-action="delete"
|
||||
name="{{ plugin['id'] }}"
|
||||
aria-label="delete plugin"
|
||||
class="z-20 mx-2 inline-block font-bold text-left text-white uppercase align-middle transition-all cursor-pointer text-xs ease-in tracking-tight-rem hover:-translate-y-px">
|
||||
<svg class="h-5 w-5 fill-red-500 dark:brightness-90"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512">
|
||||
<path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z" />
|
||||
</svg>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if plugin['type'] == "pro" %}
|
||||
<a {% if not is_pro_version %}target="_blank" rel="noopener"{% endif %}
|
||||
aria-label="pro plugin"
|
||||
class="hover:-translate-y-px mx-1 -translate-y-0.5"
|
||||
href="{% if not is_pro_version %}https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro{% else %}javascript:void(0){% endif %}">
|
||||
<svg class="h-6 w-6 dark:brightness-90"
|
||||
viewBox="0 0 48 46"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="fill-yellow-500" d="M43.218 28.2327L43.6765 23.971C43.921 21.6973 44.0825 20.1957 43.9557 19.2497L44 19.25C46.071 19.25 47.75 17.5711 47.75 15.5C47.75 13.4289 46.071 11.75 44 11.75C41.929 11.75 40.25 13.4289 40.25 15.5C40.25 16.4366 40.5935 17.2931 41.1613 17.9503C40.346 18.4535 39.2805 19.515 37.6763 21.1128C36.4405 22.3438 35.8225 22.9593 35.1333 23.0548C34.7513 23.1075 34.3622 23.0532 34.0095 22.898C33.373 22.6175 32.9485 21.8567 32.0997 20.335L27.6262 12.3135C27.1025 11.3747 26.6642 10.5889 26.2692 9.95662C27.89 9.12967 29 7.44445 29 5.5C29 2.73857 26.7615 0.5 24 0.5C21.2385 0.5 19 2.73857 19 5.5C19 7.44445 20.11 9.12967 21.7308 9.95662C21.3358 10.589 20.8975 11.3746 20.3738 12.3135L15.9002 20.335C15.0514 21.8567 14.627 22.6175 13.9905 22.898C13.6379 23.0532 13.2487 23.1075 12.8668 23.0548C12.1774 22.9593 11.5595 22.3438 10.3238 21.1128C8.71968 19.515 7.6539 18.4535 6.83882 17.9503C7.4066 17.2931 7.75 16.4366 7.75 15.5C7.75 13.4289 6.07107 11.75 4 11.75C1.92893 11.75 0.25 13.4289 0.25 15.5C0.25 17.5711 1.92893 19.25 4 19.25L4.04428 19.2497C3.91755 20.1957 4.07905 21.6973 4.32362 23.971L4.782 28.2327C5.03645 30.5982 5.24802 32.849 5.50717 34.875H42.4928C42.752 32.849 42.9635 30.5982 43.218 28.2327Z" fill="#1C274C" />
|
||||
<path class="fill-yellow-500" d="M21.2803 45.5H26.7198C33.8098 45.5 37.3545 45.5 39.7198 43.383C40.7523 42.4588 41.4057 40.793 41.8775 38.625H6.1224C6.59413 40.793 7.24783 42.4588 8.2802 43.383C10.6454 45.5 14.1903 45.5 21.2803 45.5Z" fill="#1C274C" />
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
259
src/ui/templates/reports.html
vendored
259
src/ui/templates/reports.html
vendored
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set attribute_name = "reports" %}
|
||||
{% set methods = ["all"] %}
|
||||
{% set codes = ["all"] %}
|
||||
{% set reasons = ["all"] %}
|
||||
|
|
@ -66,25 +67,15 @@
|
|||
</div>
|
||||
<!-- info-->
|
||||
{% if reports|length != 0 %}
|
||||
{% set reports_info = [
|
||||
{% set infos = [
|
||||
{"name" : "REPORTING TOTAL", "data" : total_report|string or "0"},
|
||||
{"name" : "TOP METHOD", "data" : top_method['name']|string},
|
||||
{"name" : "TOP REASON", "data" : top_reason['name']|string},
|
||||
{"name" : "TOP COUNTRY", "data" : top_country['name']|string},
|
||||
{"name" : "TOP STATUS CODE", "data" : top_code['name']|string},
|
||||
] %}
|
||||
<div class=" h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in reports_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
{% include "card_info.html" %}
|
||||
|
||||
<!-- filter -->
|
||||
{% set filters = [
|
||||
{
|
||||
|
|
@ -124,169 +115,95 @@
|
|||
"values": reasons
|
||||
}
|
||||
] %}
|
||||
<div data-reports-filter
|
||||
class="h-fit col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-5 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-reports-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="reports-{{ filter['id'] }}"
|
||||
data-name="reports-{{ filter['id'] }}"
|
||||
data-reports-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-reports-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-reports-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-reports-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end filter -->
|
||||
<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 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">
|
||||
{% include "card_filter.html" %}
|
||||
{% include "filter_nomatch.html" %}
|
||||
|
||||
<div data-{{attribute_name}}-list-container class="overflow-auto w-full 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>
|
||||
<h5 class="mx-2 font-bold dark:text-white/90 mx-2">REPORTING LIST</h5>
|
||||
</div>
|
||||
<div class=" max-h-100 sm:max-h-125 col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="min-w-[1300px] w-full grid grid-cols-12 rounded p-2">
|
||||
{% set reports_header = [
|
||||
{
|
||||
"name": "Date",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "IP",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Method",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "URL",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Code",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "User agent",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Reason",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Data",
|
||||
"position": "col-span-2"
|
||||
}
|
||||
] %}
|
||||
<!-- header-->
|
||||
{% for header in reports_header %}
|
||||
<p class="dark:text-gray-100 flex justify-center h-8 text-sm font-bold {{ header['position'] }} m-0 pb-2 border-b border-gray-400">
|
||||
{{ header['name'] }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-reports-list>
|
||||
{% for report in reports %}
|
||||
<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 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 text-sm col-span-1 m-0 my-1"
|
||||
data-reports-ip="{{ report['ip'] }}">{{ report['ip'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1"
|
||||
data-reports-country="{{ report['country'] }}">{{ report['country'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 "
|
||||
data-reports-method="{{ report['method'] }}">{{ report["method"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-reports-url="{{ report['url'] }}">{{ report['url'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 "
|
||||
data-reports-status="{{ report['status'] }}">{{ report["status"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 "
|
||||
data-reports-user_agent="{{ report['user_agent'] }}">{{ report["user_agent"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 "
|
||||
data-reports-reason="{{ report['reason'] }}">{{ report["reason"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-reports-data="{{ report['data'] }}">{{ report["data"] }}</p>
|
||||
</li>
|
||||
<div
|
||||
class="w-full overflow-auto grid grid-cols-12 col-span-12 p-4 relative">
|
||||
<div class=" max-h-100 sm:max-h-125 col-span-12 overflow-y-auto overflow-x-auto">
|
||||
<!-- list container-->
|
||||
<div class="overflow-hidden min-w-[1300px] w-full grid grid-cols-12 rounded p-2">
|
||||
{% set reports_header = [
|
||||
{
|
||||
"name": "Date",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "IP",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Country",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Method",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "URL",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Code",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "User agent",
|
||||
"position": "col-span-2"
|
||||
},
|
||||
{
|
||||
"name": "Reason",
|
||||
"position": "col-span-1"
|
||||
},
|
||||
{
|
||||
"name": "Data",
|
||||
"position": "col-span-2"
|
||||
}
|
||||
] %}
|
||||
<!-- header-->
|
||||
{% for header in reports_header %}
|
||||
<p class="dark:text-gray-100 flex justify-center h-8 text-sm font-bold {{ header['position'] }} m-0 pb-2 border-b border-gray-400">
|
||||
{{ header['name'] }}
|
||||
</p>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-{{attribute_name}}-list>
|
||||
{% for report in reports %}
|
||||
<li data-{{attribute_name}}-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 text-sm col-span-1 m-0 my-1"
|
||||
data-{{attribute_name}}-date="{{ report['date'] }}">{{ report['date'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1"
|
||||
data-{{attribute_name}}-ip="{{ report['ip'] }}">{{ report['ip'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1"
|
||||
data-{{attribute_name}}-country="{{ report['country'] }}">{{ report['country'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 "
|
||||
data-{{attribute_name}}-method="{{ report['method'] }}">{{ report["method"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-{{attribute_name}}-url="{{ report['url'] }}">{{ report['url'] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 "
|
||||
data-{{attribute_name}}-status="{{ report['status'] }}">{{ report["status"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 "
|
||||
data-{{attribute_name}}-user_agent="{{ report['user_agent'] }}">{{ report["user_agent"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 "
|
||||
data-{{attribute_name}}-reason="{{ report['reason'] }}">{{ report["reason"] }}</p>
|
||||
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1"
|
||||
data-{{attribute_name}}-data="{{ report['data'] }}">{{ report["data"] }}</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
125
src/ui/templates/services.html
vendored
125
src/ui/templates/services.html
vendored
|
|
@ -1,5 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% set attribute_name = "services" %}
|
||||
{% set methods = ["all"] %}
|
||||
{% set states = ["all", "draft", "online"] %}
|
||||
{% set draft_services = [] %}
|
||||
|
|
@ -15,12 +16,12 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- actions -->
|
||||
<div data-services-service
|
||||
<div data-{{attribute_name}}-service
|
||||
class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border">
|
||||
<div data-is-draft class="hidden" data-value="no"></div>
|
||||
<div data-service-method class="hidden" data-value="ui"></div>
|
||||
<button data-services-action="new"
|
||||
data-services-name="service"
|
||||
<button data-{{attribute_name}}-action="new"
|
||||
data-{{attribute_name}}-name="service"
|
||||
type="button"
|
||||
class="dark:bg-green-500/90 duration-300 dark:text-gray-100 w-80 flex justify-center items-center px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-base ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
<span class="mr-2">new service</span>
|
||||
|
|
@ -39,23 +40,14 @@
|
|||
<!-- service info and actions -->
|
||||
<div class="p-0 sm:mx-2 md:mx-4 grid grid-cols-12 col-span-12 md:gap-x-4 gap-y-4 relative min-w-0 break-words rounded-2xl bg-clip-border">
|
||||
<!-- info-->
|
||||
{% set services_info = [
|
||||
{% set infos = [
|
||||
{"name" : "SERVICES TOTAL", "data" : services|length|string},
|
||||
{"name" : "TOTAL DRAFT", "data" : draft_services|length|string},
|
||||
{"name" : "TOTAL ONLINE", "data" : online_services|length|string},
|
||||
] %}
|
||||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
<div role="grid" class="card-detail-container">
|
||||
{% for info in services_info %}
|
||||
<div role="row" class="card-detail-item">
|
||||
<p role="gridcell" class="card-detail-item-title">{{ info['name'] }}</p>
|
||||
<p role="gridcell" class="card-detail-item-subtitle">{{ info['data'] }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end info -->
|
||||
]
|
||||
%}
|
||||
{% include "card_info.html" %}
|
||||
|
||||
<!-- filter -->
|
||||
{% set filters = [
|
||||
{
|
||||
|
|
@ -81,85 +73,8 @@
|
|||
"values": states
|
||||
}
|
||||
] %}
|
||||
<div data-services-filter
|
||||
class="h-fit col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-4 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-4">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-services-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="services-{{ filter['id'] }}"
|
||||
data-name="services-{{ filter['id'] }}"
|
||||
data-services-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-services-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-services-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-services-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white dark:bg-slate-700 {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div data-services-nomatch-card
|
||||
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 services match</h5>
|
||||
</div>
|
||||
</div>
|
||||
{% include "card_filter.html" %}
|
||||
{% include "filter_nomatch.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end service info and actions -->
|
||||
|
|
@ -176,10 +91,10 @@
|
|||
<!-- end filter -->
|
||||
{% for service in services %}
|
||||
{% set id_server_name = service["SERVER_NAME"]['value'].replace(".", "-") %}
|
||||
<div data-services-card
|
||||
data-services-service="{{ service['SERVER_NAME']['value'] }}"
|
||||
<div data-{{attribute_name}}-card
|
||||
data-{{attribute_name}}-service="{{ service['SERVER_NAME']['value'] }}"
|
||||
class="dark:brightness-110 overflow-hidden hover:scale-102 transition col-span-12 lg:col-span-6 3xl:col-span-4 p-4 w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<div data-services-settings
|
||||
<div data-{{attribute_name}}-settings
|
||||
class="hidden"
|
||||
data-value="{{ service['settings'] }}"></div>
|
||||
<div data-old-service-name
|
||||
|
|
@ -192,13 +107,13 @@
|
|||
class="hidden"
|
||||
data-value="{{ service['SERVER_NAME']['method'] }}"></div>
|
||||
<div class="flex justify-between items-start">
|
||||
<h5 data-services-name="{{ service["SERVER_NAME"]['value'] }}"
|
||||
<h5 data-{{attribute_name}}-name="{{ service["SERVER_NAME"]['value'] }}"
|
||||
class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
|
||||
{{ service["SERVER_NAME"]['value'] }}
|
||||
</h5>
|
||||
{% if service.get('IS_DRAFT', "no") == "yes" and service["SERVER_NAME"]['method'] in ["ui", "default"] %}
|
||||
<button class="group relative">
|
||||
<p data-services-state="draft"
|
||||
<p data-{{attribute_name}}-state="draft"
|
||||
class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">
|
||||
Draft
|
||||
</p>
|
||||
|
|
@ -211,7 +126,7 @@
|
|||
</button>
|
||||
{% else %}
|
||||
<button class="group relative">
|
||||
<p data-services-state="online"
|
||||
<p data-{{attribute_name}}-state="online"
|
||||
class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">
|
||||
Online
|
||||
</p>
|
||||
|
|
@ -225,7 +140,7 @@
|
|||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h6 data-services-method="{{ service["SERVER_NAME"]['method'] }}"
|
||||
<h6 data-{{attribute_name}}-method="{{ service["SERVER_NAME"]['method'] }}"
|
||||
class="text-left sm:mb-2 font-semibold text-gray-600 dark:text-white/80">
|
||||
{{ service["SERVER_NAME"]['method'] }}
|
||||
</h6>
|
||||
|
|
@ -350,9 +265,9 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
{% for button in action_buttons %}
|
||||
<button data-services-action="{{ button['name'] }}"
|
||||
<button data-{{attribute_name}}-action="{{ button['name'] }}"
|
||||
aria-label="{{ button['label'] }}"
|
||||
data-services-name="{{ service['SERVER_NAME']['value'] }}"
|
||||
data-{{attribute_name}}-name="{{ service['SERVER_NAME']['value'] }}"
|
||||
class="dark:brightness-90 z-20 mx-1 bg-{{ button['color'] }} hover:bg-{{ button['color'] }}/80 focus:bg-{{ button['color'] }}/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md">
|
||||
{% if button['name'] == "clone" %}
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
|||
14
src/ui/templates/services_modal.html
vendored
14
src/ui/templates/services_modal.html
vendored
|
|
@ -31,6 +31,19 @@
|
|||
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button data-toggle-settings-mode-btn="advanced"
|
||||
class="transition hover:brightness-75 dark:hover:brightness-110 sm:ml-4 flex items-center border border-gray-700 dark:border-gray-300 rounded py-1 px-2">
|
||||
<p data-toggle-settings-mode="simple"
|
||||
class="hidden dark:text-gray-100 mb-0 mr-2 pointer-events-none">Simple</p>
|
||||
<p data-toggle-settings-mode="advanced"
|
||||
class="dark:text-gray-100 mb-0 mr-2 pointer-events-none">Advanced</p>
|
||||
<svg data-toggle-settings-mode="simple" class="hidden translate-y-0.5 w-5 h-5 fill-gray-700 stroke-white/0 dark:fill-gray-300 pointer-events-none" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.84 1.804A1 1 0 0 1 8.82 1h2.36a1 1 0 0 1 .98.804l.331 1.652a6.993 6.993 0 0 1 1.929 1.115l1.598-.54a1 1 0 0 1 1.186.447l1.18 2.044a1 1 0 0 1-.205 1.251l-1.267 1.113a7.047 7.047 0 0 1 0 2.228l1.267 1.113a1 1 0 0 1 .206 1.25l-1.18 2.045a1 1 0 0 1-1.187.447l-1.598-.54a6.993 6.993 0 0 1-1.929 1.115l-.33 1.652a1 1 0 0 1-.98.804H8.82a1 1 0 0 1-.98-.804l-.331-1.652a6.993 6.993 0 0 1-1.929-1.115l-1.598.54a1 1 0 0 1-1.186-.447l-1.18-2.044a1 1 0 0 1 .205-1.251l1.267-1.114a7.05 7.05 0 0 1 0-2.227L1.821 7.773a1 1 0 0 1-.206-1.25l1.18-2.045a1 1 0 0 1 1.187-.447l1.598.54A6.992 6.992 0 0 1 7.51 3.456l.33-1.652ZM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<svg data-toggle-settings-mode="advanced" class="translate-y-0.5 w-5 h-5 fill-gray-700 stroke-white/0 dark:fill-gray-300 pointer-events-none" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path fill-rule="evenodd" d="M8.34 1.804A1 1 0 0 1 9.32 1h1.36a1 1 0 0 1 .98.804l.295 1.473c.497.144.971.342 1.416.587l1.25-.834a1 1 0 0 1 1.262.125l.962.962a1 1 0 0 1 .125 1.262l-.834 1.25c.245.445.443.919.587 1.416l1.473.294a1 1 0 0 1 .804.98v1.361a1 1 0 0 1-.804.98l-1.473.295a6.95 6.95 0 0 1-.587 1.416l.834 1.25a1 1 0 0 1-.125 1.262l-.962.962a1 1 0 0 1-1.262.125l-1.25-.834a6.953 6.953 0 0 1-1.416.587l-.294 1.473a1 1 0 0 1-.98.804H9.32a1 1 0 0 1-.98-.804l-.295-1.473a6.957 6.957 0 0 1-1.416-.587l-1.25.834a1 1 0 0 1-1.262-.125l-.962-.962a1 1 0 0 1-.125-1.262l.834-1.25a6.957 6.957 0 0 1-.587-1.416l-1.473-.294A1 1 0 0 1 1 10.68V9.32a1 1 0 0 1 .804-.98l1.473-.295c.144-.497.342-.971.587-1.416l-.834-1.25a1 1 0 0 1 .125-1.262l.962-.962A1 1 0 0 1 5.38 3.03l1.25.834a6.957 6.957 0 0 1 1.416-.587l.294-1.473ZM13 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="-translate-y-1"
|
||||
aria-label="close modal"
|
||||
|
|
@ -44,6 +57,7 @@
|
|||
</div>
|
||||
|
||||
{% include "services_modal_settings_advanced.html" %}
|
||||
{% include "services_modal_settings_simple.html" %}
|
||||
{% include "services_modal_delete.html" %}
|
||||
|
||||
</div>
|
||||
|
|
|
|||
2
src/ui/templates/services_modal_delete.html
vendored
2
src/ui/templates/services_modal_delete.html
vendored
|
|
@ -21,4 +21,4 @@
|
|||
</div>
|
||||
<!-- end action button-->
|
||||
</form>
|
||||
<!-- end delete form-->
|
||||
<!-- end delete form-->
|
||||
|
|
|
|||
|
|
@ -112,4 +112,4 @@
|
|||
<p data-services-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,33 @@
|
|||
{% set steps = [
|
||||
{
|
||||
"name" : "STEP 1 - SERVER NAME",
|
||||
"description" : "We need this to...",
|
||||
"settings" : [
|
||||
{"plugin_id" : "general", "setting_id": "SERVER_NAME", "label" : "What is your host ?", "levels" : {"standard" : "", "advanced" : "", "high" : ""} },
|
||||
],
|
||||
"configs": [
|
||||
{"name": "my_config_1", "type": "modsec", "data": "..."},
|
||||
{"name": "my_config_2", "type": "server-http", "data": "..."}
|
||||
]
|
||||
},
|
||||
]
|
||||
%}
|
||||
|
||||
<div data-simple class="flex flex-col">
|
||||
<div class="flex flex-col w-full items-end gap-y-3 gap-x-4">
|
||||
<h2 data-simple-step></h2>
|
||||
<p data-simple-description></p>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
</div>
|
||||
{# Get setting for each settings on steps #}
|
||||
|
||||
{% for step in steps %}
|
||||
{% for setting in step.get('settings') %}
|
||||
{% for plugin in plugins %}
|
||||
{% if setting["plugin_id"] == plugin["id"]%}
|
||||
{% if setting.update({"setting" : plugin["settings"][setting["setting_id"]]})%}{%endif%}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- new and edit form -->
|
||||
<form data-simple data-services-simple-modal-form
|
||||
class="w-full h-[90vh] overflow-auto flex flex-col justify-between"
|
||||
class="!hidden w-full h-[90vh] overflow-auto flex flex-col justify-between"
|
||||
id="form-simple-new"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
|
|
@ -19,17 +35,30 @@
|
|||
<input type="hidden" value="" name="simple_OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="simple_is_draft" />
|
||||
<input type="hidden" value="yes" name="simple_is_simple_mode" />
|
||||
{% for step in steps %}
|
||||
<div data-step="{{loop.index}}" class="flex flex-col">
|
||||
<div class="flex flex-col w-full items-start mt-2">
|
||||
<h2 class="ml-2 mr-1 text-xl transition duration-300 ease-in-out font-bold text-md uppercase dark:text-white/90 mb-0" data-simple-step>{{ step.get("name")}}</h2>
|
||||
<p class="ml-2 mr-1 text-sm dark:text-gray-300 mb-1" data-simple-description>{{ step.get("description")}}</p>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
{% include "settings_simple.html" %}
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- action button -->
|
||||
<div class="w-full flex-col items-center justify-center flex mt-10">
|
||||
<div class="flex justify-center">
|
||||
<button data-services-modal-close
|
||||
<button data-services-simple-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-services-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
|
||||
<button data-services-simple-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
<p data-simple-services-modal-error-msg
|
||||
<p data-services-simple-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
29
src/ui/templates/setting_checkbox.html
vendored
Normal file
29
src/ui/templates/setting_checkbox.html
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{% if setting_input["type"] == "check" %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_id = setting_input['id'] %}
|
||||
|
||||
<div data-checkbox-handler="{{ inp_id }}"
|
||||
class="relative mb-7 md:mb-0 z-10 ">
|
||||
<label class="sr-only" for="{{ inp_name_mult }}">{{ inp_name }}</label>
|
||||
<input id="{{ inp_name_mult }}"
|
||||
name="{{ inp_name_mult }}"
|
||||
data-default-method="{% if inp_name in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] %}mode{% else %}{{ global_config[setting]['method'] }}{% endif %}"
|
||||
data-default-value="{{ global_config[inp_name]['value'] }}"
|
||||
{% if inp_name in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] or global_config[inp_name]['method'] != 'ui' and global_config[inp_name]['method'] != 'default' %} disabled {% endif %}
|
||||
data-checked="{% if global_config[inp_name]['value'] == "yes" %}true{% else %}false{% endif %}"
|
||||
checked
|
||||
id="checkbox-{{ inp_id }}"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
data-pattern="{{ setting_input['regex']|safe }}"
|
||||
value="{{ global_config[inp_name]['value'] }}" />
|
||||
<svg data-checkbox-handler="{{ inp_id }}"
|
||||
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path class="pointer-events-none" d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
50
src/ui/templates/setting_header.html
vendored
Normal file
50
src/ui/templates/setting_header.html
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{% if setting_input %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_name_multisite = inp_name + "-multisite_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
|
||||
{% set inp_label = setting_input['label'] %}
|
||||
{% set inp_help = setting_input['help'] %}
|
||||
{% set inp_context = setting_input['context'] %}
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ inp_label }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ inp_name_mult }}">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ inp_name_mult }}">
|
||||
<p class="popover-settings-text">{{ inp_help }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
<!-- end title and info -->
|
||||
{% if inp_context == "multisite" and current_endpoint == "global-config" %}
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ inp_name_multisite }}">
|
||||
<svg class="popover-settings-svg-multiple"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ inp_name_multisite }}">
|
||||
<p class="popover-settings-text">Multisite (apply as default to services without specific value).</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
44
src/ui/templates/setting_input.html
vendored
Normal file
44
src/ui/templates/setting_input.html
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
{% if value["type"] != "select" and value["type"] != "check" %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_type = setting_input['type'] %}
|
||||
{% set inp_default = setting_input['default'] %}
|
||||
|
||||
<div class="relative flex items-center">
|
||||
<label class="sr-only" for="{{ inp_name_mult }}">{{ inp_name }}</label>
|
||||
<input {% if inp_name == "SERVER_NAME" %}required{% endif %}
|
||||
data-default-value="{{ global_config[inp_name]['value'] }}"
|
||||
data-default-method="{{ global_config[inp_name]['method'] }}"
|
||||
data-setting-input
|
||||
{% if global_config[inp_name]['method'] != 'ui' and global_config[inp_name]['method'] != 'default' %}disabled{% endif %}
|
||||
id="{{ inp_name_mult }}"
|
||||
name="{{ inp_name_mult }}"
|
||||
class="regular-input"
|
||||
value="{% if global_config[inp_name]['value'] %} {{ global_config[inp_name]['value'] }} {% else %} {{ inp_default }} {% endif %}"
|
||||
type="{{ inp_type }}"
|
||||
pattern="{{ value['regex']|safe }}" />
|
||||
{% if inp_type == "password" %}
|
||||
<div data-setting-password-container class="absolute flex right-2 h-5 w-5">
|
||||
<button type="button"
|
||||
data-setting-password="visible"
|
||||
class="h-5 w-5 flex items-center align-middle">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512">
|
||||
<path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button"
|
||||
data-setting-password="invisible"
|
||||
class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512">
|
||||
<path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
18
src/ui/templates/setting_invalid.html
vendored
Normal file
18
src/ui/templates/setting_invalid.html
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{% if setting_input %}
|
||||
{% set inp_label = setting_input['label'] %}
|
||||
{% set inp_regex = setting_input['regex'] %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
<!-- invalid feedback -->
|
||||
<div role="alert"
|
||||
data-invalid="{{ inp_name_mult }}"
|
||||
aria-label="show when invalid input"
|
||||
class="block md:absolute hidden md:hidden text-sm text-red-500">
|
||||
Invalid value
|
||||
<span class="sr-only">
|
||||
{{ inp_label }} is invalid and must match this pattern:
|
||||
{{ inp_regex|safe }}
|
||||
</span>
|
||||
</div>
|
||||
<!--end invalid feedback-->
|
||||
{% endif %}
|
||||
84
src/ui/templates/setting_select.html
vendored
Normal file
84
src/ui/templates/setting_select.html
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
{% if value["type"] == "select" %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_default = setting_input['default'] %}
|
||||
{% set inp_items = setting_input['select'] %}
|
||||
{% set inp_id = setting_input['id'] %}
|
||||
|
||||
<!-- default hidden-->
|
||||
<select data-default-method="{{ global_config[inp_name]['method'] }}"
|
||||
data-default-value="{{ inp_default }}"
|
||||
id="{{ inp_name_mult }}"
|
||||
name="{{ inp_name_mult }}"
|
||||
data-setting-select-default="{{ inp_id }}"
|
||||
data-type="form-select"
|
||||
class="hidden">
|
||||
{% for item in inp_items %}
|
||||
<option {% if not item %}label="empty"{% endif %}
|
||||
value="{{ item }}"
|
||||
{% if global_config[inp_name]['value'] and global_config[inp_name]['value'] == item or not global_config[inp_name]['value'] and inp_default == item %} selected{% endif %}>
|
||||
{{ item }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<!-- end default hidden-->
|
||||
<!--custom-->
|
||||
<div data-select-container class="relative">
|
||||
<button {% if global_config[inp_name]['method'] != 'ui' and global_config[inp_name]['method'] != 'default' %}disabled{% endif %}
|
||||
data-setting-select="{{ inp_id }}"
|
||||
data-default-value="{{ global_config[inp_name]['value'] }}"
|
||||
data-default-method="{{ global_config[inp_name]['method'] }}"
|
||||
aria-controls="{{ value['id'] }}-dropdown"
|
||||
type="button"
|
||||
class="custom-select-btn">
|
||||
{% for item in inp_items %}
|
||||
{% if global_config[inp_name]['value'] and
|
||||
global_config[inp_name]['value'] == item %}
|
||||
<span data-setting-select-text="{{ inp_id }}"
|
||||
data-value="{{ global_config[inp_name]['value'] }}">{{ global_config[inp_name]['value'] }}</span>
|
||||
{% elif not global_config[inp_name]['value'] and inp_default == item %}
|
||||
<span aria-description="current value"
|
||||
data-setting-select-text="{{ inp_id }}"
|
||||
data-value="{{ inp_default }}">{{ inp_default }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- chevron -->
|
||||
<svg data-setting-select="{{ inp_id }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
<!-- end chevron -->
|
||||
</button>
|
||||
<!-- dropdown-->
|
||||
<div id="{{ inp_id }}-dropdown"
|
||||
role="listbox"
|
||||
data-setting-select-dropdown="{{ inp_id }}"
|
||||
class="hidden z-[20] fixed h-full flex-col mt-2 max-h-[200px] overflow-auto">
|
||||
{% for item in inp_items %}
|
||||
{% if global_config[inp_name]['value'] and
|
||||
global_config[inp_name]['value'] == item or not global_config[setting_input['name']]['value']
|
||||
and inp_default == item %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
data-setting-select-dropdown-btn="{{ inp_id }}"
|
||||
type="button"
|
||||
class="active custom-dropdown-btn {% if loop.index == 1 %}border-t rounded-t{% endif %} {% if loop.index == loop.length %}rounded-b{% endif %} ">
|
||||
{{ item }}
|
||||
</button>
|
||||
{% else %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
data-setting-select-dropdown-btn="{{ inp_id }}"
|
||||
type="button"
|
||||
class="custom-dropdown-btn {% if loop.index == 1 %}border-t rounded-t{% endif %} {% if loop.index == loop.length %}rounded-b{% endif %} ">
|
||||
{{ item }}
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end custom-->
|
||||
{% endif %}
|
||||
392
src/ui/templates/settings_plugins.html
vendored
392
src/ui/templates/settings_plugins.html
vendored
|
|
@ -52,6 +52,8 @@
|
|||
<div data-plugin-settings class="w-full grid grid-cols-12">
|
||||
<!-- plugin settings not multiple -->
|
||||
{% for setting, value in plugin["settings"].items() %}
|
||||
{% set setting_input = { "name" : setting, "context" : value.get("context"), "help" : value.get("help"), "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : False} %}
|
||||
|
||||
{% if setting != "IS_DRAFT" and (current_endpoint == "global-config" and setting not in ["SERVER_NAME", "IS_LOADING"] or current_endpoint == "services" and value['context'] == "multisite") %}
|
||||
{% if value['multiple'] and value['multiple'] not in multList %}
|
||||
{% if multList.append(value['multiple']) %}{% endif %}
|
||||
|
|
@ -59,203 +61,12 @@
|
|||
{% if not value['multiple'] %}
|
||||
<div data-setting-container data-{{ current_endpoint }}-type="{{ plugin['type'] }}" data-{{ current_endpoint }}-context="{{ value['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ value["id"] }}">
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ value["label"] }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}">
|
||||
<p class="popover-settings-text">{{ value['help'] }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
{% if value["context"] == "multisite" and current_endpoint == "global-config" %}
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}-multiple">
|
||||
<svg class="popover-settings-svg-multiple"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}-multiple">
|
||||
<p class="popover-settings-text">Multisite (apply as default to services without specific value).</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- end title and info -->
|
||||
<!-- input -->
|
||||
{% if value["type"] != "select" and value["type"] != "check" %}
|
||||
<div class="relative flex items-center">
|
||||
<label class="sr-only" for="{{ setting }}">{{ setting }}</label>
|
||||
<input {% if setting == "SERVER_NAME" %}required{% endif %}
|
||||
data-default-value="{{ global_config[setting]['value'] }}"
|
||||
data-default-method="{{ global_config[setting]['method'] }}"
|
||||
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %}disabled{% endif %}
|
||||
id="{{ setting }}"
|
||||
data-setting-input
|
||||
name="{{ setting }}"
|
||||
class="regular-input"
|
||||
value="{% if global_config[setting]['value'] %} {{ global_config[setting]['value'] }} {% else %} {{ value['default'] }} {% endif %}"
|
||||
type="{{ value['type'] }}"
|
||||
pattern="{{ value['regex']|safe }}" />
|
||||
{% if value['type'] == "password" %}
|
||||
<div data-setting-password-container class="absolute flex right-2 h-5 w-5">
|
||||
<button type="button"
|
||||
data-setting-password="visible"
|
||||
class="h-5 w-5 flex items-center align-middle">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512">
|
||||
<path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button"
|
||||
data-setting-password="invisible"
|
||||
class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512">
|
||||
<path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end input -->
|
||||
<!-- select -->
|
||||
{% if value["type"] == "select" %}
|
||||
<!-- default hidden-->
|
||||
<select data-default-method="{{ global_config[setting]['method'] }}"
|
||||
data-default-value="{{ value['default'] }}"
|
||||
id="{{ setting }}"
|
||||
name="{{ setting }}"
|
||||
data-setting-select-default="{{ value['id'] }}"
|
||||
data-type="form-select"
|
||||
id="{{ setting }}"
|
||||
name="{{ setting }}"
|
||||
class="hidden">
|
||||
{% for item in value['select'] %}
|
||||
<option {% if not item %}label="empty"{% endif %}
|
||||
value="{{ item }}"
|
||||
{% if global_config[setting]['value'] and global_config[setting]['value'] == item or not global_config[setting]['value'] and value['default'] == item %} selected{% endif %}>
|
||||
{{ item }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<!-- end default hidden-->
|
||||
<!--custom-->
|
||||
<div data-select-container class="relative">
|
||||
<button {% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %}disabled{% endif %}
|
||||
data-setting-select="{{ value['id'] }}"
|
||||
data-default-value="{{ global_config[setting]['value'] }}"
|
||||
data-default-method="{{ global_config[setting]['method'] }}"
|
||||
aria-controls="{{ value['id'] }}-dropdown"
|
||||
type="button"
|
||||
class="custom-select-btn">
|
||||
{% for item in value['select'] %}
|
||||
{% if global_config[setting]['value'] and
|
||||
global_config[setting]['value'] == item %}
|
||||
<span data-setting-select-text="{{ value['id'] }}"
|
||||
data-value="{{ global_config[setting]['value'] }}">{{ global_config[setting]['value'] }}</span>
|
||||
{% elif not global_config[setting]['value'] and value['default'] == item %}
|
||||
<span aria-description="current value"
|
||||
data-setting-select-text="{{ value['id'] }}"
|
||||
data-value="{{ value['default'] }}">{{ value['default'] }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- chevron -->
|
||||
<svg data-setting-select="{{ value['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
<!-- end chevron -->
|
||||
</button>
|
||||
<!-- dropdown-->
|
||||
<div id="{{ value['id'] }}-dropdown"
|
||||
role="listbox"
|
||||
data-setting-select-dropdown="{{ value['id'] }}"
|
||||
class="hidden z-[20] fixed h-full flex-col mt-2 max-h-[200px] overflow-auto">
|
||||
{% for item in value['select'] %}
|
||||
{% if global_config[setting]['value'] and
|
||||
global_config[setting]['value'] == item or not global_config[setting]['value']
|
||||
and value['default'] == item %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
data-setting-select-dropdown-btn="{{ value['id'] }}"
|
||||
type="button"
|
||||
class="active custom-dropdown-btn {% if loop.index == 1 %}border-t rounded-t{% endif %} {% if loop.index == loop.length %}rounded-b{% endif %} ">
|
||||
{{ item }}
|
||||
</button>
|
||||
{% else %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
data-setting-select-dropdown-btn="{{ value['id'] }}"
|
||||
type="button"
|
||||
class="custom-dropdown-btn {% if loop.index == 1 %}border-t rounded-t{% endif %} {% if loop.index == loop.length %}rounded-b{% endif %} ">
|
||||
{{ item }}
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end custom-->
|
||||
{% endif %}
|
||||
<!-- checkbox -->
|
||||
{% if value["type"] == "check" %}
|
||||
<div data-checkbox-handler="{{ value['id'] }}"
|
||||
class="relative mb-7 md:mb-0 z-10 ">
|
||||
<label class="sr-only" for="{{ setting }}">{{ setting }}</label>
|
||||
<input id="{{ setting }}"
|
||||
name="{{ setting }}"
|
||||
data-default-method="{% if setting in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] %}mode{% else %}{{ global_config[setting]['method'] }}{% endif %}"
|
||||
data-default-value="{{ global_config[setting]['value'] }}"
|
||||
{% if setting in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] or global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %}
|
||||
data-checked="{% if global_config[setting]['value'] == "yes" %}true{% else %}false{% endif %}"
|
||||
checked
|
||||
id="checkbox-{{ value['id'] }}"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
data-pattern="{{ value['regex']|safe }}"
|
||||
value="{{ global_config[setting]['value'] }}" />
|
||||
<svg data-checkbox-handler="{{ value['id'] }}"
|
||||
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path class="pointer-events-none" d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end checkbox -->
|
||||
<!-- invalid feedback -->
|
||||
<div role="alert"
|
||||
data-invalid="{{ setting }}"
|
||||
aria-label="show when invalid input"
|
||||
class="block md:absolute hidden md:hidden text-sm text-red-500">
|
||||
Invalid value
|
||||
<span class="sr-only"> {{ value['label'] }} is invalid and must match this pattern:
|
||||
{{ value['regex']|safe }}</span>
|
||||
</div>
|
||||
<!--end invalid feedback-->
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html" %}
|
||||
{% include "setting_select.html" %}
|
||||
{% include "setting_checkbox.html" %}
|
||||
{% include "setting_invalid.html"%}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
@ -285,192 +96,19 @@
|
|||
<!-- multiple settings -->
|
||||
<div data-{{ current_endpoint }}-settings-multiple="{{ multiple }}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full my-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting, value in plugin["settings"].items() %}
|
||||
{% set setting_input = { "name" : setting, "context" : value.get("context"), "help" : value.get("help"), "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : False} %}
|
||||
|
||||
{# render only setting that match the multiple id and context #}
|
||||
{% if value['multiple'] == multiple and (
|
||||
current_endpoint == "global-config"
|
||||
or current_endpoint == "services" and value['context'] == "multisite"
|
||||
) %}
|
||||
<div data-setting-container="{{ setting }}_SCHEMA" data-{{ current_endpoint }}-type="{{ plugin['type'] }}" data-{{ current_endpoint }}-context="{{ value['context'] }}" class="relative mx-2 md:mx-3 my-2 md:my-3 col-span-12 md:col-span-6 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ value["id"] }}_SCHEMA">
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ value["label"] }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}_SCHEMA">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}_SCHEMA">
|
||||
<p class="popover-settings-text">{{ value['help'] }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
{% if value["context"] == "multisite" and current_endpoint == "global-config" %}
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}-multiple_SCHEMA">
|
||||
<svg class="popover-settings-svg-multiple"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 17.25v-.228a4.5 4.5 0 00-.12-1.03l-2.268-9.64a3.375 3.375 0 00-3.285-2.602H7.923a3.375 3.375 0 00-3.285 2.602l-2.268 9.64a4.5 4.5 0 00-.12 1.03v.228m19.5 0a3 3 0 01-3 3H5.25a3 3 0 01-3-3m19.5 0a3 3 0 00-3-3H5.25a3 3 0 00-3 3m16.5 0h.008v.008h-.008v-.008zm-3 0h.008v.008h-.008v-.008z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}-multiple_SCHEMA">
|
||||
<p class="popover-settings-text">Multisite (apply as default to services without specific value).</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- end title and info -->
|
||||
<!-- input -->
|
||||
{% if value["type"] not in ["select", "check"] %}
|
||||
<div class="relative flex items-center">
|
||||
<label class="sr-only" for="{{ setting }}_SCHEMA">{{ setting }}</label>
|
||||
<input data-default-value="{{ value['default'] }}"
|
||||
data-default-method="default"
|
||||
data-setting-input
|
||||
id="{{ setting }}_SCHEMA"
|
||||
name="{{ setting }}_SCHEMA"
|
||||
class="regular-input"
|
||||
value="{{ value['default'] }}"
|
||||
type="{{ value['type'] }}"
|
||||
pattern="{{ value['regex']|safe }}" />
|
||||
{% if value['type'] == "password" %}
|
||||
<div data-setting-password-container class="absolute flex right-2 h-5 w-5">
|
||||
<button type="button"
|
||||
data-setting-password="visible"
|
||||
class="h-5 w-5 flex items-center align-middle">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512">
|
||||
<path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button"
|
||||
data-setting-password="invisible"
|
||||
class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
|
||||
<svg class="fill-primary pointer-events-none dark:fill-blue-500 hover:brightness-75 transition-all"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 640 512">
|
||||
<path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end input -->
|
||||
<!-- select -->
|
||||
{% if value["type"] == "select" %}
|
||||
<!-- default hidden-->
|
||||
<select data-default-method="default"
|
||||
data-default-value="{{ value['default'] }}"
|
||||
id="{{ setting }}_SCHEMA"
|
||||
name="{{ setting }}_SCHEMA"
|
||||
data-select-default="{{ value['id'] }}"
|
||||
data-type="form-select"
|
||||
id="{{ setting }}"
|
||||
name="{{ setting }}"
|
||||
class="hidden">
|
||||
{% for item in value['select'] %}
|
||||
<option {% if not item %}label="empty"{% endif %}
|
||||
value="{{ item }}"
|
||||
{% if value['default'] == item %}selected{% endif %}>
|
||||
{{ item }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<!-- end default hidden-->
|
||||
<!--custom-->
|
||||
<div data-select-container class="relative">
|
||||
<button data-setting-select="{{ value['id'] }}"
|
||||
data-default-value="{{ value['default'] }}"
|
||||
aria-controls="{{ value['id'] }}-dropdown"
|
||||
type="button"
|
||||
class="custom-select-btn">
|
||||
{% for item in value['select'] %}
|
||||
{% if value['default'] == item %}
|
||||
<span aria-description="current value"
|
||||
data-setting-select-text="{{ value['id'] }}"
|
||||
data-value="{{ value['default'] }}">{{ value['default'] }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- chevron -->
|
||||
<svg data-setting-select="{{ value['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
<!-- end chevron -->
|
||||
</button>
|
||||
<!-- dropdown-->
|
||||
<div id="{{ value['id'] }}-dropdown"
|
||||
role="listbox"
|
||||
data-setting-select-dropdown="{{ value['id'] }}"
|
||||
class="hidden z-[20] fixed h-full flex-col mt-2 max-h-[200px] overflow-auto">
|
||||
{% for item in value['select'] %}
|
||||
{% if value['default'] == item %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
data-setting-select-dropdown-btn="{{ value['id'] }}"
|
||||
class="active custom-dropdown-btn {% if loop.index == 1 %}border-t rounded-t{% endif %} {% if loop.index == loop.length %}rounded-b{% endif %}">
|
||||
{{ item }}
|
||||
</button>
|
||||
{% else %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
data-setting-select-dropdown-btn="{{ value['id'] }}"
|
||||
class="custom-dropdown-btn {% if loop.index == 1 %}border-t rounded-t{% endif %} {% if loop.index == loop.length %}rounded-b{% endif %}">
|
||||
{{ item }}
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end custom-->
|
||||
{% endif %}
|
||||
<!-- checkbox -->
|
||||
{% if value["type"] == "check" %}
|
||||
<div data-checkbox-handler="{{ value['id'] }}"
|
||||
class="relative mb-7 md:mb-0">
|
||||
<label class="sr-only" for="{{ setting }}_SCHEMA">{{ setting }}</label>
|
||||
<input id="{{ setting }}_SCHEMA" name="{{ setting }}_SCHEMA"
|
||||
data-default-method="default"
|
||||
data-default-value="{{ value['default'] }}" {% if value['default'] == 'yes' %} checked {%
|
||||
endif %} id="checkbox-{{ value['id'] }}"
|
||||
class="checkbox" type="checkbox" data-pattern="{{ value['regex']|safe }}"
|
||||
value="{{ value['default'] }}" />
|
||||
<svg data-checkbox-handler="{{ value['id'] }}"
|
||||
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
<!-- end checkbox -->
|
||||
<!-- invalid feedback -->
|
||||
<div role="alert"
|
||||
data-invalid="{{ setting }}_SCHEMA"
|
||||
aria-label="show when invalid input"
|
||||
class="block md:absolute hidden md:hidden text-sm text-red-500">
|
||||
Invalid value
|
||||
<span class="sr-only"> {{ value['label'] }} is invalid and must match this pattern:
|
||||
{{ value['regex']|safe }}</span>
|
||||
</div>
|
||||
<!--end invalid feedback-->
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html"%}
|
||||
{% include "setting_select.html"%}
|
||||
{% include "setting_checkbox.html"%}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
|||
127
src/ui/templates/settings_simple.html
vendored
Normal file
127
src/ui/templates/settings_simple.html
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
{% set current_endpoint = current_endpoint or url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
|
||||
<!-- plugin item -->
|
||||
|
||||
{% for plugin in plugin_simple %}
|
||||
<div data-simple id="{{ plugin['plugin_id'] }}-simple"
|
||||
class="w-full px-1">
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<div class="flex justify-start items-center">
|
||||
<h5 class="my-2 transition duration-300 ease-in-out ml-2 mr-1 font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ plugin['label'] }}
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
{# get number of multiple groups for the plugin #}
|
||||
{% set multList = [] %}
|
||||
<!-- end title and desc -->
|
||||
<div class="w-full grid grid-cols-12">
|
||||
<!-- plugin settings not multiple -->
|
||||
{% for setting, value in plugin["setting"].items() %}
|
||||
{% set setting_input = { "name" : setting, "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : True} %}
|
||||
|
||||
{% if value['multiple'] and value['multiple'] not in multList %}
|
||||
{% if multList.append(value['multiple']) %}{% endif %}
|
||||
{% endif %}
|
||||
{% if not value['multiple'] %}
|
||||
<div data-setting-container data-{{ current_endpoint }}-type="{{ plugin['type'] }}" data-{{ current_endpoint }}-context="{{ value['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ value["id"] }}">
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ value["label"] }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}">
|
||||
<p class="popover-settings-text">{{ value['help'] }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
</div>
|
||||
<!-- end title and info -->
|
||||
{% include "setting_input.html"%}
|
||||
{% include "setting_select.html"%}
|
||||
{% include "setting_checkbox.html"%}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end plugin settings not multiple -->
|
||||
{% if multList|length > 0 %}
|
||||
<h5 data-multiple-title
|
||||
class="transition duration-300 ease-in-out ml-2 font-bold text-[1.1rem] uppercase dark:text-white/90 mt-2 mb-0">
|
||||
multiple settings
|
||||
</h5>
|
||||
{% endif %}
|
||||
{% for multiple in multList %}
|
||||
<!-- plugin multiple handler -->
|
||||
<div data-multiple-handler="{{ multiple }}"
|
||||
class="flex items-center mx-2 mb-2 mt-5 col-span-12 ">
|
||||
<h5 class="input-title max-w-[150px] sm:max-w-[350px]">{{ multiple.replace('-', ' ').replace('_', ' ')|upper }}</h5>
|
||||
<button data-{{ current_endpoint }}-multiple-add="{{ multiple }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Add
|
||||
</button>
|
||||
<button data-{{ current_endpoint }}-multiple-toggle="{{ multiple }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
SHOW / HIDE
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin multiple handler-->
|
||||
<!-- multiple settings -->
|
||||
<div data-{{ current_endpoint }}-settings-multiple="{{ multiple }}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full my-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting, value in plugin["setting"].items() %}
|
||||
{% set setting_input = { "name" : setting, "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : True} %}
|
||||
|
||||
{# render only setting that match the multiple id and context #}
|
||||
{% if value['multiple'] == multiple and (
|
||||
current_endpoint == "global-config"
|
||||
or current_endpoint == "services" and value['context'] == "multisite"
|
||||
) %}
|
||||
<div data-setting-container="{{ setting }}_SCHEMA" data-{{ current_endpoint }}-type="{{ plugin['type'] }}" data-{{ current_endpoint }}-context="{{ value['context'] }}" class="relative mx-2 md:mx-3 my-2 md:my-3 col-span-12 md:col-span-6 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ value["id"] }}_SCHEMA">
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ value["label"] }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}_SCHEMA">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}_SCHEMA">
|
||||
<p class="popover-settings-text">{{ value['help'] }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
</div>
|
||||
|
||||
{% include "setting_input.html"%}
|
||||
{% include "setting_select.html"%}
|
||||
{% include "setting_checkbox.html"%}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div data-multiple-delete-container
|
||||
class="col-span-12 flex justify-center my-4">
|
||||
<button data-{{ current_endpoint }}-multiple-delete="{{ plugin['name'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end multiple settings -->
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end plugin item -->
|
||||
|
|
@ -257,11 +257,11 @@ try:
|
|||
|
||||
reverse_proxy_host_input = safe_get_element(DRIVER, By.ID, "REVERSE_PROXY_HOST")
|
||||
assert isinstance(reverse_proxy_host_input, WebElement), "Reverse proxy host input is not a WebElement"
|
||||
reverse_proxy_host_input.send_keys("http://app1:8080")
|
||||
DRIVER.execute_script(f"""return document.querySelector('input#REVERSE_PROXY_HOST[data-setting-input]').value = 'http://app1:8080' """)
|
||||
|
||||
reverse_proxy_url_input = safe_get_element(DRIVER, By.ID, "REVERSE_PROXY_URL")
|
||||
assert isinstance(reverse_proxy_url_input, WebElement), "Reverse proxy url input is not a WebElement"
|
||||
reverse_proxy_url_input.send_keys("/")
|
||||
DRIVER.execute_script(f"""return document.querySelector('input#REVERSE_PROXY_URL[data-setting-input]').value = '/' """)
|
||||
|
||||
log_info("Set new service values, trying to save ...")
|
||||
|
||||
|
|
@ -404,7 +404,6 @@ try:
|
|||
log_error("The service is still working, retry in 5 seconds ...")
|
||||
sleep(5)
|
||||
|
||||
|
||||
log_info("Create another service app3.example.com to get filters (need at least 4 services on page)")
|
||||
|
||||
try:
|
||||
|
|
|
|||
Loading…
Reference in a new issue