Update pre-commit-hooks and apply it

This commit is contained in:
Théophile Diot 2024-05-31 09:22:52 +01:00
parent 92f3873b8c
commit e76a47b5bc
No known key found for this signature in database
GPG key ID: 248FEA4BAE400D06
36 changed files with 883 additions and 1025 deletions

View file

@ -36,7 +36,7 @@ repos:
exclude: ^src/(bw/lua/middleclass.lua|common/core/antibot/captcha.lua)$
- repo: https://github.com/lunarmodules/luacheck
rev: 418f48976c73be697fe64b0eba9ea9821ac9bca8 # frozen: v1.1.2
rev: cc089e3f65acdd1ef8716cc73a3eca24a6b845e4 # frozen: v1.2.0
hooks:
- id: luacheck
exclude: ^src/(bw/lua/middleclass.lua|common/core/antibot/captcha.lua)$
@ -57,7 +57,7 @@ repos:
exclude: ^tests/
- repo: https://github.com/codespell-project/codespell
rev: 6e41aba91fb32e9feb741a6258eefeb9c6e4a482 # frozen: v2.2.6
rev: 193cd7d27cd571f79358af09a8fb8997e54f8fff # frozen: v2.3.0
hooks:
- id: codespell
name: Codespell Spell Checker

View file

