mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
update configs page + fix select filter
* remove hardcode value by define value for filter select * fix add file button enabled using breadcrumb on root * add file manager configs filters : show only global conf, or show only path that lead to a conf * handle new filters directly on file manager class if any * add configs info using js script : get total configs and total global configs
This commit is contained in:
parent
d0e73d73af
commit
d1f8f84ad9
10 changed files with 629 additions and 230 deletions
File diff suppressed because one or more lines are too long
|
|
@ -5,7 +5,270 @@ import {
|
|||
FolderDropdown,
|
||||
} from "./utils/file.manager.js";
|
||||
|
||||
class Dropdown {
|
||||
constructor(prefix = "configs") {
|
||||
this.prefix = prefix;
|
||||
this.container = document.querySelector("main");
|
||||
this.lastDrop = "";
|
||||
this.initDropdown();
|
||||
}
|
||||
|
||||
initDropdown() {
|
||||
this.container.addEventListener("click", (e) => {
|
||||
//SELECT BTN LOGIC
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-setting-select`) &&
|
||||
!e.target.closest("button").hasAttribute(`disabled`)
|
||||
) {
|
||||
const btnName = e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-setting-select`);
|
||||
if (this.lastDrop !== btnName) {
|
||||
this.lastDrop = btnName;
|
||||
this.closeAllDrop();
|
||||
}
|
||||
|
||||
this.toggleSelectBtn(e);
|
||||
}
|
||||
} catch (err) {}
|
||||
//SELECT DROPDOWN BTN LOGIC
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-setting-select-dropdown-btn`)
|
||||
) {
|
||||
const btn = e.target.closest("button");
|
||||
const btnValue = btn.getAttribute("value");
|
||||
const btnSetting = btn.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown-btn`,
|
||||
);
|
||||
//stop if same value to avoid new fetching
|
||||
const isSameVal = this.isSameValue(btnSetting, btnValue);
|
||||
if (isSameVal) return this.hideDropdown(btnSetting);
|
||||
//else, add new value to custom
|
||||
this.setSelectNewValue(btnSetting, btnValue);
|
||||
//close dropdown and change style
|
||||
this.hideDropdown(btnSetting);
|
||||
|
||||
if (
|
||||
!e.target.closest("button").hasAttribute(`data-${this.prefix}-file`)
|
||||
) {
|
||||
this.changeDropBtnStyle(btnSetting, btn);
|
||||
}
|
||||
//show / hide filter
|
||||
if (btnSetting === "instances") {
|
||||
this.hideFilterOnLocal(btn.getAttribute("data-_type"));
|
||||
}
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
closeAllDrop() {
|
||||
const drops = document.querySelectorAll(
|
||||
`[data-${this.prefix}-setting-select-dropdown]`,
|
||||
);
|
||||
drops.forEach((drop) => {
|
||||
drop.classList.add("hidden");
|
||||
drop.classList.remove("flex");
|
||||
document
|
||||
.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
|
||||
`data-${this.prefix}-setting-select-dropdown`,
|
||||
)}"]`,
|
||||
)
|
||||
.classList.remove("rotate-180");
|
||||
});
|
||||
}
|
||||
|
||||
isSameValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`,
|
||||
);
|
||||
const currVal = selectCustom.textContent;
|
||||
return currVal === value ? true : false;
|
||||
}
|
||||
|
||||
setSelectNewValue(btnSetting, value) {
|
||||
const selectCustom = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
selectCustom.querySelector(
|
||||
`[data-${this.prefix}-setting-select-text]`,
|
||||
).textContent = value;
|
||||
}
|
||||
|
||||
hideDropdown(btnSetting) {
|
||||
//hide dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
dropdownEl.classList.add("hidden");
|
||||
dropdownEl.classList.remove("flex");
|
||||
//svg effect
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
|
||||
);
|
||||
dropdownChevron.classList.remove("rotate-180");
|
||||
}
|
||||
|
||||
changeDropBtnStyle(btnSetting, selectedBtn) {
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
|
||||
);
|
||||
//reset dropdown btns
|
||||
const btnEls = dropdownEl.querySelectorAll("button");
|
||||
|
||||
btnEls.forEach((btn) => {
|
||||
btn.classList.remove(
|
||||
"bg-primary",
|
||||
"dark:bg-primary",
|
||||
"text-gray-300",
|
||||
"text-gray-300",
|
||||
);
|
||||
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
|
||||
});
|
||||
//highlight clicked btn
|
||||
selectedBtn.classList.remove(
|
||||
"bg-white",
|
||||
"dark:bg-slate-700",
|
||||
"text-gray-700",
|
||||
);
|
||||
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
|
||||
}
|
||||
|
||||
toggleSelectBtn(e) {
|
||||
const attribute = e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-setting-select`);
|
||||
//toggle dropdown
|
||||
const dropdownEl = document.querySelector(
|
||||
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
|
||||
);
|
||||
const dropdownChevron = document.querySelector(
|
||||
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
|
||||
);
|
||||
dropdownEl.classList.toggle("hidden");
|
||||
dropdownEl.classList.toggle("flex");
|
||||
dropdownChevron.classList.toggle("rotate-180");
|
||||
}
|
||||
|
||||
//hide date filter on local
|
||||
hideFilterOnLocal(type) {
|
||||
if (type === "local") {
|
||||
this.hideInp(`input#from-date`);
|
||||
this.hideInp(`input#to-date`);
|
||||
}
|
||||
|
||||
if (type !== "local") {
|
||||
this.showInp(`input#from-date`);
|
||||
this.showInp(`input#to-date`);
|
||||
}
|
||||
}
|
||||
|
||||
showInp(selector) {
|
||||
document.querySelector(selector).closest("div").classList.add("flex");
|
||||
document.querySelector(selector).closest("div").classList.remove("hidden");
|
||||
}
|
||||
|
||||
hideInp(selector) {
|
||||
document.querySelector(selector).closest("div").classList.add("hidden");
|
||||
document.querySelector(selector).closest("div").classList.remove("flex");
|
||||
}
|
||||
}
|
||||
|
||||
class Filter {
|
||||
constructor(prefix = "configs") {
|
||||
this.prefix = prefix;
|
||||
this.container = document.querySelector(`[data-${this.prefix}-filter]`);
|
||||
this.confPathOnlyValue = "false";
|
||||
this.globalConfOnlyValue = "false";
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
this.setPathWithConfFilter();
|
||||
this.initHandler();
|
||||
});
|
||||
}
|
||||
|
||||
setPathWithConfFilter() {
|
||||
// get all .conf by path
|
||||
const confs = document.querySelectorAll("[data-path*='.conf']");
|
||||
// for each, get previous path and set attribute data-path-to-a-conf
|
||||
confs.forEach((conf) => {
|
||||
const separatePath = conf.getAttribute("data-path").split("/");
|
||||
separatePath.shift();
|
||||
for (let i = 0; i < separatePath.length; i++) {
|
||||
// merge path to given index
|
||||
const path = separatePath
|
||||
.slice(0, i + 1)
|
||||
.join("/")
|
||||
.trim();
|
||||
// get element with
|
||||
const folder = document.querySelector(`[data-path="/${path}"]`);
|
||||
if (!folder) continue;
|
||||
// set attribute data-path-to-a-conf
|
||||
folder.setAttribute("data-path-to-a-conf", "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initHandler() {
|
||||
this.container.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
|
||||
"withconf" ||
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-setting-select-dropdown-btn`) ===
|
||||
"globalconf"
|
||||
) {
|
||||
setTimeout(() => {
|
||||
// return to root to avoid conflict, filter logic is on file.manager.js
|
||||
document
|
||||
.querySelector('[data-configs-breadcrumb-item][data-level="0"]')
|
||||
.querySelector("button")
|
||||
.click();
|
||||
}, 50);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigsInfo {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
this.totalInfo = document.querySelector("[data-info-total-conf]");
|
||||
this.globalInfo = document.querySelector("[data-info-global-conf]");
|
||||
this.totalInfo.textContent = document
|
||||
.querySelector("[data-configs-folders]")
|
||||
.querySelectorAll("[data-_type='file']").length;
|
||||
this.globalInfo.textContent = document
|
||||
.querySelector("[data-configs-folders]")
|
||||
.querySelectorAll("[data-_type='file'][data-level='2']").length;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const setConfigsInfo = new ConfigsInfo();
|
||||
const setModal = new FolderModal("configs");
|
||||
const setEditor = new FolderEditor();
|
||||
const setFolderNav = new FolderNav("configs");
|
||||
const setDropdown = new FolderDropdown("configs");
|
||||
const setFilterDropdown = new Dropdown("configs");
|
||||
const setFilter = new Filter();
|
||||
|
|
|
|||
|
|
@ -93,10 +93,13 @@ class FolderNav {
|
|||
|
||||
//check if file/folder can be created on folder
|
||||
updateActions(folder) {
|
||||
// for root
|
||||
if (!folder) return this.addFileEl.setAttribute("disabled", "");
|
||||
//check if folder allow add file/folder
|
||||
const isAddFile = folder.getAttribute("data-can-create-file");
|
||||
console.log(isAddFile, "isAddFile")
|
||||
isAddFile === "True" ? this.addFileEl.removeAttribute("disabled") : this.addFileEl.setAttribute("disabled", "");
|
||||
const isAddFile = folder.getAttribute("data-can-create-file") || "False";
|
||||
isAddFile === "True"
|
||||
? this.addFileEl.removeAttribute("disabled")
|
||||
: this.addFileEl.setAttribute("disabled", "");
|
||||
}
|
||||
|
||||
showCurrentFolderEls(path, lvl) {
|
||||
|
|
@ -105,6 +108,37 @@ class FolderNav {
|
|||
);
|
||||
for (let i = 0; i < nestedEl.length; i++) {
|
||||
const el = nestedEl[i];
|
||||
try {
|
||||
// check filter before showing if any (case configs page)
|
||||
const onlyPathWithConf = document
|
||||
.querySelector('[data-configs-setting-select-text="withconf"]')
|
||||
.textContent.trim()
|
||||
.toLowerCase();
|
||||
const onlyGlobalConf = document
|
||||
.querySelector('[data-configs-setting-select-text="globalconf"]')
|
||||
.textContent.trim()
|
||||
.toLowerCase();
|
||||
if (
|
||||
onlyPathWithConf === "true" &&
|
||||
!el.hasAttribute("data-path-to-a-conf")
|
||||
) {
|
||||
el.classList.add("hidden");
|
||||
continue;
|
||||
}
|
||||
if (onlyGlobalConf === "true") {
|
||||
const type = el.getAttribute("data-_type");
|
||||
const level = el.getAttribute("data-level");
|
||||
|
||||
if (+level > 2) {
|
||||
el.classList.add("hidden");
|
||||
continue;
|
||||
}
|
||||
if (level === "2" && type === "folder") {
|
||||
el.classList.add("hidden");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (err) {}
|
||||
el.setAttribute("data-current-el", "");
|
||||
el.classList.remove("hidden");
|
||||
}
|
||||
|
|
@ -341,11 +375,14 @@ class FolderModal {
|
|||
|
||||
//HANDLERS
|
||||
initAddConfig() {
|
||||
if (this.prefix !== "configs") return;
|
||||
this.addConfContainer.addEventListener("click", (e) => {
|
||||
//add file
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").hasAttribute(`data-${this.prefix}-add-file`)
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-add-file`)
|
||||
) {
|
||||
this.setModal(
|
||||
"new",
|
||||
|
|
|
|||
2
src/ui/templates/bans.html
vendored
2
src/ui/templates/bans.html
vendored
|
|
@ -118,7 +118,7 @@
|
|||
<span aria-description="current filter state value"
|
||||
id="bans-{{ filter['id'] }}"
|
||||
data-name="bans-{{ filter['id'] }}"
|
||||
data-bans-setting-select-text="{{ filter['id'] }}">all</span>
|
||||
data-bans-setting-select-text="{{ filter['id'] }}">{{ filter['value']}}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-bans-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
|
|
|
|||
108
src/ui/templates/configs.html
vendored
108
src/ui/templates/configs.html
vendored
|
|
@ -1,4 +1,112 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
|
||||
{% set configs_info = [
|
||||
{ "id" : "total-conf", "name" : "CONFIGS TOTAL", "data" : "unknown"},
|
||||
{ "id" : "global-conf", "name" : "CONFIGS GLOBAL", "data" : "unknown"},
|
||||
] %}
|
||||
<div class="h-fit col-span-12 md:col-span-4 3xl:col-span-3 p-4 relative min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">INFO</h5>
|
||||
{% for info in configs_info %}
|
||||
<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">
|
||||
{{ info['name'] }}
|
||||
</p>
|
||||
<p data-info-{{info['id']}} 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">
|
||||
{{ info['data'] }}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end info -->
|
||||
<!-- filter -->
|
||||
{% set filters = [
|
||||
{
|
||||
"type": "select",
|
||||
"name": "Path with conf only",
|
||||
"id": "withconf",
|
||||
"value": "false",
|
||||
"values": [
|
||||
"false",
|
||||
"true",
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"name": "Show global conf only",
|
||||
"id": "globalconf",
|
||||
"value": "false",
|
||||
"values": [
|
||||
"false",
|
||||
"true"
|
||||
]
|
||||
},
|
||||
] %}
|
||||
<div data-configs-filter
|
||||
class="h-fit col-span-12 md:col-span-8 lg:col-span-5 2xl:col-span-4 3xl:col-span-3 p-4 relative flex flex-col min-w-0 break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">FILTER</h5>
|
||||
<div class="mx-2 grid grid-cols-12 gap-x-4 gap-y-2">
|
||||
{% for filter in filters %}
|
||||
{% if filter['type'] == 'input' %}
|
||||
<!-- search inpt-->
|
||||
<div class="flex flex-col relative col-span-12">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<label for="{{ filter['id'] }}" class="sr-only">{{ filter['label'] }}</label>
|
||||
<input type="text"
|
||||
id="{{ filter['id'] }}"
|
||||
name="{{ filter['id'] }}"
|
||||
class="dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:valid:border-green-500 focus:invalid:border-red-500 outline-none focus:border-primary text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-3 py-1 font-normal text-gray-700 transition-all placeholder:text-gray-500"
|
||||
placeholder="{{ filter['placeholder'] }}"
|
||||
pattern="{{ filter['pattern'] }}"
|
||||
required />
|
||||
</div>
|
||||
<!-- end search inpt-->
|
||||
{% endif %}
|
||||
{% if filter['type'] == 'select' %}
|
||||
<!-- select -->
|
||||
<div class="flex flex-col relative col-span-12">
|
||||
<h5 class="my-1 transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300">
|
||||
{{ filter['name'] }}
|
||||
</h5>
|
||||
<button aria-controls="filter-{{ filter['id'] }}"
|
||||
data-configs-setting-select="{{ filter['id'] }}"
|
||||
class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 font-normal text-gray-700 transition-all placeholder:text-gray-500">
|
||||
<span aria-description="current filter state value"
|
||||
id="configs{{ filter['id'] }}"
|
||||
data-name="configs{{ filter['id'] }}"
|
||||
data-configs-setting-select-text="{{ filter['id'] }}">{{ filter['value']}}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-configs-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
</button>
|
||||
<!-- end chevron -->
|
||||
<!-- dropdown-->
|
||||
<div id="filter-{{ filter['id'] }}"
|
||||
role="listbox"
|
||||
data-configs-setting-select-dropdown="{{ filter['id'] }}"
|
||||
class="hidden z-100 absolute h-full flex-col w-full translate-y-16">
|
||||
{% for value in filter['values'] %}
|
||||
<button role="option"
|
||||
data-configs-setting-select-dropdown-btn="{{ filter['id'] }}"
|
||||
value="{{ value }}"
|
||||
class="{% if loop.first %}dark:bg-primary bg-primary text-gray-300 border-t rounded-t {% else %} bg-white {% endif %} {% if loop.last %}rounded-b{% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 my-0 relative py-2 px-3 text-left align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300">
|
||||
{{ value }}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end select -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end filter -->
|
||||
{% include "file_manager.html" %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
431
src/ui/templates/file_manager.html
vendored
431
src/ui/templates/file_manager.html
vendored
|
|
@ -1,254 +1,245 @@
|
|||
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
|
||||
<!-- main container -->
|
||||
<div data-{{ current_endpoint }}-container class="dark:brightness-110 md:min-h-75-screen col-span-12 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">
|
||||
<div class="w-full grid-cols-12 grid">
|
||||
<div class="col-span-12 md:col-span-8">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">
|
||||
{% if current_endpoint == "configs" %}
|
||||
SERVICE MANAGER
|
||||
{% else %}
|
||||
FILE
|
||||
MANAGER
|
||||
{% endif %}
|
||||
</h5>
|
||||
<!--breadcrumb -->
|
||||
<ul data-{{ current_endpoint }}-breadcrumb class="flex flex-wrap bg-transparent rounded-lg md:mb-8">
|
||||
<li data-{{ current_endpoint }}-breadcrumb-item data-{{ current_endpoint }}-back class="mr-3 cursor-pointer text-sm capitalize leading-normal dark:text-gray-500 text-gray-600" aria-current="page">
|
||||
<svg class="w-4.5 h-4.5 hover:brigthness-80"
|
||||
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 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3" />
|
||||
</svg>
|
||||
</li>
|
||||
<li data-{{ current_endpoint }}-breadcrumb-item data-level="0" data-path="{% if current_endpoint == "cache" %}/var/cache/bunkerweb{% elif current_endpoint == "configs" %}/etc/bunkerweb/{{ current_endpoint }}{% endif %}" data-name="{{ current_endpoint }}" class="leading-normal text-sm">
|
||||
<button class="dark:text-gray-500 text-gray-600 after:float-right after:pl-2 after:text-gray-600 dark:after:text-gray-500 after:content-['/']">
|
||||
{{ current_endpoint }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end breadcrumb -->
|
||||
</div>
|
||||
<!-- actions -->
|
||||
<ul data-{{ current_endpoint }}-add-container class="col-span-12 md:col-span-4 mt-4 mb-6 md:mt-0 md:mb-3 w-full flex justify-center md:justify-end items-center">
|
||||
<li data-{{ current_endpoint }}-add-folder class="rounded transition hidden flex-col items-center mx-2 p-2 md:py-4 md:px-6 relative cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-800">
|
||||
<button>
|
||||
<svg class="relative dark:brightness-125 h-8 w-8 lg:h-9 lg:w-9 fill-primary stroke-gray-100 dark:stroke-gray-600"
|
||||
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.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7m0 0a3 3 0 01-3 3m0 3h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008zm-3 6h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008z" />
|
||||
</svg>
|
||||
<span class="dark:text-gray-500 pt-1 mb-0 font-sans font-semibold leading-normal uppercase text-sm lg:text-md">
|
||||
ADD SERVICE
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
<li data-{{ current_endpoint }}-add-file class="rounded transition hidden flex-col items-center mx-2 p-2 md:py-4 md:px-6 relative cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-800">
|
||||
<button>
|
||||
<svg class="-translate-x-1 relative dark:brightness-125 h-8 w-8 lg:h-9 lg:w-9 fill-primary stroke-gray-100 dark:stroke-gray-600"
|
||||
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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
||||
</svg>
|
||||
<span class="dark:text-gray-500 pt-1 mb-0 font-sans font-semibold leading-normal uppercase text-sm lg:text-md">
|
||||
ADD FILE
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end actions -->
|
||||
</div>
|
||||
<!-- folders-->
|
||||
<div data-{{ current_endpoint }}-folders class="grid grid-cols-12 gap-3">
|
||||
{% for folder in folders %}
|
||||
{% for child in folder['children'] recursive %}
|
||||
{{ loop(child['children']) }}
|
||||
<!-- folder -->
|
||||
<div data-{{ current_endpoint }}-element="{{ child['name'] }}" data-name="{{ child['name'] }}" data-can-create-folder="{{ child['can_create_folders'] }}" data-can-create-file="{{ child['can_create_files'] }}" data-path="{{ child['path'] }}" data-level="{{ loop.depth }}" data-_type="{{ child['type'] }}" class="cursor-pointer {% if loop.depth != 1 %}hidden{% endif %} relative min-h-20 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-3 flex justify-center items-center h-full transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800">
|
||||
{% if child['content'] %}
|
||||
<span data-value="{{ child['content'] }}" data-{{ current_endpoint }}-content class="hidden"></span>
|
||||
<div data-{{ current_endpoint }}-container class="flex flex-col justify-between :brightness-110 md:min-h-75-screen col-span-12 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">
|
||||
<div class="max-h-[500px]">
|
||||
<div class="w-full grid-cols-12 grid">
|
||||
<div class="col-span-12 md:col-span-8">
|
||||
<h5 class="mb-2 font-bold dark:text-white/90">
|
||||
{% if current_endpoint == "configs" %}
|
||||
SERVICE MANAGER
|
||||
{% else %}
|
||||
FILE
|
||||
MANAGER
|
||||
{% endif %}
|
||||
<div class="w-full items-center grid grid-cols-12 pointer-events-none">
|
||||
<!-- service root-->
|
||||
{% if child['type'] == "folder" and current_endpoint == "configs" and loop.depth == 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||
<path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</h5>
|
||||
<!--breadcrumb -->
|
||||
<ul data-{{ current_endpoint }}-breadcrumb class="flex flex-wrap bg-transparent rounded-lg md:mb-8">
|
||||
<li data-{{ current_endpoint }}-breadcrumb-item data-{{ current_endpoint }}-back class="mr-3 cursor-pointer text-sm capitalize leading-normal dark:text-gray-500 text-gray-600" aria-current="page">
|
||||
<svg class="w-4.5 h-4.5 hover:brigthness-80"
|
||||
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 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3" />
|
||||
</svg>
|
||||
</li>
|
||||
<li data-{{ current_endpoint }}-breadcrumb-item data-level="0" data-path="{% if current_endpoint == "cache" %}/var/cache/bunkerweb{% elif current_endpoint == "configs" %}/etc/bunkerweb/{{ current_endpoint }}{% endif %}" data-name="{{ current_endpoint }}" class="leading-normal text-sm">
|
||||
<button class="dark:text-gray-500 text-gray-600 after:float-right after:pl-2 after:text-gray-600 dark:after:text-gray-500 after:content-['/']">
|
||||
{{ current_endpoint }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end breadcrumb -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- folders-->
|
||||
<div data-{{ current_endpoint }}-folders class="grid grid-cols-12 gap-3">
|
||||
{% for folder in folders %}
|
||||
{% for child in folder['children'] recursive %}
|
||||
{{ loop(child['children']) }}
|
||||
<!-- folder -->
|
||||
<div data-{{ current_endpoint }}-element="{{ child['name'] }}" data-name="{{ child['name'] }}" data-can-create-folder="{{ child['can_create_folders'] }}" data-can-create-file="{{ child['can_create_files'] }}" data-path="{{ child['path'] }}" data-level="{{ loop.depth }}" data-_type="{{ child['type'] }}" class="cursor-pointer {% if loop.depth != 1 %}hidden{% endif %} relative min-h-20 col-span-12 md:col-span-6 2xl:col-span-4 3xl:col-span-3 p-3 flex justify-center items-center h-full transition rounded bg-gray-100 hover:bg-gray-300 dark:bg-slate-700 dark:hover:bg-slate-800">
|
||||
{% if child['content'] %}
|
||||
<span data-value="{{ child['content'] }}" data-{{ current_endpoint }}-content class="hidden"></span>
|
||||
{% endif %}
|
||||
<!-- end service root-->
|
||||
<!-- services folder -->
|
||||
{% if child['type'] == "folder" and current_endpoint == "configs" and loop.depth != 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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>
|
||||
{% endif %}
|
||||
<!-- end services folder-->
|
||||
<!-- services files -->
|
||||
{% if child['type'] == "file" and current_endpoint == "configs" and loop.depth != 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end services files-->
|
||||
<!-- cache folder-->
|
||||
{% if child['type'] == "folder" and current_endpoint == "cache" and loop.depth == 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end cache folder -->
|
||||
<!-- cache file -->
|
||||
{% if child['type'] == "file" and current_endpoint == "cache" %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M15 13.5H9m4.06-7.19l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end cache file -->
|
||||
<span data-{{ current_endpoint }}-element-text class="col-span-10 pointer-events-none transition duration-300 ease-in-out dark:opacity-90 text-center mr-12 mb-0 text-sm xl:text-base text-slate-700 dark:text-gray-300">
|
||||
{{ child['name'] }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<!-- action button -->
|
||||
<div data-{{ current_endpoint }}-action-button="{{ child['name'] }}" class="dark:brightness-125 dark:hover:brightness-100 flex justify-center items-center absolute h-full w-10 bg-primary fill-white first-letter:absolute top-0 -right-1 font-bold text-center text-white uppercase transition-all rounded-none rounded-r-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem bg-150 bg-x-25 active:opacity-85">
|
||||
<svg class="h-8 w-8 fill-white"
|
||||
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="M12 6.75a.75.75 0 110-1.5.75.75 0 010 1.5zM12 12.75a.75.75 0 110-1.5.75.75 0 010 1.5zM12 18.75a.75.75 0 110-1.5.75.75 0 010 1.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end action button -->
|
||||
</div>
|
||||
<!-- dropdown actions -->
|
||||
<div role="tablist" data-{{ current_endpoint }}-action-dropdown="{{ child['name'] }}" class="absolute hidden flex-col z-110 w-48 right-0 top-0 translate-y-16">
|
||||
<!-- view button-->
|
||||
<button role="tab" value="view" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center 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 w-full border-t rounded-t border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-green-700 dark:brightness-125"
|
||||
<div class="w-full items-center grid grid-cols-12 pointer-events-none">
|
||||
<!-- service root-->
|
||||
{% if child['type'] == "folder" and current_endpoint == "configs" and loop.depth == 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z" />
|
||||
<path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end service root-->
|
||||
<!-- services folder -->
|
||||
{% if child['type'] == "folder" and current_endpoint == "configs" and loop.depth != 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<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>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">view</span>
|
||||
{% endif %}
|
||||
<!-- end services folder-->
|
||||
<!-- services files -->
|
||||
{% if child['type'] == "file" and current_endpoint == "configs" and loop.depth != 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end services files-->
|
||||
<!-- cache folder-->
|
||||
{% if child['type'] == "folder" and current_endpoint == "cache" and loop.depth == 1 %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end cache folder -->
|
||||
<!-- cache file -->
|
||||
{% if child['type'] == "file" and current_endpoint == "cache" %}
|
||||
<svg class="col-span-2 h-[2.5rem] w-[2.5rem] fill-primary stroke-gray-100 dark:stroke-gray-600 dark:brightness-150"
|
||||
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="M15 13.5H9m4.06-7.19l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
|
||||
</svg>
|
||||
{% endif %}
|
||||
<!-- end cache file -->
|
||||
<span data-{{ current_endpoint }}-element-text class="col-span-10 pointer-events-none transition duration-300 ease-in-out dark:opacity-90 text-center mr-12 mb-0 text-sm xl:text-base text-slate-700 dark:text-gray-300">
|
||||
{{ child['name'] }}
|
||||
</span>
|
||||
</button>
|
||||
<!-- end view button-->
|
||||
<!-- edit button -->
|
||||
{% if child['type'] == "file" and child['can_edit'] == True or
|
||||
child['type'] == "folder" and child['can_edit'] == True %}
|
||||
<button role="tab" value="edit" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
</div>
|
||||
<div>
|
||||
<!-- action button -->
|
||||
<div data-{{ current_endpoint }}-action-button="{{ child['name'] }}" class="dark:brightness-125 dark:hover:brightness-100 flex justify-center items-center absolute h-full w-10 bg-primary fill-white first-letter:absolute top-0 -right-1 font-bold text-center text-white uppercase transition-all rounded-none rounded-r-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem bg-150 bg-x-25 active:opacity-85">
|
||||
<svg class="h-8 w-8 fill-white"
|
||||
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="M12 6.75a.75.75 0 110-1.5.75.75 0 010 1.5zM12 12.75a.75.75 0 110-1.5.75.75 0 010 1.5zM12 18.75a.75.75 0 110-1.5.75.75 0 010 1.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
<!-- end action button -->
|
||||
</div>
|
||||
<!-- dropdown actions -->
|
||||
<div role="tablist" data-{{ current_endpoint }}-action-dropdown="{{ child['name'] }}" class="absolute hidden flex-col z-110 w-48 right-0 top-0 translate-y-16">
|
||||
<!-- view button-->
|
||||
<button role="tab" value="view" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center 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 w-full border-t rounded-t border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-yellow-500"
|
||||
<svg class="h-5.5 w-5.5 stroke-green-700 dark:brightness-125"
|
||||
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="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">edit</span>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">view</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<!-- end edit button -->
|
||||
<!-- download button -->
|
||||
{% if child['type'] == "file" and child['can_download'] == True %}
|
||||
{% if current_endpoint == "cache" %}
|
||||
<button role="tab" value="download" data-{{ current_endpoint }}-download="{{ child['name'].split("/")[0] }}" data-{{ current_endpoint }}-file="{{ child['name'].split("/")[1] }}" data-{{ current_endpoint }}-setting-select-dropdown-btn="{{ child['name'].split("/")[0] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<!-- end view button-->
|
||||
<!-- edit button -->
|
||||
{% if child['type'] == "file" and child['can_edit'] == True or
|
||||
child['type'] == "folder" and child['can_edit'] == True %}
|
||||
<button role="tab" value="edit" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-sky-500"
|
||||
<svg class="h-5.5 w-5.5 stroke-yellow-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" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
|
||||
</svg>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">download</span>
|
||||
</span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button role="tab" value="download" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-6 w-6 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="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">download</span>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">edit</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<!-- end download button -->
|
||||
<!-- delete button -->
|
||||
{% if child['can_delete'] == True %}
|
||||
<button role="tab" value="delete" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="bg-white duration-300 border-gray-300 hover:brightness-90 text-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-red-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="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
|
||||
</svg>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">delete</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<!-- end delete button -->
|
||||
<!-- end edit button -->
|
||||
<!-- download button -->
|
||||
{% if child['type'] == "file" and child['can_download'] == True %}
|
||||
{% if current_endpoint == "cache" %}
|
||||
<button role="tab" value="download" data-{{ current_endpoint }}-download="{{ child['name'].split("/")[0] }}" data-{{ current_endpoint }}-file="{{ child['name'].split("/")[1] }}" data-{{ current_endpoint }}-setting-select-dropdown-btn="{{ child['name'].split("/")[0] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<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">
|
||||
<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-4 font-bold uppercase">download</span>
|
||||
</span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button role="tab" value="download" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="duration-300 border-gray-300 hover:brightness-90 bg-white text-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-6 w-6 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="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">download</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<!-- end download button -->
|
||||
<!-- delete button -->
|
||||
{% if child['can_delete'] == True %}
|
||||
<button role="tab" value="delete" data-{{ current_endpoint }}-action-dropdown-btn="{{ child['name'] }}" class="bg-white duration-300 border-gray-300 hover:brightness-90 text-white my-0 relative px-6 py-2 text-center 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 w-full border-b border-l border-r hover:bg-gray-100">
|
||||
<span class="flex justify-start items-center">
|
||||
<svg class="h-5.5 w-5.5 stroke-red-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="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
|
||||
</svg>
|
||||
<span class="transition duration-300 ease-in-out text-gray-700 dark:text-gray-300 dark:opacity-80 ml-4 font-bold uppercase">delete</span>
|
||||
</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<!-- end delete button -->
|
||||
</div>
|
||||
<!-- end dropdown actions -->
|
||||
</div>
|
||||
<!-- end dropdown actions -->
|
||||
</div>
|
||||
<!-- end folder-->
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end folders-->
|
||||
<!-- end folder-->
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end folders-->
|
||||
</div>
|
||||
|
||||
{% if current_endpoint == "configs" %}
|
||||
<!-- actions -->
|
||||
<ul data-{{ current_endpoint }}-add-container class="col-span-12 md:col-span-4 mt-4 mb-6 md:mt-0 md:mb-3 w-full flex justify-center items-center">
|
||||
<li class="rounded transition flex-col items-center mx-2 mt-4 relative cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-800">
|
||||
<button disabled class="file-manager-actions-item-btn"
|
||||
data-{{ current_endpoint }}-add-file>
|
||||
<svg class="-translate-x-1 relative dark:brightness-125 h-8 w-8 lg:h-9 lg:w-9 fill-primary stroke-gray-100 dark:stroke-gray-600"
|
||||
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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
||||
</svg>
|
||||
<span class="dark:text-gray-500 pt-1 mb-0 font-sans font-semibold leading-normal uppercase text-sm lg:text-md">
|
||||
ADD FILE
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end actions -->
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- end main container -->
|
||||
<!-- modal -->
|
||||
|
|
|
|||
2
src/ui/templates/jobs.html
vendored
2
src/ui/templates/jobs.html
vendored
|
|
@ -99,7 +99,7 @@
|
|||
<span aria-description="current filter state value"
|
||||
id="jobs-{{ filter['id'] }}"
|
||||
data-name="jobs-{{ filter['id'] }}"
|
||||
data-jobs-setting-select-text="{{ filter['id'] }}">all</span>
|
||||
data-jobs-setting-select-text="{{ filter['id'] }}">{{ filter['value']}}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-jobs-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
|
|
|
|||
2
src/ui/templates/plugins.html
vendored
2
src/ui/templates/plugins.html
vendored
|
|
@ -116,7 +116,7 @@
|
|||
<span aria-description="current filter state value"
|
||||
id="plugins-{{ filter['id'] }}"
|
||||
data-name="plugins-{{ filter['id'] }}"
|
||||
data-plugins-setting-select-text="{{ filter['id'] }}">all</span>
|
||||
data-plugins-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-plugins-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
|
|
|
|||
2
src/ui/templates/reports.html
vendored
2
src/ui/templates/reports.html
vendored
|
|
@ -125,7 +125,7 @@
|
|||
<span aria-description="current filter state value"
|
||||
id="reports-{{ filter['id'] }}"
|
||||
data-name="reports-{{ filter['id'] }}"
|
||||
data-reports-setting-select-text="{{ filter['id'] }}">all</span>
|
||||
data-reports-setting-select-text="{{ filter['id'] }}">{{ filter['value'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-reports-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
|
|
|
|||
2
src/ui/templates/services.html
vendored
2
src/ui/templates/services.html
vendored
|
|
@ -131,7 +131,7 @@
|
|||
<span aria-description="current filter state value"
|
||||
id="services-{{ filter['id'] }}"
|
||||
data-name="services-{{ filter['id'] }}"
|
||||
data-services-setting-select-text="{{ filter['id'] }}">all</span>
|
||||
data-services-setting-select-text="{{ filter['id'] }}">{{ filter['value']}}</span>
|
||||
<!-- chevron -->
|
||||
<svg data-services-setting-select="{{ filter['id'] }}"
|
||||
class="transition-transform h-4 w-4 fill-gray-500"
|
||||
|
|
|
|||
Loading…
Reference in a new issue