mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
start block requests ui
*add block request endpoint *add block request template *update menu to go to new page
This commit is contained in:
parent
ceb81603dd
commit
a7d3a2fd56
5 changed files with 413 additions and 53 deletions
|
|
@ -1595,6 +1595,18 @@ def logs_container(container_id):
|
|||
return jsonify({"logs": logs, "last_update": int(time() * 1000)})
|
||||
|
||||
|
||||
@app.route("/block_requests", methods=["GET"])
|
||||
@login_required
|
||||
def block_requests():
|
||||
# TODO : Get block requests from database to send it
|
||||
return render_template(
|
||||
"block_requests.html",
|
||||
block_requests=[],
|
||||
username=current_user.get_id(),
|
||||
dark_mode=app.config["DARK_MODE"],
|
||||
)
|
||||
|
||||
|
||||
@app.route("/jobs", methods=["GET"])
|
||||
@login_required
|
||||
def jobs():
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -19,10 +19,10 @@ class ServiceModal {
|
|||
//modal forms
|
||||
this.formNewEdit = this.modal.querySelector("[data-services-modal-form]");
|
||||
this.formDelete = this.modal.querySelector(
|
||||
"[data-services-modal-form-delete]"
|
||||
"[data-services-modal-form-delete]",
|
||||
);
|
||||
this.submitBtn = document.querySelector(
|
||||
"button[data-services-modal-submit]"
|
||||
"button[data-services-modal-submit]",
|
||||
);
|
||||
//container
|
||||
this.container = document.querySelector("main");
|
||||
|
|
@ -165,7 +165,7 @@ class ServiceModal {
|
|||
"delete-btn",
|
||||
"valid-btn",
|
||||
"edit-btn",
|
||||
"info-btn"
|
||||
"info-btn",
|
||||
);
|
||||
this.submitBtn.classList.add(btnType);
|
||||
}
|
||||
|
|
@ -225,15 +225,15 @@ class ServiceModal {
|
|||
//click the custom select dropdown to update select value
|
||||
select.parentElement
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`
|
||||
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`,
|
||||
)
|
||||
.click();
|
||||
|
||||
//set state to custom visible el
|
||||
const btnCustom = document.querySelector(
|
||||
`[data-setting-select=${select.getAttribute(
|
||||
"data-setting-select-default"
|
||||
)}]`
|
||||
"data-setting-select-default",
|
||||
)}]`,
|
||||
);
|
||||
|
||||
this.setDisabledDefault(btnCustom, defaultMethod);
|
||||
|
|
@ -272,9 +272,8 @@ class ServiceModal {
|
|||
|
||||
if (action === "delete") {
|
||||
this.showDeleteForm();
|
||||
formEl.querySelector(
|
||||
`[data-services-modal-text]`
|
||||
).textContent = `Are you sure you want to delete ${serviceName} ?`;
|
||||
formEl.querySelector(`[data-services-modal-text]`).textContent =
|
||||
`Are you sure you want to delete ${serviceName} ?`;
|
||||
const nameInp = formEl.querySelector(`input[name="SERVER_NAME"]`);
|
||||
nameInp.setAttribute("value", serviceName);
|
||||
nameInp.value = serviceName;
|
||||
|
|
@ -384,7 +383,7 @@ class ServiceModal {
|
|||
if (inp.tagName === "SELECT") {
|
||||
inp.parentElement
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn][value='${value}']`
|
||||
`button[data-setting-select-dropdown-btn][value='${value}']`,
|
||||
)
|
||||
.click();
|
||||
inp.setAttribute("data-method", method);
|
||||
|
|
@ -487,7 +486,7 @@ class Multiple {
|
|||
const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`);
|
||||
//get all multiple groups
|
||||
const multipleEls = document.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple*="${attName}"]`
|
||||
`[data-${this.prefix}-settings-multiple*="${attName}"]`,
|
||||
);
|
||||
//case no schema
|
||||
if (multipleEls.length <= 0) return;
|
||||
|
|
@ -499,7 +498,7 @@ class Multiple {
|
|||
//and keep the highest num
|
||||
multipleEls.forEach((container) => {
|
||||
const ctnrName = container.getAttribute(
|
||||
"data-services-settings-multiple"
|
||||
"data-services-settings-multiple",
|
||||
);
|
||||
const num = this.getSuffixNumOrFalse(ctnrName);
|
||||
if (!isNaN(num) && num > topNum) topNum = num;
|
||||
|
|
@ -510,7 +509,7 @@ class Multiple {
|
|||
const setNum = +currNum === 0 ? `` : `_${currNum}`;
|
||||
//the default (schema) group is the last group
|
||||
const schema = document.querySelector(
|
||||
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`
|
||||
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`,
|
||||
);
|
||||
//clone schema to create a group with new num
|
||||
const schemaClone = schema.cloneNode(true);
|
||||
|
|
@ -548,7 +547,7 @@ class Multiple {
|
|||
.hasAttribute(`data-${this.prefix}-multiple-delete`)
|
||||
) {
|
||||
const multContainer = e.target.closest(
|
||||
"[data-services-settings-multiple]"
|
||||
"[data-services-settings-multiple]",
|
||||
);
|
||||
multContainer.remove();
|
||||
}
|
||||
|
|
@ -570,13 +569,13 @@ class Multiple {
|
|||
? name.replace(`_${splitName[splitName.length - 1]}`, "").trim()
|
||||
: name.trim();
|
||||
const relateSetting = document.querySelector(
|
||||
`[data-setting-container=${nameSuffixLess}_SCHEMA]`
|
||||
`[data-setting-container=${nameSuffixLess}_SCHEMA]`,
|
||||
);
|
||||
const relateCtnr = relateSetting.closest(
|
||||
"[data-services-settings-multiple]"
|
||||
"[data-services-settings-multiple]",
|
||||
);
|
||||
const relateCtnrName = relateCtnr.getAttribute(
|
||||
"data-services-settings-multiple"
|
||||
"data-services-settings-multiple",
|
||||
);
|
||||
//then we sort the setting on the right container name by suffixe number
|
||||
if (!(relateCtnrName in sortMultiples)) {
|
||||
|
|
@ -594,7 +593,7 @@ class Multiple {
|
|||
addOneMultGroup() {
|
||||
const settings = document.querySelector("[data-services-modal-form]");
|
||||
const multAddBtns = settings.querySelectorAll(
|
||||
"[data-services-multiple-add]"
|
||||
"[data-services-multiple-add]",
|
||||
);
|
||||
multAddBtns.forEach((btn) => {
|
||||
//check if already one (SCHEMA exclude so length >= 2)
|
||||
|
|
@ -609,7 +608,7 @@ class Multiple {
|
|||
|
||||
showMultByAtt(att) {
|
||||
const multContainers = document.querySelectorAll(
|
||||
`[data-services-settings-multiple^=${att}]`
|
||||
`[data-services-settings-multiple^=${att}]`,
|
||||
);
|
||||
multContainers.forEach((container) => {
|
||||
if (
|
||||
|
|
@ -623,7 +622,7 @@ class Multiple {
|
|||
|
||||
toggleMultByAtt(att) {
|
||||
const multContainers = document.querySelectorAll(
|
||||
`[data-services-settings-multiple^=${att}]`
|
||||
`[data-services-settings-multiple^=${att}]`,
|
||||
);
|
||||
multContainers.forEach((container) => {
|
||||
if (
|
||||
|
|
@ -639,7 +638,7 @@ class Multiple {
|
|||
//get schema settings
|
||||
const multiples = {};
|
||||
const schemaSettings = document.querySelectorAll(
|
||||
`[data-setting-container$="SCHEMA"]`
|
||||
`[data-setting-container$="SCHEMA"]`,
|
||||
);
|
||||
// loop on every schema settings
|
||||
schemaSettings.forEach((schema) => {
|
||||
|
|
@ -665,11 +664,11 @@ class Multiple {
|
|||
setMultipleToDOM(sortMultObj) {
|
||||
//we loop on each multiple that contains values to render to DOM
|
||||
for (const [schemaCtnrName, multGroupBySuffix] of Object.entries(
|
||||
sortMultObj
|
||||
sortMultObj,
|
||||
)) {
|
||||
//we need to access the DOM schema container
|
||||
const schemaCtnr = document.querySelector(
|
||||
`[data-services-settings-multiple="${schemaCtnrName}"]`
|
||||
`[data-services-settings-multiple="${schemaCtnrName}"]`,
|
||||
);
|
||||
//now we have to loop on each multiple settings group
|
||||
for (const [suffix, settings] of Object.entries(multGroupBySuffix)) {
|
||||
|
|
@ -685,14 +684,14 @@ class Multiple {
|
|||
for (const [name, data] of Object.entries(settings)) {
|
||||
//get setting container of clone container
|
||||
const settingContainer = schemaCtnrClone.querySelector(
|
||||
`[data-setting-container="${name}"]`
|
||||
`[data-setting-container="${name}"]`,
|
||||
);
|
||||
//replace input info and disabled state
|
||||
this.setSetting(
|
||||
data["value"],
|
||||
data["method"],
|
||||
data["global"],
|
||||
settingContainer
|
||||
settingContainer,
|
||||
);
|
||||
}
|
||||
//send schema clone to DOM and show it
|
||||
|
|
@ -707,7 +706,7 @@ class Multiple {
|
|||
"data-services-settings-multiple",
|
||||
schemaCtnrClone
|
||||
.getAttribute("data-services-settings-multiple")
|
||||
.replace("_SCHEMA", suffix)
|
||||
.replace("_SCHEMA", suffix),
|
||||
);
|
||||
|
||||
//rename title
|
||||
|
|
@ -721,18 +720,18 @@ class Multiple {
|
|||
|
||||
//rename setting container
|
||||
const settingCtnrs = schemaCtnrClone.querySelectorAll(
|
||||
"[data-setting-container]"
|
||||
"[data-setting-container]",
|
||||
);
|
||||
settingCtnrs.forEach((settingCtnr) => {
|
||||
settingCtnr.setAttribute(
|
||||
"data-setting-container",
|
||||
settingCtnr
|
||||
.getAttribute("data-setting-container")
|
||||
.replace("_SCHEMA", suffix)
|
||||
.replace("_SCHEMA", suffix),
|
||||
);
|
||||
settingCtnr.setAttribute(
|
||||
"id",
|
||||
settingCtnr.getAttribute("id").replace("_SCHEMA", suffix)
|
||||
settingCtnr.getAttribute("id").replace("_SCHEMA", suffix),
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -809,15 +808,15 @@ class Multiple {
|
|||
//click the custom select dropdown btn value to update select value
|
||||
select.parentElement
|
||||
.querySelector(
|
||||
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`
|
||||
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`,
|
||||
)
|
||||
.click();
|
||||
|
||||
//set state to custom visible el
|
||||
const btnCustom = document.querySelector(
|
||||
`[data-setting-select=${select.getAttribute(
|
||||
"data-setting-select-default"
|
||||
)}]`
|
||||
"data-setting-select-default",
|
||||
)}]`,
|
||||
);
|
||||
|
||||
this.setDisabledMultServ(btnCustom, method, global);
|
||||
|
|
@ -853,10 +852,10 @@ class Multiple {
|
|||
selects.forEach((select) => {
|
||||
const method = select.getAttribute("data-default-method");
|
||||
const name = select.getAttribute(
|
||||
"data-services-setting-select-default"
|
||||
"data-services-setting-select-default",
|
||||
);
|
||||
const selDOM = document.querySelector(
|
||||
`button[data-services-setting-select='${name}']`
|
||||
`button[data-services-setting-select='${name}']`,
|
||||
);
|
||||
if (method === "ui" || method === "default") {
|
||||
selDOM.removeAttribute("disabled", "");
|
||||
|
|
@ -891,7 +890,7 @@ class Multiple {
|
|||
hiddenIfNoMultiples() {
|
||||
//hide multiple btn if no multiple exist on a plugin
|
||||
const multiples = document.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple]`
|
||||
`[data-${this.prefix}-settings-multiple]`,
|
||||
);
|
||||
multiples.forEach((container) => {
|
||||
if (container.querySelectorAll(`[data-setting-container]`).length <= 0)
|
||||
|
|
@ -903,7 +902,7 @@ class Multiple {
|
|||
|
||||
removePrevMultiples() {
|
||||
const multiPlugins = document.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple]`
|
||||
`[data-${this.prefix}-settings-multiple]`,
|
||||
);
|
||||
multiPlugins.forEach((multiGrp) => {
|
||||
if (
|
||||
|
|
@ -941,7 +940,7 @@ const setModal = new ServiceModal();
|
|||
const format = new FormatValue();
|
||||
const setFilterGlobal = new FilterSettings(
|
||||
"settings-filter",
|
||||
"[data-service-content='settings']"
|
||||
"[data-service-content='settings']",
|
||||
);
|
||||
|
||||
const setMultiple = new Multiple("services");
|
||||
|
|
|
|||
331
src/ui/templates/block_requests.html
vendored
Normal file
331
src/ui/templates/block_requests.html
vendored
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
{% extends "base.html" %} {% block content %} {% set current_endpoint =
|
||||
url_for(request.endpoint)[1:].split("/")[-1].strip() %}
|
||||
<!-- info-->
|
||||
<div
|
||||
class="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 class="mx-1 flex items-center my-4">
|
||||
<p
|
||||
class="transition duration-300 ease-in-out font-bold mb-0 font-sans text-sm leading-normal uppercase dark:text-gray-500 dark:opacity-80"
|
||||
>
|
||||
BLOCK REQUESTS TOTAL
|
||||
</p>
|
||||
<p
|
||||
class="transition duration-300 ease-in-out pl-2 col-span-1 mb-0 font-sans text-sm font-semibold leading-normal uppercase dark:text-white dark:opacity-80"
|
||||
>
|
||||
{{block_requests|length}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- end info -->
|
||||
|
||||
<!-- filter -->
|
||||
<div
|
||||
data-{{current_endpoint}}-filter
|
||||
class="col-span-12 md:col-span-8 2xl:col-span-6 3xl:col-span-5 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
|
||||
>
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5
|
||||
class="my-1 transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300"
|
||||
>
|
||||
Search
|
||||
</h5>
|
||||
<label for="keyword" class="sr-only">search</label>
|
||||
<input
|
||||
type="text"
|
||||
id="keyword"
|
||||
name="keyword"
|
||||
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="keyword"
|
||||
pattern="(.*?)"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
|
||||
<!-- select success -->
|
||||
<div class="flex flex-col relative col-span-12 md:col-span-6">
|
||||
<h5
|
||||
class="my-1 transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300"
|
||||
>
|
||||
Success state
|
||||
</h5>
|
||||
<button
|
||||
aria-controls="filter-state"
|
||||
data-{{current_endpoint}}-setting-select="success"
|
||||
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="{{current_endpoint}}-success"
|
||||
data-name="{{current_endpoint}}-success"
|
||||
data-{{current_endpoint}}-setting-select-text="success"
|
||||
>all</span
|
||||
>
|
||||
<!-- chevron -->
|
||||
<svg
|
||||
data-{{current_endpoint}}-setting-select="success"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<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-state"
|
||||
role="listbox"
|
||||
data-{{current_endpoint}}-setting-select-dropdown="success"
|
||||
class="hidden z-100 absolute h-full flex-col w-full translate-y-16"
|
||||
>
|
||||
<button
|
||||
role="option"
|
||||
data-{{current_endpoint}}-setting-select-dropdown-btn="success"
|
||||
value="all"
|
||||
class="border-t rounded-t border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 dark:bg-primary bg-primary text-gray-300"
|
||||
>
|
||||
all
|
||||
</button>
|
||||
<button
|
||||
role="option"
|
||||
data-{{current_endpoint}}-setting-select-dropdown-btn="success"
|
||||
value="false"
|
||||
class="border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
|
||||
>
|
||||
false
|
||||
</button>
|
||||
<button
|
||||
role="option"
|
||||
data-{{current_endpoint}}-setting-select-dropdown-btn="success"
|
||||
value="true"
|
||||
class="rounded-b border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
|
||||
>
|
||||
true
|
||||
</button>
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select success -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- end filter -->
|
||||
|
||||
<div
|
||||
class="w-full overflow-hidden overflow-y-auto overflow-x-auto max-h-100 sm:max-h-125 min-h-50-screen 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="mb-4 mt-2 font-bold dark:text-white/90 mx-2">BLOCK REQUESTS</h5>
|
||||
<!-- list container-->
|
||||
<div class="min-w-[900px] w-full grid grid-cols-12 rounded p-2">
|
||||
<!-- header-->
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-3 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Name
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-3 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Last run
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-1 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Every
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-1 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Reload
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-1 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Success
|
||||
</p>
|
||||
<p
|
||||
class="dark:text-gray-300 h-8 text-sm font-bold col-span-3 m-0 pb-2 border-b border-gray-400"
|
||||
>
|
||||
Files
|
||||
</p>
|
||||
<!-- end header-->
|
||||
<!-- list -->
|
||||
<ul class="col-span-12 w-full" data-{{current_endpoint}}-list>
|
||||
{% for request, value in block_requests.items() %}
|
||||
<li
|
||||
|
||||
class="items-center grid grid-cols-12 border-b border-gray-300 py-2.5"
|
||||
>
|
||||
<p
|
||||
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-3 m-0 my-1"
|
||||
data-{{current_endpoint}}-name
|
||||
>
|
||||
{{request}}
|
||||
</p>
|
||||
<p
|
||||
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-3 m-0 my-1"
|
||||
data-{{current_endpoint}}-last_run
|
||||
>
|
||||
{{value['last_run']}}
|
||||
</p>
|
||||
<p
|
||||
|
||||
class="dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
|
||||
data-{{current_endpoint}}-every
|
||||
>
|
||||
{{value["every"]}}
|
||||
</p>
|
||||
{% if value["reload"] %}
|
||||
<p
|
||||
|
||||
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
|
||||
data-{{current_endpoint}}-reload="true"
|
||||
>
|
||||
<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 not value["reload"] %}
|
||||
<p
|
||||
|
||||
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
|
||||
data-{{current_endpoint}}-reload="false"
|
||||
>
|
||||
<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 value["success"] %}
|
||||
<p
|
||||
|
||||
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
|
||||
data-{{current_endpoint}}-success="true"
|
||||
>
|
||||
<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>
|
||||
{% elif not value["success"] %}
|
||||
<p
|
||||
|
||||
class="ml-6 dark:text-gray-400 dark:opacity-80 text-sm col-span-1 m-0 my-1"
|
||||
data-{{current_endpoint}}-success="false"
|
||||
>
|
||||
<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 %}
|
||||
<div
|
||||
|
||||
class="relative dark:text-gray-400 text-sm col-span-3 m-0 my-1"
|
||||
data-{{current_endpoint}}-files
|
||||
>
|
||||
{% if value['cache']%}
|
||||
<button
|
||||
data-{{current_endpoint}}-setting-select="{{request}}"
|
||||
class="py-1 text-sm disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left leading-6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
>
|
||||
<span
|
||||
id="{{current_endpoint}}-{{request}}"
|
||||
data-name="{{current_endpoint}}-{{request}}"
|
||||
data-{{current_endpoint}}-setting-select-text="{{request}}"
|
||||
>files</span
|
||||
>
|
||||
<!-- chevron -->
|
||||
<svg
|
||||
data-{{current_endpoint}}-setting-select="{{request}}"
|
||||
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-{{current_endpoint}}-setting-select-dropdown="{{request}}"
|
||||
class="hidden z-100 absolute h-full flex-col w-full translate-y-0.5"
|
||||
>
|
||||
{% for file in value['cache'] %}
|
||||
<button
|
||||
data-{{current_endpoint}}-download="{{request}}"
|
||||
data-{{current_endpoint}}-file="{{file['file_name']}}"
|
||||
data-{{current_endpoint}}-setting-select-dropdown-btn="{{request}}"
|
||||
value="list"
|
||||
class="{% if loop.index == loop.length %}rounded-b-lg {% endif %}{% if loop.first %}rounded-t-lg{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 bg-white dark:bg-slate-700 text-gray-700"
|
||||
>
|
||||
<span class="flex justify-start items-center">
|
||||
<svg
|
||||
class="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"
|
||||
class="w-6 h-6"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M9 12.75l3 3m0 0l3-3m-3 3v-7.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span
|
||||
class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-2"
|
||||
>{{file['file_name']}}</span
|
||||
>
|
||||
</span>
|
||||
</button>
|
||||
{%endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
{%endif%}
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<!-- end list-->
|
||||
</div>
|
||||
<!-- end list container-->
|
||||
</div>
|
||||
{% endblock %}
|
||||
48
src/ui/templates/menu.html
vendored
48
src/ui/templates/menu.html
vendored
|
|
@ -133,20 +133,12 @@
|
|||
<div
|
||||
class="mr-2 flex items-center justify-center rounded-lg bg-center stroke-0 text-center p-1 xl:p-1.5"
|
||||
>
|
||||
<svg
|
||||
class="stroke-red-500 h-5.5 w-5.5 relative"
|
||||
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="M5.636 5.636a9 9 0 1012.728 0M12 3v9"
|
||||
/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
class="stroke-stone-500 h-5.5 w-5.5 relative"
|
||||
>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<span class="ml-1 duration-300 opacity-100 pointer-events-none ease"
|
||||
>Instances</span
|
||||
|
|
@ -309,6 +301,31 @@
|
|||
</a>
|
||||
</li>
|
||||
<!-- end item -->
|
||||
<!-- item -->
|
||||
<li class="mt-0.5 w-full">
|
||||
<a
|
||||
class="{% if current_endpoint == 'block_requests' %}font-semibold text-slate-700 dark:bg-primary/50 rounded-lg dark:hover:bg-primary/60 bg-primary/20 hover:bg-primary/30{% else %}dark:hover:bg-primary/20 hover:bg-primary/5 {% endif %} hover:rounded-lg dark:text-white dark:opacity-80 py-1 text-sm ease-nav-brand my-0 mx-2 flex items-center whitespace-nowrap px-4 transition"
|
||||
href="{% if current_endpoint == 'block_requests' %}#{% else %}loading?next={{ url_for('block_requests') }}{% endif %}"
|
||||
>
|
||||
<div
|
||||
class="mr-2 flex items-center justify-center rounded-lg bg-center stroke-0 text-center p-1 xl:p-1.5"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
class="stroke-red-500 dark:stroke-red-500 h-6 w-6 relative"
|
||||
>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 0 0 5.636 5.636m12.728 12.728A9 9 0 0 1 5.636 5.636m12.728 12.728L5.636 5.636" />
|
||||
</svg>
|
||||
|
||||
|
||||
</div>
|
||||
<span class="ml-1 duration-300 opacity-100 pointer-events-none ease"
|
||||
>
|
||||
Block requests
|
||||
</span
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
<!-- end item -->
|
||||
<!-- item -->
|
||||
<li class="mt-0.5 w-full">
|
||||
<a
|
||||
|
|
@ -334,7 +351,8 @@
|
|||
</svg>
|
||||
</div>
|
||||
<span class="ml-1 duration-300 opacity-100 pointer-events-none ease"
|
||||
>Logs</span
|
||||
>Logs
|
||||
</span
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
|||
Loading…
Reference in a new issue