@ -10,7 +10,7 @@ But dedicating time to a specific technology may not be easy depending on your b
Getting professional services in addition to the open-source or PRO version is the ideal solution to cover your business needs. You can focus on your top priorities and rely on a trusted partner when it comes to web security.
Please note that professionnal services are directly offered by [Bunkerity](https://www.bunkerity.com/?utm_campaign=self&utm_source=doc), the company maintaining the BunkerWeb project, through our [BunkerWeb Panel](https://panel.bunkerweb.io/?utm_campaign=self&utm_source=doc) online platform.
Please note that professional services are directly offered by [Bunkerity](https://www.bunkerity.com/?utm_campaign=self&utm_source=doc), the company maintaining the BunkerWeb project, through our [BunkerWeb Panel](https://panel.bunkerweb.io/?utm_campaign=self&utm_source=doc) online platform.
## Which professional services do you offer ?

View file

@ -229,7 +229,7 @@
Get support and more information :
- [Order professionnal support](https://panel.bunkerweb.io/?utm_source=doc&utm_campaign=self)
- [Order professional support](https://panel.bunkerweb.io/?utm_source=doc&utm_campaign=self)
- [Create an issue on GitHub](https://github.com/bunkerity/bunkerweb/issues)
- [Join the BunkerWeb Discord server](https://discord.bunkerity.com)

View file

@ -85,7 +85,7 @@ class News {
) {
sessionStorage.setItem(
"lastRefetch",
Math.round(new Date().getTime() / 1000) + 3600
Math.round(new Date().getTime() / 1000) + 3600,
);
sessionStorage.setItem("lastNews", JSON.stringify(lastNews));
}
@ -102,7 +102,7 @@ class News {
news.photo.url,
news.excerpt,
news.tags,
news.date
news.date,
);
const BASE_URL = this.BASE_URL;
let cleanHTML = DOMPurify.sanitize(cardHTML);
@ -114,7 +114,7 @@ class News {
slug.addEventListener("click", function () {
window.open(
`${BASE_URL}blog/post/${news.slug}?utm_campaign=self&utm_source=ui`,
"_blank"
"_blank",
);
});
});
@ -268,7 +268,7 @@ class FlashMsg {
if (Number(this.flashCount.textContent) > 0) this.animeBtn();
// display only one fixed flash message
const flashFixedEls = document.querySelectorAll(
"[data-flash-message-fixed]"
"[data-flash-message-fixed]",
);
if (flashFixedEls.length > 1) {
flashFixedEls.forEach((el, i) => {
@ -298,7 +298,7 @@ class FlashMsg {
flashEl.remove();
//update count
this.flashCount.textContent = document.querySelectorAll(
"[data-flash-message]"
"[data-flash-message]",
).length;
}
} catch (err) {}
@ -401,7 +401,7 @@ class Banner {
// Try to get data from api
if (sessionStorage.getItem("bannerNews") !== null) {
return this.updateBanner(
JSON.parse(sessionStorage.getItem("bannerNews"))
JSON.parse(sessionStorage.getItem("bannerNews")),
);
}
fetch("https://www.bunkerweb.io/api/bw-ui-news")
@ -413,7 +413,7 @@ class Banner {
// Refetch after one hour
sessionStorage.setItem(
"bannerRefetch",
Math.round(new Date().getTime() / 1000) + 3600
Math.round(new Date().getTime() / 1000) + 3600,
);
return this.updateBanner(res.data[0].data);
})
@ -446,7 +446,7 @@ class Banner {
this.bannerEl.querySelector(
`[role="listitem"][data-id="${
+visibleEl.getAttribute("data-id") + 1
}"]`
}"]`,
) || this.bannerEl.querySelector(`[role="listitem"][data-id="0"]`);
// Hide current one
@ -538,7 +538,7 @@ class Clipboard {
if (result.state === "granted" || result.state === "prompt") {
/* write to the clipboard now */
const copyEl = document.querySelector(
e.target.getAttribute("data-clipboard-target")
e.target.getAttribute("data-clipboard-target"),
);
copyEl.select();
@ -560,7 +560,7 @@ class Clipboard {
if (!this.isCopy) {
/* write to the clipboard now */
const copyEl = document.querySelector(
e.target.getAttribute("data-clipboard-target")
e.target.getAttribute("data-clipboard-target"),
);
copyEl.select();
@ -579,7 +579,7 @@ class Clipboard {
if (!this.isCopy) {
/* write to the clipboard now */
const copyEl = document.querySelector(
e.target.getAttribute("data-clipboard-target")
e.target.getAttribute("data-clipboard-target"),
);
copyEl.select();
@ -611,7 +611,7 @@ class Clipboard {
"opacity-0",
"transition-opacity",
"duration-300",
this.isCopy ? "bg-green-500" : "bg-red-500"
this.isCopy ? "bg-green-500" : "bg-red-500",
);
feedbackEl.textContent = this.isCopy ? "Copied!" : "Error!";
btn.appendChild(feedbackEl);
@ -642,13 +642,13 @@ const setMenu = new Menu();
const setNewsSidebar = new Sidebar(
"[data-sidebar-info]",
"[data-sidebar-info-open]",
"[data-sidebar-info-close]"
"[data-sidebar-info-close]",
);
const setFlashSidebar = new Sidebar(
"[data-flash-sidebar]",
"[data-flash-sidebar-open]",
"[data-flash-sidebar-close]"
"[data-flash-sidebar-close]",
);
const setClipboard = new Clipboard();

File diff suppressed because one or more lines are too long

View file

@ -2,7 +2,7 @@ class FolderNav {
constructor(prefix) {
this.prefix = prefix;
this.breadContainer = document.querySelector(
`[data-${this.prefix}-breadcrumb]`
`[data-${this.prefix}-breadcrumb]`,
);
this.container = document.querySelector(`[data-${this.prefix}-container]`);
this.isReadonly =
@ -12,11 +12,11 @@ class FolderNav {
? true
: false;
this.listContainer = document.querySelector(
`[data-${this.prefix}-folders]`
`[data-${this.prefix}-folders]`,
);
this.els = document.querySelectorAll(`div[data-${this.prefix}-element]`);
this.files = document.querySelectorAll(
`div[data-${this.prefix}-element][data-_type='file']`
`div[data-${this.prefix}-element][data-_type='file']`,
);
this.addFileEl = document.querySelector(`[data-${this.prefix}-add-file]`);
this.initSorted();
@ -91,8 +91,8 @@ class FolderNav {
this.removeBreadElByLvl(+prevLvl);
const folder = document.querySelector(
`div[data-${this.prefix}-element][data-path='${item.getAttribute(
"data-path"
)}']`
"data-path",
)}']`,
);
this.updateActions(folder);
}
@ -113,7 +113,7 @@ class FolderNav {
showCurrentFolderEls(path, lvl) {
const nestedEl = document.querySelectorAll(
`div[data-path^="${path}/"][data-level="${+lvl + 1}"]`
`div[data-path^="${path}/"][data-level="${+lvl + 1}"]`,
);
for (let i = 0; i < nestedEl.length; i++) {
const el = nestedEl[i];
@ -157,7 +157,7 @@ class FolderNav {
//the clicked bread item
removeBreadElByLvl(lvl) {
const breadcrumbItem = this.breadContainer.querySelectorAll(
`[data-${this.prefix}-breadcrumb-item]`
`[data-${this.prefix}-breadcrumb-item]`,
);
breadcrumbItem.forEach((item) => {
if (
@ -216,7 +216,7 @@ class FolderDropdown {
this.prefix = prefix;
this.container = document.querySelector(`[data-${this.prefix}-container]`);
this.dropEls = document.querySelectorAll(
`[data-${this.prefix}-action-dropdown]`
`[data-${this.prefix}-action-dropdown]`,
);
this.init();
}
@ -262,7 +262,7 @@ class FolderDropdown {
.closest("button")
.getAttribute(`data-${this.prefix}-action-dropdown-btn`);
const dropEl = document.querySelector(
`[data-${this.prefix}-action-dropdown="${att}"]`
`[data-${this.prefix}-action-dropdown="${att}"]`,
);
this.hideDrop(dropEl);
}
@ -346,33 +346,33 @@ class FolderModal {
: false;
//add service/file elements
this.breadContainer = document.querySelector(
`[data-${this.prefix}-breadcrumb]`
`[data-${this.prefix}-breadcrumb]`,
);
this.addConfContainer = document.querySelector(
`[data-${this.prefix}-add-container]`
`[data-${this.prefix}-add-container]`,
);
//modal DOM elements
this.form = document.querySelector(`[data-${this.prefix}-modal-form]`);
this.modalEl = document.querySelector(`[data-${this.prefix}-modal]`);
this.modalTitle = this.modalEl.querySelector(
`[data-${this.prefix}-modal-title]`
`[data-${this.prefix}-modal-title]`,
);
this.modalPath = this.modalEl.querySelector(
`[data-${this.prefix}-modal-path]`
`[data-${this.prefix}-modal-path]`,
);
this.modalEditor = this.modalEl.querySelector(
`[data-${this.prefix}-modal-editor]`
`[data-${this.prefix}-modal-editor]`,
);
this.modalPathPrev = this.modalPath.querySelector(
`p[data-${this.prefix}-modal-path-prefix]`
`p[data-${this.prefix}-modal-path-prefix]`,
);
this.modalPathName = this.modalPath.querySelector("input");
this.modalPathSuffix = this.modalPath.querySelector(
`p[data-${this.prefix}-modal-path-suffix]`
`p[data-${this.prefix}-modal-path-suffix]`,
);
this.modalSubmit = this.modalEl.querySelector(
`[data-${this.prefix}-modal-submit]`
`[data-${this.prefix}-modal-submit]`,
);
//hidden input for backend
this.modalInpPath = this.modalEl.querySelector("#path");
@ -381,7 +381,7 @@ class FolderModal {
this.modalInpOldName = this.modalEl.querySelector("#old_name");
this.modalTxtarea = this.modalEl.querySelector("#content");
this.modalDelMsg = this.modalEl.querySelector(
`[data-${this.prefix}-modal-delete]`
`[data-${this.prefix}-modal-delete]`,
);
//HANDLERS
//modal and values logic after clicking add file/folder button
@ -411,7 +411,7 @@ class FolderModal {
"file",
"",
"",
this.getLevelFromBread()
this.getLevelFromBread(),
);
}
} catch (err) {}
@ -481,7 +481,7 @@ class FolderModal {
var element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
"data:text/plain;charset=utf-8," + encodeURIComponent(text),
);
element.setAttribute("download", filename);
@ -652,7 +652,7 @@ class FolderModal {
"delete-btn",
"valid-btn",
"edit-btn",
"info-btn"
"info-btn",
);
}

View file

@ -1,7 +1,6 @@
{% extends "base.html" %}
{% block content %}
{% set attribute_name = "account" %}
<div data-service-content
class="md:max-w-[700px] min-h-[200px] first-letter:w-full overflow-hidden overflow-y-auto overflow-x-auto 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">
<h5 class="my-2 font-bold dark:text-white/90 mx-2">SETTINGS</h5>
@ -27,8 +26,8 @@
"description": "Enabled / Disabled TOTP"
}
] %}
<div data-{{attribute_name}}-tabs class="col-span-12 grid grid-cols-12">
<div role="tablist" data-{{attribute_name}}-tabs class="block col-span-12 mb-4">
<div data-{{ attribute_name }}-tabs class="col-span-12 grid grid-cols-12">
<div role="tablist" data-{{ attribute_name }}-tabs class="block col-span-12 mb-4">
<!-- tabs -->
{% for tab in tabs %}
<button role="tab"
@ -142,7 +141,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">License key</h5>
<label class="sr-only" for="license">License key</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="license"
name="license"
class="col-span-12 regular-input"
@ -173,7 +173,8 @@
</div>
</div>
<div class="col-span-12 flex justify-center mt-6">
<button {% if is_readonly%}disabled{% endif %} type="submit"
<button {% if is_readonly %}disabled{% endif %}
type="submit"
id="activate-key-button"
name="activate-key-button"
class="valid-btn">SAVE</button>
@ -200,7 +201,8 @@
<div class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">Username</h5>
<label class="sr-only" for="admin_username">New username</label>
<input {% if is_readonly%}disabled{% endif %} type="text"
<input {% if is_readonly %}disabled{% endif %}
type="text"
id="admin_username"
name="admin_username"
class="col-span-12 regular-input"
@ -216,7 +218,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">Password</h5>
<label class="sr-only" for="curr_password">Password</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="curr_password"
name="curr_password"
class="col-span-12 regular-input"
@ -249,7 +252,8 @@
</div>
<!-- end password inpt-->
<div class="col-span-12 flex justify-center mt-6">
<button {% if is_readonly%}disabled{% endif %} type="submit"
<button {% if is_readonly %}disabled{% endif %}
type="submit"
id="username-button"
name="username-button"
value="username"
@ -277,7 +281,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">Password</h5>
<label class="sr-only" for="curr_password">Password</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="curr_password"
name="curr_password"
class="col-span-12 regular-input"
@ -314,7 +319,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">New password</h5>
<label class="sr-only" for="admin_password">New password</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="admin_password"
name="admin_password"
class="col-span-12 regular-input"
@ -351,7 +357,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">Confirm new password</h5>
<label class="sr-only" for="admin_password_check">Confirm new password</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="admin_password_check"
name="admin_password_check"
class="col-span-12 regular-input"
@ -384,7 +391,11 @@
<strong class="opacity-0 font-normal text-sm text-red-500" data-pw-alert>Value does not match password</strong>
</div>
<div class="col-span-12 flex justify-center">
<button {% if is_readonly%}disabled{% endif %} type="submit" id="pw-button" name="pw-button" class="valid-btn">Save</button>
<button {% if is_readonly %}disabled{% endif %}
type="submit"
id="pw-button"
name="pw-button"
class="valid-btn">Save</button>
</div>
</form>
<form data-tab-item="totp"
@ -426,7 +437,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">Secret token</h5>
<label class="sr-only" for="secret_token">secret token</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="secret_token"
name="secret_token"
class="col-span-12 regular-input"
@ -477,7 +489,8 @@
<div class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">2FA code</h5>
<label class="sr-only" for="totp_token">totp code</label>
<input {% if is_readonly%}disabled{% endif %} type="text"
<input {% if is_readonly %}disabled{% endif %}
type="text"
id="totp_token"
name="totp_token"
class="col-span-12 regular-input"
@ -492,7 +505,8 @@
class="flex flex-col relative col-span-12 px-4 my-2 md:px-6 md:my-3 lg:px-6 lg:my-3 max-w-[400px] w-full">
<h5 class="input-title">Password</h5>
<label class="sr-only" for="curr_password">Password</label>
<input {% if is_readonly%}disabled{% endif %} type="password"
<input {% if is_readonly %}disabled{% endif %}
type="password"
id="curr_password"
name="curr_password"
class="col-span-12 regular-input"
@ -525,7 +539,8 @@
</div>
<!-- end password inpt-->
<div class="col-span-12 flex justify-center mt-6">
<button {% if is_readonly%}disabled{% endif %} type="submit"
<button {% if is_readonly %}disabled{% endif %}
type="submit"
id="totp-button"
name="totp-button"
value="totp"

View file

@ -11,10 +11,10 @@
{% if terms.append(ban["term"]) %}{% endif %}
{% endif %}
{% endfor %}
<!-- actions -->
<div class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border">
<button {% if is_readonly%}disabled{% endif %} data-add-ban
<button {% if is_readonly %}disabled{% endif %}
data-add-ban
type="button"
class="disabled:cursor-not-allowed dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-700 dark:disabled:border-gray-700/0 disabled:hover:translate-y-0 disabled:hover:bg-gray-400 disabled:hover:border-gray-400/0 dark:disabled:hover:translate-y-0 dark:disabled:hover:bg-gray-700 dark:disabled:hover:border-gray-700/0 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">Add ban</span>
@ -75,119 +75,106 @@
}
] %}
{% set is_filter_hidden = True if bans|length == 0 else False %}
{% 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">
{% 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="mx-2 font-bold dark:text-white/90 mx-2">BANS LIST</h5>
</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 }}"
data-{{attribute_name}}-keyword="{{ ban['ip'] }} {{ ban['ban_start'] }} {{ ban['ban_end'] }}"
data-{{attribute_name}}-reason="{{ ban['reason'] }}"
data-{{attribute_name}}-remain="{{ ban['remain'] }}"
data-{{attribute_name}}-term="{{ ban['term'] }}"
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5 break-all">
<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 {% if is_readonly%}disabled{% endif %} 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 mr-1 my-1"
>{{ ban['ip'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-2 m-0 mr-1 my-1"
>{{ ban['reason'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-2 m-0 mr-1 my-1"
>{{ ban['ban_start'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-2 m-0 mr-1 my-1"
>{{ ban['ban_end'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-3 m-0 mr-1 my-1"
>{{ ban['remain'] }}</p>
<p class="hidden">{{ 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 {% if is_readonly%}disabled{% endif %} data-unban-btn
disabled
type="submit"
class="valid-btn mr-3 text-base">UNBAN</button>
</form>
</div>
</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 }}" data-{{ attribute_name }}-keyword="{{ ban['ip'] }} {{ ban['ban_start'] }} {{ ban['ban_end'] }}" data-{{ attribute_name }}-reason="{{ ban['reason'] }}" data-{{ attribute_name }}-remain="{{ ban['remain'] }}" data-{{ attribute_name }}-term="{{ ban['term'] }}" class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5 break-all">
<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 {% if is_readonly %}disabled{% endif %}
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 mr-1 my-1">{{ ban['ip'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-2 m-0 mr-1 my-1">{{ ban['reason'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-2 m-0 mr-1 my-1">{{ ban['ban_start'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-2 m-0 mr-1 my-1">{{ ban['ban_end'] }}</p>
<p class="dark:text-gray-400 text-sm col-span-3 m-0 mr-1 my-1">{{ ban['remain'] }}</p>
<p class="hidden">{{ 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 {% if is_readonly %}disabled{% endif %}
data-unban-btn
disabled
type="submit"
class="valid-btn mr-3 text-base">UNBAN</button>
</form>
</div>
</div>
{% include "bans_modal.html" %}
{% endblock content %}

View file

@ -22,7 +22,8 @@
<!-- info -->
<main class="xl:pl-75 w-full px-2 sm:px-6 pb-0 pt-20 sm:pt-3 min-h-[85vh] flex flex-col justify-between">
<div class="max-w-[1920px] grid gap-y-4 gap-3 sm:gap-4 lg:gap-6 grid-cols-12 w-full">
<div class="hidden" data-global-is-readonly="{%if is_readonly%}true{% else%}false{%endif%}"></div>
<div class="hidden"
data-global-is-readonly="{% if is_readonly %}true{% else %}false{% endif %}"></div>
{% block content %}{% endblock %}
</div>
{% include "footer.html" %}

View file

@ -5,12 +5,8 @@
else 'col-span-12 md:col-span-6 2xl:col-span-4' if attribute_name == 'plugins'
else 'col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-5' if attribute_name == 'reports'
else 'col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-4' if attribute_name == 'services'
else 'col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-4'
%}
<div data-{{attribute_name}}-filter
class="{% if is_filter_hidden %} hidden {%endif%} h-fit {{grid_cols}} 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">
else 'col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-4' %}
<div data-{{ attribute_name }}-filter class="{% if is_filter_hidden %} hidden {% endif %} h-fit {{ grid_cols }} 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 %}
@ -22,12 +18,12 @@
</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 />
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 %}
@ -37,32 +33,18 @@
<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>
<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">
<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">
<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">
<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 %}

View file

@ -1,15 +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 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>
</div>
{% endif %}
{% endif %}

View file

@ -1,7 +1,6 @@
{% extends "base.html" %}
{% block content %}
{% set attribute_name = "configs" %}
{% set infos = [
{
"id": "total-conf",
@ -14,7 +13,6 @@
"data": "unknown"
}
] %}
{% include "card_info.html" %}
<!-- end info -->
<!-- filter -->
@ -39,9 +37,8 @@
"true"
]
}
]
%}
{% include "card_filter.html" %}
<!-- end filter -->
{% include "file_manager.html" %}
] %}
{% include "card_filter.html" %}
<!-- end filter -->
{% include "file_manager.html" %}
{% endblock content %}

View file

@ -271,9 +271,8 @@
<!-- editor-->
<div data-{{ current_endpoint }}-modal-editor id="editor" class="text-base w-full h-96 overflow-hidden overflow-y-auto my-2 border border-gray-300 dark:border-slate-800">
</div>
<p data-{{ current_endpoint }}-modal-delete
class="hidden text-center text-gray-700 dark:text-gray-300 mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm">
</p>
<p data-{{ current_endpoint }}-modal-delete class="hidden text-center text-gray-700 dark:text-gray-300 mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm">
</p>
<!-- editor-->
<div class="mt-4 w-full justify-end flex">
<button type="button" data-{{ current_endpoint }}-modal-close class="dark:bg-slate-800 close-btn text-xs mr-2">

View file

@ -1,14 +1,15 @@
<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 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">
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>
<h5 class="font-bold dark:text-white/90 mx-2 text-white">
No {{ attribute_name.replace('-', ' ').replace('_', ' ')|lower }} match
</h5>
</div>
</div>
</div>

View file

@ -1,7 +1,6 @@
{% 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">
@ -46,7 +45,6 @@
}
] %}
{% include "card_filter.html" %}
<!-- end filter -->
<div data-global-config-plugins-container
class="col-span-12 gap-y-4 grid grid-cols-12">
@ -64,11 +62,13 @@
<!-- end plugin item -->
<!-- submit -->
<div class="flex w-full justify-center mt-8 mb-2">
<button {% if is_readonly%}disabled{% endif %} type="submit" class="valid-btn">SAVE</button>
<button {% if is_readonly %}disabled{% endif %}
type="submit"
class="valid-btn">SAVE</button>
</div>
<!-- end submit -->
</form>
<!--end form global conf -->
{% include "filter_nomatch.html" %}
{% include "filter_nomatch.html" %}
</div>
{% endblock content %}

View file

@ -13,9 +13,7 @@
<link rel="stylesheet" href="css/dashboard.css" />
<script type="module" src="js/global.js" nonce="{{ script_nonce }}"></script>
<script src="js/plugins/utils.js" nonce="{{ script_nonce }}"></script>
<script async
src="js/utils/purify/purify.min.js"
nonce="{{ script_nonce }}"></script>
<script async src="js/utils/purify/purify.min.js" nonce="{{ script_nonce }}"></script>
<script src="js/editor/ace.js" nonce="{{ script_nonce }}"></script>
{% if current_endpoint == "global_config" %}
<script type="module" src="js/global_config.js" nonce="{{ script_nonce }}"></script>
@ -32,9 +30,7 @@
<link rel="stylesheet" href="css/flatpickr.dark.css" />
<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" />
<link rel="stylesheet" href="css/datepicker-foundation.css" />
{% elif current_endpoint == "jobs" %}
<script type="module" src="js/jobs.js" nonce="{{ script_nonce }}"></script>
{% elif current_endpoint == "account" %}

View file

@ -1,7 +1,6 @@
{% extends "base.html" %}
{% block content %}
{% set attribute_name = "home" %}
{% set cards = [
{'name' : 'Version', 'title' : 'PRO' if is_pro_version else 'PRO LOCKED' if pro_status == 'active' and pro_overlapped else 'EXPIRED' if pro_status == 'expired' else 'SUSPENDED' if pro_status == 'suspended' else 'FREE', 'link' : 'https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro', 'subtitle' : 'all features available' if is_pro_version else 'awaiting compliance' if pro_status == 'active' and pro_overlapped else 'renew license' if pro_status == 'expired' else 'talk to team' if pro_status == 'suspended' else 'upgrade to pro', 'subtitle_color' : 'success' if is_pro_version else 'warning' },
{'name' : 'Version number', 'title' : version, 'link' : 'https://github.com/bunkerity/bunkerweb', 'subtitle' : "couldn't find remote" if not remote_version else "latest version" if remote_version and check_version else 'Update to ' + remote_version , 'subtitle_color' : "error" if not remote_version else "success" if remote_version and check_version else 'warning'},

View file

@ -1,7 +1,6 @@
{% extends "base.html" %}
{% block content %}
{% set attribute_name = "instances" %}
{% if instances|length == 0 %}
<div class="col-span-12 sm:col-span-4 sm:col-start-5">
<div class="text-center relative w-full p-4 text-white bg-blue-500 rounded-lg">No instance to show</div>
@ -19,9 +18,7 @@
<div class="flex justify-start items-start overflow-hidden">
{% if instance.health %}<div class="min-w-4 mr-2 mt-2 h-4 w-4 rounded-full bg-green-500"></div>{% endif %}
{% if not instance.health %}<div class="min-w-4 mr-2 mt-2 h-4 w-4 rounded-full bg-red-500"></div>{% endif %}
<h5 class="break-words font-bold dark:text-white/90 transition duration-300 ease-in-out">
{{ instance.name }}
</h5>
<h5 class="break-words font-bold dark:text-white/90 transition duration-300 ease-in-out">{{ instance.name }}</h5>
</div>
<!-- end state and title-->
<!-- detail list -->

View file

@ -11,194 +11,168 @@
{% set infos = [
{"name" : "JOBS TOTAL", "data" : jobs|length|string},
{"name" : "JOBS ERRORS", "data" : jobs_errors|string},
]
%}
{% include "card_info.html" %}
<!-- filter -->
{% set filters = [
{
"type": "input",
"name": "Search",
"label": "search",
"id": "keyword",
"placeholder": "keyword",
"pattern": "(.*?)"
},
{
"type": "select",
"name": "Success state",
"id": "success",
"value": "all",
"values": [
"all",
"false",
"true"
]
},
{
"type": "select",
"name": "Reload state",
"id": "reload",
"value": "all",
"values": [
"all",
"false",
"true"
]
},
{
"type": "select",
"name": "Run time",
"id": "every",
"value": "all",
"values": run_times
}
] %}
{% 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">JOBS LIST</h5>
</div>
<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">
<!-- list container-->
{% set job_headers = [
{
"name": "Name",
"custom_class": "col-span-3"
},
{
"name": "Last run",
"custom_class": "col-span-3"
},
{
"name": "Every",
"custom_class": "col-span-1"
},
{
"name": "Reload",
"custom_class": "flex justify-center col-span-1"
},
{
"name": "Success",
"custom_class": "flex justify-center col-span-1"
},
{
"name": "Files",
"custom_class": "col-span-3"
}
] %}
<div class="w-full grid grid-cols-12 rounded p-2">
<!-- header-->
{% for header in job_headers %}
<p class="{{ header['custom_class'] }} dark:text-gray-100 h-8 text-sm font-bold 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 job_name, value in jobs.items() %}
<!-- job item-->
{% set jobs_data = [
{"type" : "text", "filter_name" : "name", "value" : job_name, "custom_class" : "col-span-3"},
{"type" : "text", "filter_name" : "last_run", "value" : value['last_run'], "custom_class" : "col-span-3"},
{"type" : "text", "filter_name" : "every", "value" : value['every'], "custom_class" : "col-span-1"},
{"type" : "check", "filter_name" : "reload", "value" : value['reload'], "custom_class" : "col-span-1"},
{"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-{{attribute_name}}-item
{% for data in jobs_data %}
data-{{attribute_name}}-{{ data['filter_name'] }}="{{ data['value'] }}"
{%endfor%}
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5 break-all">
{% for data in jobs_data %}
{% if data['type'] == "text" %}
<p class="{{ data['custom_class'] }} dark:text-gray-400 text-sm m-0 my-1 mr-1">
{{ 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 mr-1">
<svg class="fill-green-500 h-5 w-5"
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 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" />
</svg>
</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 mr-1">
<svg class="fill-red-500 h-5 w-5"
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 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" />
</svg>
</p>
{% endif %}
{% if data['type'] == "select" %}
<div class="{{ data['custom_class'] }} relative dark:text-gray-400 text-sm m-0 my-1 mr-1"
data-{{attribute_name}}-files>
{% if value['cache'] %}
<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-{{attribute_name}}-setting-select-text="{{ job_name }}">files</span>
<!-- chevron -->
<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">
<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 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-{{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">
<svg class="min-w-fit h-5.5 w-5.5 stroke-sky-500"
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="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="overflow-hidden break-word transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 ml-2">{{ file['file_name'] }}</span>
</span>
</button>
{% endfor %}
</div>
<!-- end dropdown-->
{% endif %}
</div>
{% endif %}
{% endfor %}
</li>
<!-- end job item-->
{% endfor %}
</ul>
<!-- end list-->
</div>
<!-- end list container-->
</div>
</div>
{% include "card_info.html" %}
<!-- filter -->
{% set filters = [
{
"type": "input",
"name": "Search",
"label": "search",
"id": "keyword",
"placeholder": "keyword",
"pattern": "(.*?)"
},
{
"type": "select",
"name": "Success state",
"id": "success",
"value": "all",
"values": [
"all",
"false",
"true"
]
},
{
"type": "select",
"name": "Reload state",
"id": "reload",
"value": "all",
"values": [
"all",
"false",
"true"
]
},
{
"type": "select",
"name": "Run time",
"id": "every",
"value": "all",
"values": run_times
}
] %}
{% 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">JOBS LIST</h5>
</div>
<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">
<!-- list container-->
{% set job_headers = [
{
"name": "Name",
"custom_class": "col-span-3"
},
{
"name": "Last run",
"custom_class": "col-span-3"
},
{
"name": "Every",
"custom_class": "col-span-1"
},
{
"name": "Reload",
"custom_class": "flex justify-center col-span-1"
},
{
"name": "Success",
"custom_class": "flex justify-center col-span-1"
},
{
"name": "Files",
"custom_class": "col-span-3"
}
] %}
<div class="w-full grid grid-cols-12 rounded p-2">
<!-- header-->
{% for header in job_headers %}
<p class="{{ header['custom_class'] }} dark:text-gray-100 h-8 text-sm font-bold 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 job_name, value in jobs.items() %}
<!-- job item-->
{% set jobs_data = [
{"type" : "text", "filter_name" : "name", "value" : job_name, "custom_class" : "col-span-3"},
{"type" : "text", "filter_name" : "last_run", "value" : value['last_run'], "custom_class" : "col-span-3"},
{"type" : "text", "filter_name" : "every", "value" : value['every'], "custom_class" : "col-span-1"},
{"type" : "check", "filter_name" : "reload", "value" : value['reload'], "custom_class" : "col-span-1"},
{"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-{{ attribute_name }}-item {% for data in jobs_data %}data-{{ attribute_name }}-{{ data['filter_name'] }}="{{ data['value'] }}"{% endfor %} class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5 break-all">
{% for data in jobs_data %}
{% if data['type'] == "text" %}
<p class="{{ data['custom_class'] }} dark:text-gray-400 text-sm m-0 my-1 mr-1">{{ 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 mr-1">
<svg class="fill-green-500 h-5 w-5"
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 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" />
</svg>
</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 mr-1">
<svg class="fill-red-500 h-5 w-5"
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 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" />
</svg>
</p>
{% endif %}
{% if data['type'] == "select" %}
<div class="{{ data['custom_class'] }} relative dark:text-gray-400 text-sm m-0 my-1 mr-1" data-{{ attribute_name }}-files>
{% if value['cache'] %}
<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-{{ attribute_name }}-setting-select-text="{{ job_name }}">files</span>
<!-- chevron -->
<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">
<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 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-{{ 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">
<svg class="min-w-fit h-5.5 w-5.5 stroke-sky-500"
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="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="overflow-hidden break-word transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 ml-2">{{ file['file_name'] }}</span>
</span>
</button>
{% endfor %}
</div>
<!-- end dropdown-->
{% endif %}
</div>
{% endif %}
{% endfor %}
</li>
<!-- end job item-->
{% endfor %}
</ul>
<!-- end list-->
</div>
<!-- end list container-->
</div>
</div>
</div>
{% endblock content %}

View file

@ -112,8 +112,10 @@
<!-- end form -->
<!-- particles -->
<div class="-z-10 fixed lg:relative lg:col-span-1 bg-primary w-full h-full">
<div id="lottie-particles" data-lottie="/lotties/PARTICLES.json" class="absolute top-0 left-0 w-full h-full login-img [&>*]:bg-primary"></div>
<div class="h-full w-full hidden relative lg:flex items-center justify-center">
<div id="lottie-particles"
data-lottie="/lotties/PARTICLES.json"
class="absolute top-0 left-0 w-full h-full login-img [&>*]:bg-primary"></div>
<div class="h-full w-full hidden relative lg:flex items-center justify-center">
<img class="max-w-60 max-h-30"
src="images/BUNKERWEB-print-hd-blanc.png"
alt="logo" />

View file

@ -1,10 +1,8 @@
{% extends "base.html" %}
{% block content %}
{% set attribute_name = "logs" %}
<!-- settings -->
<div data-{{attribute_name}}-settings
class="col-span-12 lg:col-span-8 2xl:col-span-6 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-{{ attribute_name }}-settings class="col-span-12 lg:col-span-8 2xl:col-span-6 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<h5 class="mb-2 font-bold dark:text-white/90">SETTINGS</h5>
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
<!-- select instance -->
@ -12,12 +10,8 @@
<h5 class="my-1 transition duration-300 ease-in-out text-sm sm:text-md font-bold m-0 dark:text-gray-200">
Select instance
</h5>
<button data-{{attribute_name}}-setting-select="instances"
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
<span id="logs-instance"
data-name="logs-instance"
class="overflow-hidden break-all"
data-{{attribute_name}}-setting-select-text="instances">
<button data-{{ attribute_name }}-setting-select="instances" class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
<span id="logs-instance" data-name="logs-instance" class="overflow-hidden break-all" data-{{ attribute_name }}-setting-select-text="instances">
{% for instance in instances %}
{% if loop.first %}
{% if
@ -30,22 +24,15 @@
{% endfor %}
</span>
<!-- chevron -->
<svg data-{{attribute_name}}-setting-select="instances"
class="min-w-4 ml-2 transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<svg data-{{ attribute_name }}-setting-select="instances" class="min-w-4 ml-2 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 data-{{attribute_name}}-setting-select-dropdown="instances"
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
<div data-{{ attribute_name }}-setting-select-dropdown="instances" class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
{% for instance in instances %}
<button data-{{attribute_name}}-setting-select-dropdown-btn="instances"
value="{{ instance.name }}"
data-_type="{{ instance._type }}"
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">
<button data-{{ attribute_name }}-setting-select-dropdown-btn="instances" value="{{ instance.name }}" data-_type="{{ instance._type }}" 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">
{{ instance.name }}
</button>
{% endfor %}
@ -179,8 +166,7 @@
]
}
] %}
<div data-{{attribute_name}}-filter
class="h-fit col-span-12 lg:col-span-4 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<div data-{{ attribute_name }}-filter class="h-fit col-span-12 lg:col-span-4 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
<h5 class="mb-2 font-bold dark:text-white/90">FILTERS</h5>
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
{% for filter in filters %}
@ -207,32 +193,18 @@
<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="logs-{{ filter['id'] }}"
data-name="logs-{{ filter['id'] }}"
data-{{attribute_name}}-setting-select-text="{{ filter['id'] }}">all</span>
<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="logs-{{ filter['id'] }}" data-name="logs-{{ filter['id'] }}" data-{{ attribute_name }}-setting-select-text="{{ filter['id'] }}">all</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">
<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">
<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">
<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 %}
@ -245,8 +217,7 @@
</div>
</div>
<!-- end filter -->
<div data-{{attribute_name}}-no-run
class="w-full overflow-hidden grid grid-cols-12 max-h-100 sm:max-h-125 col-span-12 p-4 relative break-words">
<div data-{{ attribute_name }}-no-run class="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"
@ -259,14 +230,12 @@
<h5 class="font-bold dark:text-white/90 mx-2 text-white">No logs to show</h5>
</div>
</div>
<div data-{{attribute_name}}-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 data-{{ attribute_name }}-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">
<h5 class="mb-4 mt-2 font-bold dark:text-white/90 mx-2">LOGS</h5>
</div>
<div class="col-span-12 overflow-y-auto overflow-x-auto">
<div data-{{attribute_name}}-bans-list>
<div data-{{ attribute_name }}-bans-list>
<!-- list container-->
<div class="overflow-hidden min-w-[800px] w-full grid grid-cols-12 rounded p-2">
<!-- header-->
@ -274,7 +243,7 @@
<p class="dark:text-gray-100 h-8 text-sm font-bold col-span-9 m-0 pb-2 border-b border-gray-400">Description</p>
<!-- end header-->
<!-- list -->
<ul class="col-span-12 w-full" data-{{attribute_name}}-list>
<ul class="col-span-12 w-full" data-{{ attribute_name }}-list>
</ul>
<!-- end list-->
</div>

View file

@ -47,7 +47,7 @@
</div>
<div class="mt-2 w-full px-1">
<h1 class="mb-0.5 tracking-normal text-primary text-center text-lg break-words whitespace-normal dark:text-gray-300">
{{ username|truncate(10, True, '...')}}
{{ username|truncate(10, True, '...') }}
</h1>
<a class="block underline mb-2 text-gray-600 dark:text-gray-400 text-sm text-center hover:brightness-90"
href="{% if current_endpoint == 'account' %}#{% else %}{{ url_for("account") }}{% endif %}">manage account
@ -241,15 +241,14 @@
<div class="flex flex-col justify-end mx-4 mt-2 mb-4">
<!-- dark/light mode -->
<div class="min-h-6 ml-12 my-4 flex justify-start">
<input
id="darkMode"
<input id="darkMode"
data-dark-toggle
class="dark:brightness-125 hover:brightness-75 rounded-10 duration-300 ease-in-out after:rounded-circle after:shadow-2xl after:duration-300 checked:after:translate-x-5.3 h-5 mt-0.5 relative float-left w-10 cursor-pointer appearance-none border border-solid border-gray-200 bg-slate-800/10 bg-none bg-contain bg-left bg-no-repeat align-top transition-all after:absolute after:top-px after:h-4 after:w-4 after:translate-x-px after:bg-white after:content-[''] checked:border-primary checked:bg-primary checked:bg-none checked:bg-right"
type="checkbox" />
<label for="darkMode"
data-dark-toggle-label
class="dark:text-gray-200 transition inline-block pl-3 mb-0 ml-0 font-normal cursor-pointer select-none text-sm text-slate-700">
light mode
light mode
</label>
</div>
<!-- end dark/light mode -->

View file

@ -1,7 +1,6 @@
{% extends "base.html" %}
{% block content %}
{% set attribute_name = "plugins" %}
{%
include "plugins_modal.html" %}
<!-- info -->
@ -12,24 +11,29 @@
{"name" : "PRO PLUGINS", "data" : plugins_count_pro|string if is_pro_version else plugins_count_pro|string + ' (preview)'},
] %}
{% include "card_info.html" %}
<!-- upload layout -->
<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">
<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">
<!-- dropzone -->
<form id="dropzone-form"
<form id="dropzone-form"
action="#"
class="{% if is_readonly %} cursor-not-allowed {% else %} cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-700/50 {% endif %} col-span-12 border-2 rounded-lg p-2 border-dashed border-primary dark:brightness-125 drop-zone">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input {% if is_readonly%}disabled{% endif %} class="file-input drop-zone__input"
<input {% if is_readonly %}disabled{% endif %}
class="file-input drop-zone__input"
type="file"
name="file"
multiple="multiple"
hidden />
<i class="fa-solid fa-cloud-upload-alt"></i>
<p class="dark:text-gray-500 text-sm text-center my-3">{% if is_readonly%}upload not available{% else %}click or drag and drop{% endif %}</p>
<p class="dark:text-gray-500 text-sm text-center my-3">
{% if is_readonly %}
upload not available
{% else %}
click or drag and drop
{% endif %}
</p>
</form>
<div class="col-span-12 progress-area"></div>
<div class="col-span-12 uploaded-area"></div>
@ -37,7 +41,10 @@
<div class="col-span-12 flex flex-col justify-center items-center mt-2">
<form method="post"
class="col-span-12 flex flex-col justify-center align-middle items-cente">
<input type="hidden" id="csrf_token" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden"
id="csrf_token"
name="csrf_token"
value="{{ csrf_token() }}" />
<button data-plugin-reload-btn
disabled
type="submit"
@ -49,7 +56,6 @@
</div>
</div>
<!-- end upload layout -->
<!-- filter -->
{% set filters = [
{
@ -75,66 +81,57 @@
] %}
{% include "card_filter.html" %}
{% include "filter_nomatch.html" %}
<div data-{{attribute_name}}-list-container class="plugins-list-container">
<div data-{{ attribute_name }}-list-container class="plugins-list-container">
<div class="plugins-list-container-title-container">
<h5 class="plugins-list-container-title">PLUGINS LIST</h5>
</div>
<div
class="plugins-list-items-container">
<div data-{{attribute_name}}-list class="plugins-list-items-wrap">
{% for plugin in plugins %}
<div data-plugin data-{{attribute_name}}-type="{{ plugin['type'] }}"
data-{{attribute_name}}-name="{{ plugin['name'] }}"
class="plugins-list-items {% if plugin['type'] != 'pro' or plugin['type'] == 'pro' and is_pro_version %} enabled {% else %} disabled {% endif %}">
<p data-{{attribute_name}}-content
class="plugins-list-items-name {% if plugin['type'] == 'pro' and not is_pro_version %} disabled {% endif %} ">
{{ plugin['name'] }}
</p>
<div class="plugins-list-items-actions">
{% 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="plugins-list-items-link"
href="{{ request.url_root }}plugins/{{ plugin['id'] }}">
<svg class="plugins-list-items-link-svg"
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" and plugin['method'] in ('ui', 'manual') %}
<button {% if is_readonly%}disabled{% endif %} data-{{attribute_name}}-action="delete"
name="{{ plugin['id'] }}"
aria-label="delete plugin"
class="plugins-list-items-delete">
<svg class="plugins-list-items-delete-svg {% if is_readonly%}readonly{% endif %}"
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="plugins-list-items-pro"
href="{% if not is_pro_version %}https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro{% else %}javascript:void(0){% endif %}">
<svg class="plugins-list-items-pro-svg"
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 class="plugins-list-items-container">
<div data-{{ attribute_name }}-list class="plugins-list-items-wrap">
{% for plugin in plugins %}
<div data-plugin data-{{ attribute_name }}-type="{{ plugin['type'] }}" data-{{ attribute_name }}-name="{{ plugin['name'] }}" class="plugins-list-items {% if plugin['type'] != 'pro' or plugin['type'] == 'pro' and is_pro_version %} enabled {% else %} disabled {% endif %}">
<p data-{{ attribute_name }}-content class="plugins-list-items-name {% if plugin['type'] == 'pro' and not is_pro_version %}disabled{% endif %} ">
{{ plugin['name'] }}
</p>
<div class="plugins-list-items-actions">
{% 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="plugins-list-items-link"
href="{{ request.url_root }}plugins/{{ plugin['id'] }}">
<svg class="plugins-list-items-link-svg"
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" and plugin['method'] in ('ui', 'manual') %}
<button {% if is_readonly %}disabled{% endif %} data-{{ attribute_name }}-action="delete" name="{{ plugin['id'] }}" aria-label="delete plugin" class="plugins-list-items-delete">
<svg class="plugins-list-items-delete-svg {% if is_readonly %}readonly{% endif %}"
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="plugins-list-items-pro"
href="{% if not is_pro_version %}https://panel.bunkerweb.io/?utm_campaign=self&utm_source=ui#pro{% else %}javascript:void(0){% endif %}">
<svg class="plugins-list-items-pro-svg"
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 %}

View file

@ -75,7 +75,6 @@
{"name" : "TOP STATUS CODE", "data" : top_code['name']|string},
] %}
{% include "card_info.html" %}
<!-- filter -->
{% set filters = [
{
@ -117,14 +116,12 @@
] %}
{% 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 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">REPORTING LIST</h5>
</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 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 = [
@ -173,33 +170,20 @@
{% endfor %}
<!-- end header-->
<!-- list -->
<ul class="col-span-12 w-full" data-{{attribute_name}}-list>
<ul class="col-span-12 w-full" data-{{ attribute_name }}-list>
{% for report in reports %}
<li data-{{attribute_name}}-item
data-{{attribute_name}}-country="{{ report['country'] }}"
data-{{attribute_name}}-method="{{ report['method'] }}"
data-{{attribute_name}}-status="{{ report['status'] }}"
data-{{attribute_name}}-reason="{{ report['reason'] }}"
data-{{attribute_name}}-keyword="{{ report['ip'] }} {{ report['url'] }} {{ report['data'] }} {{ report['date'] }} {{ report['user_agent'] }}"
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5 break-all">
<p class="text-center flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1"
>{{ report['date'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1"
>{{ report['ip'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1"
>{{ report['country'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1 "
>{{ report["method"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 mr-1"
>{{ report['url'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1 "
>{{ report["status"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 mr-1 "
>{{ report["user_agent"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1 "
>{{ report["reason"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 mr-1"
>{{ report["data"] }}</p>
<li data-{{ attribute_name }}-item data-{{ attribute_name }}-country="{{ report['country'] }}" data-{{ attribute_name }}-method="{{ report['method'] }}" data-{{ attribute_name }}-status="{{ report['status'] }}" data-{{ attribute_name }}-reason="{{ report['reason'] }}" data-{{ attribute_name }}-keyword="{{ report['ip'] }} {{ report['url'] }} {{ report['data'] }} {{ report['date'] }} {{ report['user_agent'] }}" class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5 break-all">
<p class="text-center flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1">
{{ report['date'] }}
</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1">{{ report['ip'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1">{{ report['country'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1 ">{{ report["method"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 mr-1">{{ report['url'] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1 ">{{ report["status"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 mr-1 ">{{ report["user_agent"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-1 m-0 my-1 mr-1 ">{{ report["reason"] }}</p>
<p class="flex justify-center dark:text-gray-400 text-sm col-span-2 m-0 my-1 mr-1">{{ report["data"] }}</p>
</li>
{% endfor %}
</ul>
@ -209,6 +193,5 @@
</div>
</div>
</div>
{% endif %}
{% endblock content %}

View file

@ -15,29 +15,21 @@
{% if online_services.append(1) %}{% endif %}
{% endif %}
{% endfor %}
{# Get name of multiples #}
{% set multiple_settings = [] %}
{% for plugin in plugins%}
{% for plugin in plugins %}
{% for setting, value in plugin.get('settings', {}).items() %}
{% if value.get("multiple", "") %}
{% if multiple_settings.append(setting) %}{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<input class="hidden" data-plugins-multiple='{{multiple_settings}}' />
<input class="hidden" data-plugins-multiple='{{ multiple_settings }}' />
<!-- actions -->
<div data-{{attribute_name}}-service data-settings="{}"
class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border">
<div data-{{ attribute_name }}-service data-settings="{}" 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 {% if is_readonly%}disabled{% endif %} data-{{attribute_name}}-action="new"
data-{{attribute_name}}-name="service"
data-old-name
data-value="new"
data-settings="{}"
type="button"
class="disabled:cursor-not-allowed dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-700 dark:disabled:border-gray-700/0 disabled:hover:translate-y-0 disabled:hover:bg-gray-400 disabled:hover:border-gray-400/0 dark:disabled:hover:translate-y-0 dark:disabled:hover:bg-gray-700 dark:disabled:hover:border-gray-700/0 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">
<button {% if is_readonly %}disabled{% endif %} data-{{ attribute_name }}-action="new" data-{{ attribute_name }}-name="service" data-old-name data-value="new" data-settings="{}" type="button" class="disabled:cursor-not-allowed dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-700 dark:disabled:border-gray-700/0 disabled:hover:translate-y-0 disabled:hover:bg-gray-400 disabled:hover:border-gray-400/0 dark:disabled:hover:translate-y-0 dark:disabled:hover:bg-gray-700 dark:disabled:hover:border-gray-700/0 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>
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
@ -58,277 +50,252 @@
{"name" : "SERVICES TOTAL", "data" : services|length|string},
{"name" : "TOTAL DRAFT", "data" : draft_services|length|string},
{"name" : "TOTAL ONLINE", "data" : online_services|length|string},
]
%}
{% include "card_info.html" %}
<!-- filter -->
{% set filters = [
{
"type": "input",
"name": "Search",
"label": "search",
"id": "service-name-keyword",
"placeholder": "service name",
"pattern": "(.*?)"
},
{
"type": "select",
"name": "Method",
"id": "method",
"value": "all",
"values": methods
},
{
"type": "select",
"name": "State",
"id": "state",
"value": "all",
"values": states
}
] %}
{% include "card_filter.html" %}
{% include "filter_nomatch.html" %}
{% include "card_info.html" %}
<!-- filter -->
{% set filters = [
{
"type": "input",
"name": "Search",
"label": "search",
"id": "service-name-keyword",
"placeholder": "service name",
"pattern": "(.*?)"
},
{
"type": "select",
"name": "Method",
"id": "method",
"value": "all",
"values": methods
},
{
"type": "select",
"name": "State",
"id": "state",
"value": "all",
"values": states
}
] %}
{% include "card_filter.html" %}
{% include "filter_nomatch.html" %}
</div>
{% endif %}
<!-- end service info and actions -->
<!-- services container-->
<div class="p-0 sm:mx-2 md:mx-4 md:px-1 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">
{% if services|length == 0 %}
<div class="col-span-12 sm:col-span-4 sm:col-start-5">
<div class="transition duration-300 ease-in-out dark:opacity-90 text-center relative w-full p-4 text-white bg-blue-500 rounded-lg">
No service to show
</div>
</div>
{% endif %}
<!-- end service info and actions -->
<!-- services container-->
<div class="p-0 sm:mx-2 md:mx-4 md:px-1 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">
{% if services|length == 0 %}
<div class="col-span-12 sm:col-span-4 sm:col-start-5">
<div class="transition duration-300 ease-in-out dark:opacity-90 text-center relative w-full p-4 text-white bg-blue-500 rounded-lg">
No service to show
</div>
</div>
{% endif %}
{% if services|length > 0 %}
<!-- end filter -->
{% for service in services %}
{% set id_server_name = service["SERVER_NAME"]['value'].replace(".", "-") %}
<div data-{{attribute_name}}-card
data-{{attribute_name}}-name="{{ service["SERVER_NAME"]['value'] }}"
data-{{attribute_name}}-method="{{ service["SERVER_NAME"]['method'] }}"
data-{{attribute_name}}-state="{{ "draft" if service.get('IS_DRAFT', "no") == "yes" else "online" }}"
data-settings="{{ service['settings'] }}"
data-{{attribute_name}}-service="{{ service['SERVER_NAME']['value'] }}"
class="flex flex-col justify-between 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-old-name
class="hidden"
data-value="{{ service['SERVER_NAME']['full_value'] }}"></div>
<div data-is-draft
class="hidden"
data-value="{% if service.get('IS_DRAFT', 'no') == 'yes' %}yes{% else %}no{% endif %}"></div>
<div data-service-method
class="hidden"
data-value="{{ service['SERVER_NAME']['method'] }}"></div>
<div class="flex justify-between items-start">
<div class="flex flex-col">
<h5
class="break-all transition duration-300 ease-in-out text-center sm:text-left mb-1 mr-2 font-bold dark:text-white/90">
{% if services|length > 0 %}
<!-- end filter -->
{% for service in services %}
{% set id_server_name = service["SERVER_NAME"]['value'].replace(".", "-") %}
<div data-{{ attribute_name }}-card data-{{ attribute_name }}-name="{{ service["SERVER_NAME"]['value'] }}" data-{{ attribute_name }}-method="{{ service["SERVER_NAME"]['method'] }}" data-{{ attribute_name }}-state="{{ "draft" if service.get('IS_DRAFT', 'no') == "yes" else "online" }}" data-settings="{{ service['settings'] }}" data-{{ attribute_name }}-service="{{ service['SERVER_NAME']['value'] }}" class="flex flex-col justify-between 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-old-name
class="hidden"
data-value="{{ service['SERVER_NAME']['full_value'] }}"></div>
<div data-is-draft
class="hidden"
data-value="{% if service.get('IS_DRAFT', 'no') == 'yes' %}yes{% else %}no{% endif %}"></div>
<div data-service-method
class="hidden"
data-value="{{ service['SERVER_NAME']['method'] }}"></div>
<div class="flex justify-between items-start">
<div class="flex flex-col">
<h5 class="break-all transition duration-300 ease-in-out text-center sm:text-left mb-1 mr-2 font-bold dark:text-white/90">
{{ service["SERVER_NAME"]['value'] }}
</h5>
<h6
class="text-left sm:mb-2 font-semibold text-gray-600 dark:text-white/80">
{{ service["SERVER_NAME"]['method'] }}
<h6 class="text-left sm:mb-2 font-semibold text-gray-600 dark:text-white/80">
{{ service["SERVER_NAME"]['method'] }}
</h6>
</div>
{% if service.get('IS_DRAFT', "no") == "yes" and service["SERVER_NAME"]['method'] in ["ui", "default"] %}
<button class="group relative">
<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>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
<path fill-rule="evenodd" d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z" clip-rule="evenodd" />
</svg>
</button>
{% else %}
<button class="group relative">
<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>
<svg data-toggle-draft="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
<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>
{% endif %}
</div>
{% set details = [
{
"name": "Reverse proxy",
"settings": [
"USE_REVERSE_PROXY"
]
},
{
"name": "Serve files",
"settings": [
"SERVE_FILES"
]
},
{
"name": "Remote PHP",
"settings": [
"REMOTE_PHP"
]
},
{
"name": "HTTPS",
"settings": [
"AUTO_LETS_ENCRYPT",
"USE_CUSTOM_SSL",
"GENERATE_SELF_SIGNED_SSL"
]
},
{
"name": "ModSecurity",
"settings": [
"USE_MODSECURITY"
]
},
{
"name": "Bad behavior",
"settings": [
"USE_BAD_BEHAVIOR"
]
},
{
"name": "Limit req",
"settings": [
"USE_LIMIT_REQ"
]
},
{
"name": "DNSBL",
"settings": [
"USE_DNSBL"
]
}
] %}
<!-- detail list -->
<div role="grid"
class="w-full grid grid-cols-12 justify-items-center sm:justify-items-start gap-2 mt-4 mb-6 ml-3 sm:ml-1">
{% for detail in details %}
{% set use = [] %}
{% for setting in detail['settings'] %}
{% if service[setting]['value'] == 'yes' %}
{% if use.append(1) %}{% endif %}
{% endif %}
{% endfor %}
<!-- detail -->
<div role="row" class="flex items-center col-span-12 sm:col-span-6">
<p role="gridcell"
class="transition duration-300 ease-in-out font-bold mb-0 font-sans text-sm leading-normal uppercase dark:text-gray-500 ">
{{ detail['name'] }}
</p>
<p role="gridcell"
class="transition duration-300 ease-in-out dark:opacity-90 pl-2 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-gray-500 ">
{% if use %}
<span class="sr-only">yes</span>
<svg class="h-4 w-4 fill-green-500"
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" />
</svg>
{% else %}
<span class="sr-only">no</span>
<svg class="h-4 w-4 fill-red-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512">
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z" />
</svg>
{% endif %}
</p>
</div>
{% if service.get('IS_DRAFT', "no") == "yes" and service["SERVER_NAME"]['method'] in ["ui", "default"] %}
<button class="group relative">
<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>
<!-- end detail -->
{% endfor %}
</div>
<!-- end detail list-->
<!-- button list-->
<div class="relative w-full flex justify-center sm:justify-end">
<a aria-label="access service url"
href="http://{{ service['SERVER_NAME']['value'] }}"
target="_blank"
rel="noopener"
class="dark:brightness-90 z-20 mx-1 bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md">
<svg class="h-6 w-6 fill-white"
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" />
</svg>
</a>
{% set action_buttons = [
{
"name": "clone",
"label": "clone service settings",
"color": "emerald-500"
},
{
"name": "edit",
"label": "edit service settings",
"color": "yellow-500"
}
] %}
{% if service["SERVER_NAME"]['method'] == "ui" %}
{% if action_buttons.append({"name" : "delete", "label" : "delete service settings", "color" : "red-500"}) %}
{% endif %}
{% endif %}
{% for button in action_buttons %}
<button {% if button['name'] == "clone" and is_readonly or button['name'] == "delete" and is_readonly %}disabled{% endif %} {% if button['name'] == "clone" or button['name'] == "edit" %}data-settings="{{ service['settings'] }}"{% endif %} {% if button['name'] == "new" %}data-settings="{}"{% endif %} data-{{ attribute_name }}-action="{{ button['name'] }}" aria-label="{{ button['label'] }}" data-{{ attribute_name }}-name="{{ service['SERVER_NAME']['value'] }}" class="disabled:cursor-not-allowed dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-700 dark:disabled:border-gray-700/0 disabled:hover:translate-y-0 disabled:hover:bg-gray-400 disabled:hover:border-gray-400/0 dark:disabled:hover:translate-y-0 dark:disabled:hover:bg-gray-700 dark:disabled:hover:border-gray-700/0 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"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
<path fill-rule="evenodd" d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z" clip-rule="evenodd" />
class="w-6 h-6 fill-white">
<path fill-rule="evenodd" d="M17.663 3.118c.225.015.45.032.673.05C19.876 3.298 21 4.604 21 6.109v9.642a3 3 0 0 1-3 3V16.5c0-5.922-4.576-10.775-10.384-11.217.324-1.132 1.3-2.01 2.548-2.114.224-.019.448-.036.673-.051A3 3 0 0 1 13.5 1.5H15a3 3 0 0 1 2.663 1.618ZM12 4.5A1.5 1.5 0 0 1 13.5 3H15a1.5 1.5 0 0 1 1.5 1.5H12Z" clip-rule="evenodd" />
<path d="M3 8.625c0-1.036.84-1.875 1.875-1.875h.375A3.75 3.75 0 0 1 9 10.5v1.875c0 1.036.84 1.875 1.875 1.875h1.875A3.75 3.75 0 0 1 16.5 18v2.625c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625v-12Z" />
<path d="M10.5 10.5a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963 5.23 5.23 0 0 0-3.434-1.279h-1.875a.375.375 0 0 1-.375-.375V10.5Z" />
</svg>
</button>
{% else %}
<button class="group relative">
<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>
<svg data-toggle-draft="false"
{% endif %}
{% if button['name'] == "edit" %}
<svg class="h-6 w-6 fill-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
<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" />
viewBox="0 0 512 512">
<path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336c44.2 0 80-35.8 80-80s-35.8-80-80-80s-80 35.8-80 80s35.8 80 80 80z" />
</svg>
</button>
{% endif %}
</div>
{% set details = [
{
"name": "Reverse proxy",
"settings": [
"USE_REVERSE_PROXY"
]
},
{
"name": "Serve files",
"settings": [
"SERVE_FILES"
]
},
{
"name": "Remote PHP",
"settings": [
"REMOTE_PHP"
]
},
{
"name": "HTTPS",
"settings": [
"AUTO_LETS_ENCRYPT",
"USE_CUSTOM_SSL",
"GENERATE_SELF_SIGNED_SSL"
]
},
{
"name": "ModSecurity",
"settings": [
"USE_MODSECURITY"
]
},
{
"name": "Bad behavior",
"settings": [
"USE_BAD_BEHAVIOR"
]
},
{
"name": "Limit req",
"settings": [
"USE_LIMIT_REQ"
]
},
{
"name": "DNSBL",
"settings": [
"USE_DNSBL"
]
}
] %}
<!-- detail list -->
<div role="grid"
class="w-full grid grid-cols-12 justify-items-center sm:justify-items-start gap-2 mt-4 mb-6 ml-3 sm:ml-1">
{% for detail in details %}
{% set use = [] %}
{% for setting in detail['settings'] %}
{% if service[setting]['value'] == 'yes' %}
{% if use.append(1) %}{% endif %}
{% endif %}
{% endfor %}
<!-- detail -->
<div role="row" class="flex items-center col-span-12 sm:col-span-6">
<p role="gridcell"
class="transition duration-300 ease-in-out font-bold mb-0 font-sans text-sm leading-normal uppercase dark:text-gray-500 ">
{{ detail['name'] }}
</p>
<p role="gridcell"
class="transition duration-300 ease-in-out dark:opacity-90 pl-2 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-gray-500 ">
{% if use %}
<span class="sr-only">yes</span>
<svg class="h-4 w-4 fill-green-500"
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" />
</svg>
{% else %}
<span class="sr-only">no</span>
<svg class="h-4 w-4 fill-red-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512">
<path d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z" />
</svg>
{% endif %}
</p>
</div>
<!-- end detail -->
{% endfor %}
</div>
<!-- end detail list-->
<!-- button list-->
<div class="relative w-full flex justify-center sm:justify-end">
<a aria-label="access service url"
href="http://{{ service['SERVER_NAME']['value'] }}"
target="_blank"
rel="noopener"
class="dark:brightness-90 z-20 mx-1 bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md">
<svg class="h-6 w-6 fill-white"
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" />
</svg>
</a>
{% set action_buttons = [
{
"name": "clone",
"label": "clone service settings",
"color": "emerald-500"
},
{
"name": "edit",
"label": "edit service settings",
"color": "yellow-500"
}
] %}
{% if service["SERVER_NAME"]['method'] == "ui" %}
{% if action_buttons.append({"name" : "delete", "label" : "delete service settings", "color" : "red-500"}) %}
{% endif %}
{% endif %}
{% for button in action_buttons %}
<button
{% if button['name'] == "clone" and is_readonly or button['name'] == "delete" and is_readonly%}disabled{% endif %}
{% if button['name'] == "clone" or button['name'] == "edit"%}
data-settings="{{ service['settings'] }}"
{% if button['name'] == "delete" %}
<svg class="h-6 w-6 fill-white"
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>
{% endif %}
{% if button['name'] == "new"%}
data-settings="{}"
{% endif %}
data-{{attribute_name}}-action="{{ button['name'] }}"
aria-label="{{ button['label'] }}"
data-{{attribute_name}}-name="{{ service['SERVER_NAME']['value'] }}"
class="disabled:cursor-not-allowed dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-700 dark:disabled:border-gray-700/0 disabled:hover:translate-y-0 disabled:hover:bg-gray-400 disabled:hover:border-gray-400/0 dark:disabled:hover:translate-y-0 dark:disabled:hover:bg-gray-700 dark:disabled:hover:border-gray-700/0 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"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 fill-white">
<path fill-rule="evenodd" d="M17.663 3.118c.225.015.45.032.673.05C19.876 3.298 21 4.604 21 6.109v9.642a3 3 0 0 1-3 3V16.5c0-5.922-4.576-10.775-10.384-11.217.324-1.132 1.3-2.01 2.548-2.114.224-.019.448-.036.673-.051A3 3 0 0 1 13.5 1.5H15a3 3 0 0 1 2.663 1.618ZM12 4.5A1.5 1.5 0 0 1 13.5 3H15a1.5 1.5 0 0 1 1.5 1.5H12Z" clip-rule="evenodd" />
<path d="M3 8.625c0-1.036.84-1.875 1.875-1.875h.375A3.75 3.75 0 0 1 9 10.5v1.875c0 1.036.84 1.875 1.875 1.875h1.875A3.75 3.75 0 0 1 16.5 18v2.625c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625v-12Z" />
<path d="M10.5 10.5a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963 5.23 5.23 0 0 0-3.434-1.279h-1.875a.375.375 0 0 1-.375-.375V10.5Z" />
</svg>
{% endif %}
{% if button['name'] == "edit" %}
<svg class="h-6 w-6 fill-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336c44.2 0 80-35.8 80-80s-35.8-80-80-80s-80 35.8-80 80s35.8 80 80 80z" />
</svg>
{% endif %}
{% if button['name'] == "delete" %}
<svg class="h-6 w-6 fill-white"
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>
{% endif %}
</button>
{% endfor %}
</div>
<!-- end button list-->
</button>
{% endfor %}
</div>
{% endfor %}
{% endif %}
</div>
<!-- end services container-->
<!-- modal -->
{% include "services_modal.html" %}
<!-- end button list-->
</div>
{% endfor %}
{% endif %}
</div>
<!-- end services container-->
<!-- modal -->
{% include "services_modal.html" %}
{% endblock content %}

View file

@ -1,5 +1,6 @@
<!-- modal -->
<div data-readonly="{% if is_readonly %}true{% else %}false{% endif %}" data-services-plugins-container
<div data-readonly="{% if is_readonly %}true{% else %}false{% endif %}"
data-services-plugins-container
data-services-modal
class="dark:brightness-110 hidden w-screen h-screen fixed bg-gray-600/50 z-[1001] top-0 left-0 justify-center items-center">
<div data-services-modal-card
@ -42,10 +43,8 @@
</svg>
</button>
</div>
{% include "services_modal_settings_advanced.html" %}
{% include "services_modal_delete.html" %}
</div>
</div>
<!-- end modal -->

View file

@ -1,24 +1,24 @@
<!-- delete form-->
<form data-services-modal-form-delete
class="w-full h-full flex flex-col justify-between"
id="form-delete-server_name"
method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" value="delete" name="operation" />
<input type="hidden" value="no" name="is_draft" />
<input type="hidden" value="" name="SERVER_NAME" />
<div class="flex justify-center">
<p data-services-modal-text
class="text-gray-700 dark:text-gray-300 mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm">
</p>
</div>
<!-- action button -->
<div class="w-full justify-center flex mt-10">
<button data-services-modal-close
type="button"
class="close-btn mb-4 mr-3 text-base">Close</button>
<button type="submit" class="delete-btn mb-4 mr-3 text-base">Delete</button>
</div>
<!-- end action button-->
class="w-full h-full flex flex-col justify-between"
id="form-delete-server_name"
method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" value="delete" name="operation" />
<input type="hidden" value="no" name="is_draft" />
<input type="hidden" value="" name="SERVER_NAME" />
<div class="flex justify-center">
<p data-services-modal-text
class="text-gray-700 dark:text-gray-300 mx-2 mb-2 mt-8 font-semibold font-sans leading-normal uppercase text-sm">
</p>
</div>
<!-- action button -->
<div class="w-full justify-center flex mt-10">
<button data-services-modal-close
type="button"
class="close-btn mb-4 mr-3 text-base">Close</button>
<button type="submit" class="delete-btn mb-4 mr-3 text-base">Delete</button>
</div>
<!-- end action button-->
</form>
<!-- end delete form-->

View file

@ -9,12 +9,12 @@
</h5>
<label class="sr-only" for="settings-filter">search</label>
<input type="text"
id="settings-filter"
name="settings-filter"
class="col-span-12 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="keyword"
pattern="(.*?)"
required />
id="settings-filter"
name="settings-filter"
class="col-span-12 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="keyword"
pattern="(.*?)"
required />
</div>
<!-- end search inpt-->
<!-- type plugin -->
@ -24,14 +24,14 @@
data-services-setting-select="type"
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-type"
data-name="services-type"
data-services-setting-select-text="type">all</span>
id="services-type"
data-name="services-type"
data-services-setting-select-text="type">all</span>
<!-- chevron -->
<svg data-services-setting-select="type"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
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">
</path>
</svg>
@ -39,9 +39,9 @@
<!-- end chevron -->
<!-- dropdown-->
<div id="filter-type"
role="listbox"
data-services-setting-select-dropdown="type"
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
role="listbox"
data-services-setting-select-dropdown="type"
class="mt-1 hidden z-100 absolute flex-col w-full translate-y-16 max-h-[350px] overflow-hidden overflow-y-auto">
<button role="option"
data-services-setting-select-dropdown-btn="type"
value="all"
@ -76,31 +76,32 @@
<hr class="separator" />
</div>
</div>
<div data-advanced data-services-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 data-advanced
data-services-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 dark:stroke-white/90 stroke-gray-800">
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mb-2 w-8 h-8 dark:stroke-white/90 stroke-gray-800">
<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-gray-800">No settings match</h5>
</div>
</div>
<!-- new and edit form -->
<form data-advanced data-services-modal-form
class="w-full h-[90vh] overflow-auto flex flex-col justify-between"
id="form-new"
method="POST">
<form data-advanced
data-services-modal-form
class="w-full h-[90vh] overflow-auto flex flex-col justify-between"
id="form-new"
method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" id="operation" value="new" name="operation" />
<input type="hidden" value="new" name="OLD_SERVER_NAME" />
<input type="hidden" value="no" name="is_draft" />
<input type="hidden" value="advanced" name="mode" />
{% include "settings_plugins.html" %}
<!-- action button -->
<div class="w-full flex-col items-center justify-center flex mt-10">
@ -112,6 +113,6 @@
</div>
<!-- end action button-->
<p data-services-modal-error-msg
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
</div>
</form>

View file

@ -9,28 +9,27 @@
{% set global_config_method = global_config.get(inp_name, {'method' : inp_method }).get('method') %}
{% set global_config_value = global_config.get(inp_name, {'value' : inp_value }).get('value') %}
{% set is_read_only = True if setting_input['is_pro_plugin'] and not is_pro_version else False %}
<div data-checkbox-handler="{{ inp_id }}"
class="relative mb-7 md:mb-0 z-10 ">
class="relative mb-7 md:mb-0 z-10 ">
<label class="sr-only" for="{{ inp_name_mult }}">{{ inp_name }}</label>
<input {% if is_readonly%}disabled{% endif %} 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_method }}{% endif %}"
data-default-value="{{ global_config[inp_name]['value'] }}"
{% if inp_name in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] or global_config_method != 'ui' and global_config_method != 'default' or is_read_only %} disabled {% endif %}
data-checked="{% if global_config_value == "yes" %}true{% else %}false{% endif %}"
{% if global_config_value == "yes" %}checked{% endif %}
id="checkbox-{{ inp_id }}"
class="checkbox"
type="checkbox"
data-pattern="{{ inp_regex|safe }}"
value="{{ global_config_value }}"
{% if is_multiple %} data-is-multiple {% endif %}
/>
<input {% if is_readonly %}disabled{% endif %}
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_method }}{% endif %}"
data-default-value="{{ global_config[inp_name]['value'] }}"
{% if inp_name in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] or global_config_method != 'ui' and global_config_method != 'default' or is_read_only %} disabled {% endif %}
data-checked="{% if global_config_value == "yes" %}true{% else %}false{% endif %}"
{% if global_config_value == "yes" %}checked{% endif %}
id="checkbox-{{ inp_id }}"
class="checkbox"
type="checkbox"
data-pattern="{{ inp_regex|safe }}"
value="{{ global_config_value }}"
{% if is_multiple %}data-is-multiple{% endif %} />
<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">
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>

View file

@ -11,39 +11,38 @@
<!-- 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">
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="info popover-settings-container hidden"
data-popover-content="{{ inp_name_mult }}">
aria-description="show detail"
class="info 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="multisite 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>
<!-- 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="multisite 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>
<!-- end popover -->
{% endif %}
</div>
{% endif %}

View file

@ -1,4 +1,3 @@
{% if setting_input and setting_input["type"] != "select" and setting_input["type"] != "check" %}
{% set inp_name = setting_input['name'] %}
{% set is_multiple = setting_input["is_multiple"] %}
@ -10,30 +9,29 @@
{% set global_config_method = global_config.get(inp_name, {'method' : inp_method }).get('method') %}
{% set global_config_value = global_config.get(inp_name, {'value' : inp_value }).get('value') %}
{% set is_read_only = True if setting_input['is_pro_plugin'] and not is_pro_version else False %}
<div class="relative flex items-center">
<label class="sr-only" for="{{ inp_name_mult }}">{{ inp_name }}</label>
<input {% if is_readonly%}disabled{% endif %} {% if inp_name == "SERVER_NAME" %}required{% endif %}
data-default-value="{{ global_config_value }}"
data-default-method="{{ global_config_method }}"
data-setting-input
{% if global_config_method != 'ui' and global_config_method != 'default' or is_read_only %}disabled{% endif %}
id="{{ inp_name_mult }}"
name="{{ inp_name_mult }}"
class="regular-input"
value="{% if global_config_value %} {{ global_config_value }} {% else %} {{ inp_default }} {% endif %}"
type="{{ inp_type }}"
pattern="{{ inp_regex|safe }}"
{% if is_multiple %} data-is-multiple{% endif %}
/>
<input {% if is_readonly %}disabled{% endif %}
{% if inp_name == "SERVER_NAME" %}required{% endif %}
data-default-value="{{ global_config_value }}"
data-default-method="{{ global_config_method }}"
data-setting-input
{% if global_config_method != 'ui' and global_config_method != 'default' or is_read_only %}disabled{% endif %}
id="{{ inp_name_mult }}"
name="{{ inp_name_mult }}"
class="regular-input"
value="{% if global_config_value %} {{ global_config_value }} {% else %} {{ inp_default }} {% endif %}"
type="{{ inp_type }}"
pattern="{{ inp_regex|safe }}"
{% if is_multiple %}data-is-multiple{% endif %} />
{% 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">
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>
@ -41,8 +39,8 @@
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">
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>

View file

@ -5,9 +5,9 @@
{% 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">
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:

View file

@ -11,7 +11,6 @@
{% set global_config_method = global_config.get(inp_name, {'method' : inp_method }).get('method') %}
{% set global_config_value = global_config.get(inp_name, {'value' : inp_value }).get('value') %}
{% set is_read_only = True if setting_input['is_pro_plugin'] and not is_pro_version else False %}
<!-- default hidden-->
<select data-default-method="{{ global_config_method }}"
data-default-value="{{ inp_default }}"
@ -20,8 +19,7 @@
data-setting-select-default="{{ inp_id }}"
data-type="form-select"
class="hidden"
{% if is_multiple %} data-is-multiple {% endif %}
>
{% if is_multiple %}data-is-multiple{% endif %}>
{% for item in inp_items %}
<option {% if not item %}label="empty"{% endif %}
value="{{ item }}"
@ -33,7 +31,8 @@
<!-- end default hidden-->
<!--custom-->
<div data-select-container class="relative">
<button {% if is_readonly%}disabled{% endif %} {% if global_config_method != 'ui' and global_config_method != 'default' or is_read_only %}disabled{% endif %}
<button {% if is_readonly %}disabled{% endif %}
{% if global_config_method != 'ui' and global_config_method != 'default' or is_read_only %}disabled{% endif %}
data-setting-select="{{ inp_id }}"
data-default-value="{{ global_config_value }}"
data-default-method="{{ global_config_method }}"
@ -44,27 +43,27 @@
{% if global_config_value and
global_config_value == item %}
<span data-setting-select-text="{{ inp_id }}"
data-value="{{ global_config_value }}">{{ global_config_value }}</span>
data-value="{{ global_config_value }}">{{ global_config_value }}</span>
{% elif not global_config_value and inp_default == item %}
<span aria-description="current value"
data-setting-select-text="{{ inp_id }}"
data-value="{{ inp_default }}">{{ inp_default }}</span>
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">
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">
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_value and
global_config_value == item or not global_config_value

View file

@ -1,9 +1,9 @@
{% set current_endpoint = current_endpoint or url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
<!-- plugin item -->
{% for plugin in plugins %}
<div data-advanced data-plugin-item="{{ plugin['id'] }}" {% if plugin['type'] == 'pro' and not is_pro_version %} data-pro-disabled {% endif %}"
id="{{ plugin['id'] }}"
class="{% if loop.index != 1 %}hidden{% endif %} w-full px-1">
<div data-advanced data-plugin-item="{{ plugin['id'] }}" {% if plugin['type'] == 'pro' and not is_pro_version %}data-pro-disabled{% endif %}"
id="{{ plugin['id'] }}"
class="{% if loop.index != 1 %}hidden{% endif %} w-full px-1">
<!-- title and desc -->
<div class="col-span-12" data-setting-header>
{% if plugin['type'] == "pro" and not is_pro_version %}
@ -53,7 +53,6 @@
<!-- plugin settings not multiple -->
{% for setting, value in plugin["settings"].items() %}
{% set setting_input = { "is_pro_plugin" : True if plugin["type"] == "pro" else False, "name" : setting, "context" : value.get("context"), "method" : value.get("method"), "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"), "value" : value.get("value"), "is_multiple" : False, "levels" : value.get('levels', {})} %}
{% 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 %}
@ -65,8 +64,7 @@
{% include "setting_input.html" %}
{% include "setting_select.html" %}
{% include "setting_checkbox.html" %}
{% include "setting_invalid.html"%}
{% include "setting_invalid.html" %}
</div>
{% endif %}
{% endif %}
@ -97,7 +95,6 @@
<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 = { "is_pro_plugin" : True if plugin["type"] == "pro" else False, "name" : setting, "context" : value.get("context"), "method" : value.get("method"), "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"), "value" : value.get("value"), "is_multiple" : True, "levels" : value.get('levels', {})} %}
{# render only setting that match the multiple id and context #}
{% if value['multiple'] == multiple and (
current_endpoint == "global-config"
@ -105,23 +102,23 @@
) %}
<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">
{% include "setting_header.html" %}
{% 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 -->
{% 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>
{% endfor %}
<!-- end multiple settings -->
</div>
<!-- end plugin settings -->
</div>
{% endfor %}
<!-- end multiple settings -->
</div>
{% endfor %}
<!-- end plugin item -->

View file

@ -323,15 +323,15 @@
<!-- end auto privacy policy-->
<!-- end email inpt-->
<div class="col-span-12 flex justify-center">
<button tabindex="2"
type="submit"
id="setup-button"
name="setup-button"
value="setup"
class="tracking-wide my-4 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-primary hover:bg-primary/80 focus:bg-primary/80 leading-normal text-sm ease-in shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
Setup
</button>
</div>
<button tabindex="2"
type="submit"
id="setup-button"
name="setup-button"
value="setup"
class="tracking-wide my-4 inline-block px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-primary hover:bg-primary/80 focus:bg-primary/80 leading-normal text-sm ease-in shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
Setup
</button>
</div>
</form>
</div>
</div>

View file

@ -11,7 +11,6 @@
<link rel="stylesheet" href="css/login.css" />
<script defer src="./js/totp.js" nonce="{{ script_nonce }}"></script>
<script src="js/lottie-web.min.js" defer nonce="{{ script_nonce }}"></script>
</head>
<body>
<div data-loader
@ -110,7 +109,9 @@
<!-- end form -->
<!-- particles -->
<div class="-z-10 fixed bg-primary">
<div id="lottie-particles" data-lottie="/lotties/PARTICLES.json" class="fixed top-0 left-0 w-full h-full login-img [&>*]:bg-primary"></div>
<div id="lottie-particles"
data-lottie="/lotties/PARTICLES.json"
class="fixed top-0 left-0 w-full h-full login-img [&>*]:bg-primary"></div>
</div>
</main>
<script nonce="{{ script_nonce }}">