mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
update services and simple mode
* refactored services.js to handle simple mode (update hidden input for simple mode form, update form setup logic, update render data logic, ...) * update simple mode template style and add new elements * update input, select and checkbox block to handle simple mode (no global config matching cases, more fallback) + fix some miss * update settings_simple template to fit data send
This commit is contained in:
parent
dce5ec484a
commit
deaf6644bb
9 changed files with 311 additions and 306 deletions
|
|
@ -16,9 +16,6 @@ class ServiceModal {
|
|||
this.modalTabsHeader = this.modal.querySelector([
|
||||
"[data-services-tabs-select-header]",
|
||||
]);
|
||||
this.modalErrMsg = this.modal.querySelector(
|
||||
"[data-services-modal-error-msg]",
|
||||
);
|
||||
this.modalCard = this.modal.querySelector("[data-services-modal-card]");
|
||||
this.switchModeBtn = this.modal.querySelector(
|
||||
"[data-toggle-settings-mode-btn]",
|
||||
|
|
@ -31,6 +28,15 @@ class ServiceModal {
|
|||
this.submitBtn = document.querySelector(
|
||||
"button[data-services-modal-submit]",
|
||||
);
|
||||
// simple el
|
||||
this.simpleForm = this.modal.querySelector("[data-services-simple-modal-form]");
|
||||
this.nextBtn = this.modal.querySelector("button[data-simple-next]");
|
||||
this.backBtn = this.modal.querySelector("button[data-simple-back]");
|
||||
this.saveSimpleBtn = this.modal.querySelector("button[data-services-simple-modal-submit]");
|
||||
// list els
|
||||
this.serverNameInps = this.modal.querySelectorAll('input[name="SERVER_NAME"][data-setting-input]');
|
||||
this.submitBtns = this.modal.querySelectorAll('button[data-services-modal-submit]');
|
||||
|
||||
//container
|
||||
this.container = document.querySelector("main");
|
||||
this.currAction = "";
|
||||
|
|
@ -66,7 +72,17 @@ class ServiceModal {
|
|||
}
|
||||
|
||||
init() {
|
||||
this.disabledSaveCases();
|
||||
// Get list of server name from services card
|
||||
// When the server name input is matching existing server name that is not the current modal one
|
||||
// Disable the submit button
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
this.serverNameInps.forEach((serverNameInput) => {
|
||||
serverNameInput.addEventListener("input", () => {
|
||||
// Case input is empty
|
||||
this.checkServNameInput();
|
||||
});
|
||||
});
|
||||
});
|
||||
this.modal.addEventListener("click", (e) => {
|
||||
// update draft mode
|
||||
try {
|
||||
|
|
@ -77,9 +93,10 @@ class ServiceModal {
|
|||
.classList.contains("hidden")
|
||||
? true
|
||||
: false;
|
||||
|
||||
this.setIsDraft(currModeIsDraft, this.currMethod);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (err) { }
|
||||
|
||||
//close
|
||||
try {
|
||||
|
|
@ -115,6 +132,7 @@ class ServiceModal {
|
|||
.closest("[data-services-service]")
|
||||
.querySelector("[data-old-service-name]")
|
||||
.getAttribute("data-value");
|
||||
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
|
|
@ -130,10 +148,8 @@ class ServiceModal {
|
|||
.querySelector("[data-services-settings]")
|
||||
.getAttribute("data-value");
|
||||
const obj = JSON.parse(servicesSettings);
|
||||
this.updateModalData(obj);
|
||||
this.updateModalData(obj, false, false, false);
|
||||
//show modal
|
||||
this.resetFilterInp();
|
||||
this.changeSubmitBtn("SAVE", "valid-btn");
|
||||
this.openModal();
|
||||
}
|
||||
} catch (err) {}
|
||||
|
|
@ -163,17 +179,7 @@ class ServiceModal {
|
|||
.querySelector("[data-services-settings]")
|
||||
.getAttribute("data-value");
|
||||
const obj = JSON.parse(servicesSettings);
|
||||
this.updateModalData(obj, true, true);
|
||||
// server name is unset
|
||||
const inpServName = document.querySelector("input#SERVER_NAME");
|
||||
inpServName.getAttribute("value", "");
|
||||
inpServName.removeAttribute("disabled", "");
|
||||
inpServName.value = "";
|
||||
// clone is UI creation, so no setting should be disabled
|
||||
|
||||
//show modal
|
||||
this.resetFilterInp();
|
||||
this.changeSubmitBtn("CREATE", "valid-btn");
|
||||
this.updateModalData(obj, true, true, true, true);
|
||||
this.openModal(); //server name is unset
|
||||
}
|
||||
} catch (err) {}
|
||||
|
|
@ -196,16 +202,7 @@ class ServiceModal {
|
|||
method,
|
||||
);
|
||||
//set default value with method default
|
||||
this.setSettingsDefault();
|
||||
//server name is unset
|
||||
const inpServName = document.querySelector("input#SERVER_NAME");
|
||||
inpServName.getAttribute("value", "");
|
||||
inpServName.removeAttribute("disabled", "");
|
||||
inpServName.value = "";
|
||||
|
||||
//show modal
|
||||
this.resetFilterInp();
|
||||
this.changeSubmitBtn("CREATE", "valid-btn");
|
||||
this.updateModalData({}, true, true, true, true);
|
||||
this.openModal();
|
||||
}
|
||||
} catch (err) {}
|
||||
|
|
@ -234,21 +231,57 @@ class ServiceModal {
|
|||
});
|
||||
}
|
||||
|
||||
resetSimpleForm() {
|
||||
// reset button
|
||||
this.backBtn.setAttribute("disabled", "");
|
||||
this.nextBtn.removeAttribute("disabled");
|
||||
|
||||
// set current security level to input
|
||||
}
|
||||
|
||||
resetFilterInp() {
|
||||
const inpFilter = document.querySelector('input[name="settings-filter"]');
|
||||
inpFilter.value = "";
|
||||
inpFilter.dispatchEvent(new Event("input"));
|
||||
}
|
||||
|
||||
changeSubmitBtn(text, btnType) {
|
||||
this.submitBtn.textContent = text;
|
||||
this.submitBtn.classList.remove(
|
||||
"delete-btn",
|
||||
"valid-btn",
|
||||
"edit-btn",
|
||||
"info-btn",
|
||||
);
|
||||
this.submitBtn.classList.add(btnType);
|
||||
changeSubmitBtn(action) {
|
||||
if(action === "delete") return;
|
||||
const text = action === "edit" ? "SAVE" : "CREATE";
|
||||
|
||||
this.submitBtns.forEach((btn) => {
|
||||
btn.textContent = text;
|
||||
btn.classList.remove(
|
||||
"delete-btn",
|
||||
"valid-btn",
|
||||
"edit-btn",
|
||||
"info-btn",
|
||||
);
|
||||
btn.classList.add("valid-btn");
|
||||
});
|
||||
}
|
||||
|
||||
resetServerName() {
|
||||
this.serverNameInps.forEach((inpServName) => {
|
||||
inpServName.getAttribute("value", "");
|
||||
inpServName.removeAttribute("disabled", "");
|
||||
inpServName.value = "";
|
||||
});
|
||||
}
|
||||
|
||||
isAvoidInpList(inp, inpName) {
|
||||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "mode" ||
|
||||
inpName === "security-level" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter" ||
|
||||
inp.hasAttribute("data-combobox")
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
setSettingsDefault() {
|
||||
|
|
@ -256,15 +289,8 @@ class ServiceModal {
|
|||
inps.forEach((inp) => {
|
||||
//form related values are excludes
|
||||
const inpName = inp.getAttribute("name");
|
||||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter" ||
|
||||
inp.hasAttribute("data-combobox")
|
||||
)
|
||||
return;
|
||||
|
||||
if (this.isAvoidInpList(inp, inpName)) return;
|
||||
|
||||
//for all other settings values
|
||||
const defaultMethod = inp.getAttribute("data-default-method");
|
||||
|
|
@ -334,17 +360,18 @@ class ServiceModal {
|
|||
setIsDraft(isDraft, method) {
|
||||
const draftVal = isDraft ? "yes" : "no";
|
||||
|
||||
document.querySelectorAll('input[name="is_draft"]').forEach((inp) => {
|
||||
const draftInps = this.modal.querySelectorAll('input[name="is_draft"]');
|
||||
|
||||
draftInps.forEach((inp) => {
|
||||
inp.setAttribute("value", draftVal);
|
||||
inp.value = draftVal;
|
||||
});
|
||||
|
||||
//Update draft button
|
||||
const btn = document.querySelector("button[data-toggle-draft-btn]");
|
||||
const btn = this.modal.querySelector("button[data-toggle-draft-btn]");
|
||||
|
||||
if (
|
||||
(!["ui", "default"].includes(method) && this.currAction !== "clone") ||
|
||||
this.currAction === "delete"
|
||||
(!["ui", "default"].includes(method) && this.currAction !== "clone")
|
||||
) {
|
||||
return btn.classList.add("hidden");
|
||||
}
|
||||
|
|
@ -362,63 +389,48 @@ class ServiceModal {
|
|||
|
||||
setForm(action, serviceName, oldServName, formEl, isDraft, method) {
|
||||
this.currAction = action;
|
||||
this.setIsDraft(isDraft === "yes" ? true : false, method);
|
||||
|
||||
this.modalTitle.textContent = `${action} ${serviceName}`;
|
||||
|
||||
const operation = action === "clone" ? "new" : action;
|
||||
|
||||
// update operation and other hidden inputs for all mode in modal
|
||||
const operationInps = this.modal.querySelectorAll('input[name="operation"]');
|
||||
operationInps.forEach((inp) => {
|
||||
inp.setAttribute("value", operation);
|
||||
inp.value = operation;
|
||||
});
|
||||
|
||||
// show / hide components
|
||||
this.hideForms();
|
||||
this.setCardViewportHeight(action === "delete" ? false : true);
|
||||
this.SetSelectTabsVisible(action === "delete" ? false : true);
|
||||
this.setHeaderActionsVisible(action === "delete" ? false : true);
|
||||
this.changeSubmitBtn(action);
|
||||
|
||||
formEl.setAttribute("id", `form-${operation}-${serviceName}`);
|
||||
const opeInp = formEl.querySelector(`input[name="operation"]`);
|
||||
opeInp.setAttribute("value", operation);
|
||||
opeInp.value = operation;
|
||||
if (action === "edit" || action === "new" || action === "clone") {
|
||||
this.formNewEdit.classList.remove("hidden");
|
||||
this.simpleForm.classList.remove("hidden");
|
||||
|
||||
if (action === "edit" || action === "new") {
|
||||
this.showNewEditForm();
|
||||
const oldNameInp = formEl.querySelector(`input[name="OLD_SERVER_NAME"]`);
|
||||
oldNameInp.setAttribute("value", oldServName);
|
||||
oldNameInp.value = oldServName;
|
||||
}
|
||||
const oldNameValue = action === "edit" ? oldServName : "";
|
||||
|
||||
const oldNameInps = this.modal.querySelectorAll('input[name="OLD_SERVER_NAME"]');
|
||||
oldNameInps.forEach((inp) => {
|
||||
inp.setAttribute("value", oldNameValue);
|
||||
inp.value = oldNameValue;
|
||||
});
|
||||
|
||||
if (action === "clone") {
|
||||
this.showNewEditForm();
|
||||
const oldNameInp = formEl.querySelector(`input[name="OLD_SERVER_NAME"]`);
|
||||
oldNameInp.setAttribute("value", "");
|
||||
oldNameInp.value = "";
|
||||
}
|
||||
|
||||
if (action === "delete") {
|
||||
this.showDeleteForm();
|
||||
this.formDelete.classList.remove("hidden");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Get list of server name from services card
|
||||
// When the server name input is matching existing server name that is not the current modal one
|
||||
// Disable the submit button
|
||||
disabledSaveCases() {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const serverNameInput = document.querySelector(
|
||||
'input[name="SERVER_NAME"]',
|
||||
);
|
||||
this.setIsDraft(isDraft === "yes" ? true : false, method);
|
||||
|
||||
window.addEventListener("click", (e) => {
|
||||
if (e.target.hasAttribute("data-services-action")) {
|
||||
// focus on input server name
|
||||
serverNameInput.focus();
|
||||
this.checkServNameInput();
|
||||
}
|
||||
});
|
||||
|
||||
serverNameInput.addEventListener("input", () => {
|
||||
// Case input is empty
|
||||
this.checkServNameInput();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Switch settings mode and update button
|
||||
|
|
@ -450,86 +462,94 @@ class ServiceModal {
|
|||
}
|
||||
|
||||
checkServNameInput() {
|
||||
const serverNameInput = document.querySelector('input[name="SERVER_NAME"]');
|
||||
|
||||
if (serverNameInput.value === "") {
|
||||
this.modalErrMsg.textContent = "Server name cannot be empty";
|
||||
this.modalErrMsg.classList.remove("hidden");
|
||||
return this.submitBtn.setAttribute("disabled", "");
|
||||
}
|
||||
|
||||
// Case conflict with another server name
|
||||
const serverNames = document.querySelectorAll("[data-services-service]");
|
||||
const serverNameValue = serverNameInput.getAttribute("value");
|
||||
|
||||
// Case inp name is current server name
|
||||
if (serverNameInput.value === serverNameValue) {
|
||||
return this.submitBtn.removeAttribute("disabled");
|
||||
}
|
||||
// case inp name is not current server name, check if it is same as another
|
||||
for (let i = 0; i < serverNames.length; i++) {
|
||||
const name = serverNames[i].getAttribute("data-services-service");
|
||||
if (name === serverNameValue) continue;
|
||||
|
||||
if (name === serverNameInput.value) {
|
||||
this.modalErrMsg.textContent = "Server name already exists";
|
||||
this.modalErrMsg.classList.remove("hidden");
|
||||
return this.submitBtn.setAttribute("disabled", "");
|
||||
this.serverNameInps.forEach((serverNameInput) => {
|
||||
const modalErrMsg = serverNameInput.closest("form").querySelector("[data-services-modal-error-msg]");
|
||||
if (serverNameInput.value === "") {
|
||||
modalErrMsg.textContent = "Server name cannot be empty";
|
||||
modalErrMsg.classList.remove("hidden");
|
||||
return serverNameInput.closest("form").querySelector('button[data-services-modal-submit]').setAttribute("disabled", "");
|
||||
}
|
||||
|
||||
// Case conflict with another server name
|
||||
const serverNames = document.querySelectorAll("[data-services-service]");
|
||||
const serverNameValue = serverNameInput.getAttribute("value");
|
||||
|
||||
// case inp name is not current server name, check if it is same as another
|
||||
for (let i = 0; i < serverNames.length; i++) {
|
||||
const name = serverNames[i].getAttribute("data-services-service");
|
||||
if (name === serverNameValue) continue;
|
||||
|
||||
if (name === serverNameInput.value) {
|
||||
modalErrMsg.textContent = "Server name already exists";
|
||||
modalErrMsg.classList.remove("hidden");
|
||||
return serverNameInput.closest("form").querySelector('button[data-services-modal-submit]').setAttribute("disabled", "");
|
||||
}
|
||||
}
|
||||
|
||||
modalErrMsg.classList.add("hidden");
|
||||
return serverNameInput.closest("form").querySelector('button[data-services-modal-submit]').removeAttribute("disabled");
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
setHeaderActionsVisible(setVisible) {
|
||||
if (setVisible) {
|
||||
this.modal.querySelector('[data-toggle-draft-btn]').classList.remove("hidden");
|
||||
this.modal.querySelector('[data-toggle-settings-mode-btn]').classList.remove("hidden");
|
||||
}
|
||||
|
||||
this.modalErrMsg.textContent = "";
|
||||
this.modalErrMsg.classList.add("hidden");
|
||||
return this.submitBtn.removeAttribute("disabled");
|
||||
if (!setVisible) {
|
||||
this.modal.querySelector('[data-toggle-draft-btn]').classList.add("hidden");
|
||||
this.modal.querySelector('[data-toggle-settings-mode-btn]').classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
showNewEditForm() {
|
||||
this.cardViewport();
|
||||
this.showSelectTabs();
|
||||
this.hideForms();
|
||||
this.formNewEdit.classList.remove("hidden");
|
||||
}
|
||||
setCardViewportHeight(setAsViewport) {
|
||||
|
||||
showDeleteForm() {
|
||||
this.cardNoViewport();
|
||||
this.hideSelectTabs();
|
||||
this.hideForms();
|
||||
if(setAsViewport) {
|
||||
this.modalCard.classList.add("h-[90vh]");
|
||||
this.modalCard.classList.add("w-full");
|
||||
}
|
||||
|
||||
this.formDelete.classList.remove("hidden");
|
||||
}
|
||||
|
||||
cardViewport() {
|
||||
this.modalCard.classList.add("h-[90vh]");
|
||||
this.modalCard.classList.add("w-full");
|
||||
}
|
||||
|
||||
cardNoViewport() {
|
||||
this.modalCard.classList.remove("h-[90vh]");
|
||||
this.modalCard.classList.remove("w-full");
|
||||
if(!setAsViewport) {
|
||||
this.modalCard.classList.remove("h-[90vh]");
|
||||
this.modalCard.classList.remove("w-full");
|
||||
}
|
||||
}
|
||||
|
||||
hideForms() {
|
||||
this.formNewEdit.classList.add("hidden");
|
||||
this.simpleForm.classList.add("hidden");
|
||||
this.formDelete.classList.add("hidden");
|
||||
}
|
||||
|
||||
hideSelectTabs() {
|
||||
this.modalTabs.classList.remove("grid");
|
||||
this.modalTabs.classList.add("hidden");
|
||||
SetSelectTabsVisible(setVisible) {
|
||||
if (setVisible) {
|
||||
this.modalTabs.classList.add("grid");
|
||||
this.modalTabs.classList.remove("hidden");
|
||||
this.modalTabsHeader.classList.add("flex");
|
||||
this.modalTabsHeader.classList.remove("hidden");
|
||||
}
|
||||
|
||||
this.modalTabsHeader.classList.remove("flex");
|
||||
this.modalTabsHeader.classList.add("hidden");
|
||||
if (!setVisible) {
|
||||
this.modalTabs.classList.remove("grid");
|
||||
this.modalTabs.classList.add("hidden");
|
||||
|
||||
this.modalTabsHeader.classList.remove("flex");
|
||||
this.modalTabsHeader.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
showSelectTabs() {
|
||||
this.modalTabs.classList.add("grid");
|
||||
this.modalTabs.classList.remove("hidden");
|
||||
this.modalTabsHeader.classList.add("flex");
|
||||
this.modalTabsHeader.classList.remove("hidden");
|
||||
}
|
||||
|
||||
updateModalData(settings, forceEnabled = false, setMethodUI = false) {
|
||||
//use this to select inputEl and change value
|
||||
updateModalData(settings = {}, forceEnabled = false, setMethodUI = false, emptyServerName = false) {
|
||||
|
||||
// check if at least one key in settings
|
||||
if (Object.keys(settings).length === 0) {
|
||||
this.setSettingsDefault();
|
||||
}
|
||||
|
||||
if (Object.keys(settings).length > 0) {
|
||||
//use this to select inputEl and change value
|
||||
for (const [key, data] of Object.entries(settings)) {
|
||||
//change format to match id
|
||||
const value = data["value"];
|
||||
|
|
@ -541,14 +561,7 @@ class ServiceModal {
|
|||
inps.forEach((inp) => {
|
||||
//form related values are excludes
|
||||
const inpName = inp.getAttribute("name");
|
||||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter"
|
||||
)
|
||||
return;
|
||||
if (this.isAvoidInpList(inp, inpName)) return;
|
||||
|
||||
//SET DISABLED / ENABLED
|
||||
//for regular input
|
||||
|
|
@ -598,6 +611,12 @@ class ServiceModal {
|
|||
});
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.resetFilterInp();
|
||||
if(emptyServerName) this.resetServerName();
|
||||
this.checkServNameInput();
|
||||
}
|
||||
|
||||
setDisabledState(inp, method, global) {
|
||||
|
|
@ -1069,7 +1088,9 @@ class Multiple {
|
|||
if (
|
||||
inpName === "csrf_token" ||
|
||||
inpName === "OLD_SERVER_NAME" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "is_draft" ||
|
||||
inpName === "mode" ||
|
||||
inpName === "security-level" ||
|
||||
inpName === "operation" ||
|
||||
inpName === "settings-filter"
|
||||
)
|
||||
|
|
@ -1096,7 +1117,7 @@ class Multiple {
|
|||
inp.checked = true;
|
||||
}
|
||||
|
||||
if (inp.getAttribute("type") !== "checkbox") {
|
||||
if (inp.getAttribute("type") !== "checkbox" ) {
|
||||
inp.setAttribute("value", value);
|
||||
inp.value = value;
|
||||
inp.setAttribute("data-method", method);
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@
|
|||
<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="mode" name="advanced" />
|
||||
|
||||
{% include "settings_plugins.html" %}
|
||||
<!-- action button -->
|
||||
<div class="w-full flex-col items-center justify-center flex mt-10">
|
||||
|
|
|
|||
|
|
@ -1,9 +1,21 @@
|
|||
{% set steps = [
|
||||
{
|
||||
"name" : "STEP 1 - SERVER NAME",
|
||||
"description" : "We need this to...",
|
||||
"name" : "STEP 1 - STARTING UP",
|
||||
"description" : "we need some information to get started.",
|
||||
"settings" : [
|
||||
{"plugin_id" : "general", "setting_id": "SERVER_NAME", "label" : "What is your host ?", "levels" : {"standard" : "", "advanced" : "", "high" : ""} },
|
||||
{"plugin_id" : "general", "setting_id": "SERVER_NAME", "title" : "DEFINE HOST", "subtitle" : "We need this to connect BunkerWeb to your application. You need to set your domain name.", "levels" : False },
|
||||
{"plugin_id" : "security-level", "setting_id": "SECURITY_LEVEL", "title" : "DEFINE SECURITY LEVEL", "subtitle" : "This will determine default settings value for the next steps. You'll be allow to modify settings to match your case if needed.", "levels" : False, "setting" : {'context': 'global', 'default': 'standard', 'help': 'Determine the default settings value. You can override them.', 'id': 'security-level', 'label': 'Security level', 'regex': '^(standard|advanced|bunker)$', 'type': 'select', 'select': ['standard', 'advanced', 'bunker']} }
|
||||
],
|
||||
"configs": [
|
||||
{"name": "my_config_1", "type": "modsec", "data": "..."},
|
||||
{"name": "my_config_2", "type": "server-http", "data": "..."}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "STEP 2 - ANTIBOT",
|
||||
"description" : "Avoid spammer and bot to access your website.",
|
||||
"settings" : [
|
||||
{"plugin_id" : "antibot", "setting_id": "USE_ANTIBOT", "title" : "Define the type of your antibot", "subtitle" : "Javascript, Captcha or Cookie don't need additionnal settings to be fill. Recaptcha, Hcaptcha and Turnstile need secret key and site key delivered from providers.", "levels" : {"standard" : "no", "advanced" : "no", "high" : "no"} },
|
||||
],
|
||||
"configs": [
|
||||
{"name": "my_config_1", "type": "modsec", "data": "..."},
|
||||
|
|
@ -31,22 +43,24 @@
|
|||
id="form-simple-new"
|
||||
method="POST">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<input type="hidden" id="simple_operation" value="new" name="simple_operation" />
|
||||
<input type="hidden" value="" name="simple_OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="simple_is_draft" />
|
||||
<input type="hidden" value="yes" name="simple_is_simple_mode" />
|
||||
<input type="hidden" value="new" name="operation" />
|
||||
<input type="hidden" value="" name="OLD_SERVER_NAME" />
|
||||
<input type="hidden" value="no" name="is_draft" />
|
||||
<input type="hidden" value="mode" name="easy" />
|
||||
|
||||
{% for step in steps %}
|
||||
<div data-step="{{loop.index}}" class="flex flex-col">
|
||||
<div data-step="{{loop.index}}" class="flex flex-col {% if loop.index != 1 %} hidden {% endif %}">
|
||||
<div class="flex flex-col w-full items-start mt-2">
|
||||
<h2 class="ml-2 mr-1 text-xl transition duration-300 ease-in-out font-bold text-md uppercase dark:text-white/90 mb-0" data-simple-step>{{ step.get("name")}}</h2>
|
||||
<p class="ml-2 mr-1 text-sm dark:text-gray-300 mb-1" data-simple-description>{{ step.get("description")}}</p>
|
||||
<p class="ml-2 mr-1 text-base dark:text-gray-300 mb-1" data-simple-description>{{ step.get("description")}}</p>
|
||||
</div>
|
||||
<div class="w-full min-w-[300px] my-1 sm:my-0">
|
||||
<hr class="separator" />
|
||||
</div>
|
||||
{% set plugin_simple = step.get('settings') %}
|
||||
{% include "settings_simple.html" %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- action button -->
|
||||
|
|
@ -55,10 +69,15 @@
|
|||
<button data-services-simple-modal-close
|
||||
type="button"
|
||||
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
|
||||
<button data-services-simple-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
|
||||
<button data-simple-back
|
||||
type="button"
|
||||
disabled
|
||||
class="dark:bg-slate-800 info-btn mb-4 mr-3 text-base">Back</button>
|
||||
<button data-simple-next type="button" class="mb-4 valid-btn">Continue</button>
|
||||
<button data-services-modal-submit type="submit" class="hidden mb-4 valid-btn">Save</button>
|
||||
</div>
|
||||
<!-- end action button-->
|
||||
<p data-services-simple-modal-error-msg
|
||||
<p data-services-modal-error-msg
|
||||
class="hidden text-red-500 font-bold dark:opacity-80 mb-0 text-center"></p>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
17
src/ui/templates/setting_checkbox.html
vendored
17
src/ui/templates/setting_checkbox.html
vendored
|
|
@ -1,23 +1,28 @@
|
|||
{% if setting_input["type"] == "check" %}
|
||||
{% if setting_input and setting_input["type"] == "check" %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_id = setting_input['id'] %}
|
||||
{% set inp_regex = setting_input['regex'] %}
|
||||
{% set inp_default = setting_input['default'] %}
|
||||
{% set inp_value = setting_input['value'] %}
|
||||
{% 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') %}
|
||||
|
||||
<div data-checkbox-handler="{{ inp_id }}"
|
||||
class="relative mb-7 md:mb-0 z-10 ">
|
||||
<label class="sr-only" for="{{ inp_name_mult }}">{{ inp_name }}</label>
|
||||
<input id="{{ inp_name_mult }}"
|
||||
name="{{ inp_name_mult }}"
|
||||
data-default-method="{% if inp_name in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] %}mode{% else %}{{ global_config[setting]['method'] }}{% endif %}"
|
||||
data-default-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[inp_name]['method'] != 'ui' and global_config[inp_name]['method'] != 'default' %} disabled {% endif %}
|
||||
data-checked="{% if global_config[inp_name]['value'] == "yes" %}true{% else %}false{% endif %}"
|
||||
{% if inp_name in ['AUTOCONF_MODE', 'SWARM_MODE', 'KUBERNETES_MODE'] or global_config_method != 'ui' and global_config_method != 'default' %} disabled {% endif %}
|
||||
data-checked="{% if global_config_value == "yes" %}true{% else %}false{% endif %}"
|
||||
checked
|
||||
id="checkbox-{{ inp_id }}"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
data-pattern="{{ setting_input['regex']|safe }}"
|
||||
value="{{ global_config[inp_name]['value'] }}" />
|
||||
data-pattern="{{ inp_regex|safe }}"
|
||||
value="{{ global_config_value }}" />
|
||||
<svg data-checkbox-handler="{{ inp_id }}"
|
||||
class="pointer-events-none absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
|||
1
src/ui/templates/setting_header.html
vendored
1
src/ui/templates/setting_header.html
vendored
|
|
@ -2,7 +2,6 @@
|
|||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_name_multisite = inp_name + "-multisite_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
|
||||
{% set inp_label = setting_input['label'] %}
|
||||
{% set inp_help = setting_input['help'] %}
|
||||
{% set inp_context = setting_input['context'] %}
|
||||
|
|
|
|||
18
src/ui/templates/setting_input.html
vendored
18
src/ui/templates/setting_input.html
vendored
|
|
@ -1,23 +1,27 @@
|
|||
|
||||
{% if value["type"] != "select" and value["type"] != "check" %}
|
||||
{% if setting_input and setting_input["type"] != "select" and setting_input["type"] != "check" %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_type = setting_input['type'] %}
|
||||
{% set inp_default = setting_input['default'] %}
|
||||
|
||||
{% set inp_value = setting_input['value'] %}
|
||||
{% set inp_regex = setting_input['regex'] %}
|
||||
{% 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') %}
|
||||
|
||||
<div class="relative flex items-center">
|
||||
<label class="sr-only" for="{{ inp_name_mult }}">{{ inp_name }}</label>
|
||||
<input {% if inp_name == "SERVER_NAME" %}required{% endif %}
|
||||
data-default-value="{{ global_config[inp_name]['value'] }}"
|
||||
data-default-method="{{ global_config[inp_name]['method'] }}"
|
||||
data-default-value="{{ global_config_value }}"
|
||||
data-default-method="{{ global_config_method }}"
|
||||
data-setting-input
|
||||
{% if global_config[inp_name]['method'] != 'ui' and global_config[inp_name]['method'] != 'default' %}disabled{% endif %}
|
||||
{% if global_config_method != 'ui' and global_config_method != 'default' %}disabled{% endif %}
|
||||
id="{{ inp_name_mult }}"
|
||||
name="{{ inp_name_mult }}"
|
||||
class="regular-input"
|
||||
value="{% if global_config[inp_name]['value'] %} {{ global_config[inp_name]['value'] }} {% else %} {{ inp_default }} {% endif %}"
|
||||
value="{% if global_config_value %} {{ global_config_value }} {% else %} {{ inp_default }} {% endif %}"
|
||||
type="{{ inp_type }}"
|
||||
pattern="{{ value['regex']|safe }}" />
|
||||
pattern="{{ inp_regex|safe }}" />
|
||||
{% if inp_type == "password" %}
|
||||
<div data-setting-password-container class="absolute flex right-2 h-5 w-5">
|
||||
<button type="button"
|
||||
|
|
|
|||
33
src/ui/templates/setting_select.html
vendored
33
src/ui/templates/setting_select.html
vendored
|
|
@ -1,12 +1,17 @@
|
|||
{% if value["type"] == "select" %}
|
||||
{% if setting_input and setting_input["type"] == "select" %}
|
||||
{% set inp_name = setting_input['name'] %}
|
||||
{% set inp_name_mult = inp_name + "_SCHEMA" if setting_input["is_multiple"] else inp_name %}
|
||||
{% set inp_default = setting_input['default'] %}
|
||||
{% set inp_value = setting_input['value'] %}
|
||||
{% set inp_method = setting_input['method'] %}
|
||||
{% set inp_items = setting_input['select'] %}
|
||||
{% set inp_id = setting_input['id'] %}
|
||||
|
||||
{% set inp_is_simple = setting_input['is_simple'] %}
|
||||
{% 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') %}
|
||||
|
||||
<!-- default hidden-->
|
||||
<select data-default-method="{{ global_config[inp_name]['method'] }}"
|
||||
<select data-default-method="{{ global_config_method }}"
|
||||
data-default-value="{{ inp_default }}"
|
||||
id="{{ inp_name_mult }}"
|
||||
name="{{ inp_name_mult }}"
|
||||
|
|
@ -16,7 +21,7 @@
|
|||
{% for item in inp_items %}
|
||||
<option {% if not item %}label="empty"{% endif %}
|
||||
value="{{ item }}"
|
||||
{% if global_config[inp_name]['value'] and global_config[inp_name]['value'] == item or not global_config[inp_name]['value'] and inp_default == item %} selected{% endif %}>
|
||||
{% if global_config_value and global_config_value == item or not global_config_value and inp_default == item %} selected{% endif %}>
|
||||
{{ item }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
|
|
@ -24,19 +29,19 @@
|
|||
<!-- end default hidden-->
|
||||
<!--custom-->
|
||||
<div data-select-container class="relative">
|
||||
<button {% if global_config[inp_name]['method'] != 'ui' and global_config[inp_name]['method'] != 'default' %}disabled{% endif %}
|
||||
<button {% if global_config_method != 'ui' and global_config_method != 'default' %}disabled{% endif %}
|
||||
data-setting-select="{{ inp_id }}"
|
||||
data-default-value="{{ global_config[inp_name]['value'] }}"
|
||||
data-default-method="{{ global_config[inp_name]['method'] }}"
|
||||
aria-controls="{{ value['id'] }}-dropdown"
|
||||
data-default-value="{{ global_config_value }}"
|
||||
data-default-method="{{ global_config_method }}"
|
||||
aria-controls="{{ inp_id }}-dropdown"
|
||||
type="button"
|
||||
class="custom-select-btn">
|
||||
{% for item in inp_items %}
|
||||
{% if global_config[inp_name]['value'] and
|
||||
global_config[inp_name]['value'] == item %}
|
||||
{% if global_config_value and
|
||||
global_config_value == item %}
|
||||
<span data-setting-select-text="{{ inp_id }}"
|
||||
data-value="{{ global_config[inp_name]['value'] }}">{{ global_config[inp_name]['value'] }}</span>
|
||||
{% elif not global_config[inp_name]['value'] and inp_default == item %}
|
||||
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>
|
||||
|
|
@ -57,8 +62,8 @@
|
|||
data-setting-select-dropdown="{{ inp_id }}"
|
||||
class="hidden z-[20] fixed h-full flex-col mt-2 max-h-[200px] overflow-auto">
|
||||
{% for item in inp_items %}
|
||||
{% if global_config[inp_name]['value'] and
|
||||
global_config[inp_name]['value'] == item or not global_config[setting_input['name']]['value']
|
||||
{% if global_config_value and
|
||||
global_config_value == item or not global_config_value
|
||||
and inp_default == item %}
|
||||
<button role="option"
|
||||
value="{{ item }}"
|
||||
|
|
|
|||
4
src/ui/templates/settings_plugins.html
vendored
4
src/ui/templates/settings_plugins.html
vendored
|
|
@ -52,7 +52,7 @@
|
|||
<div data-plugin-settings class="w-full grid grid-cols-12">
|
||||
<!-- plugin settings not multiple -->
|
||||
{% for setting, value in plugin["settings"].items() %}
|
||||
{% set setting_input = { "name" : setting, "context" : value.get("context"), "help" : value.get("help"), "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : False} %}
|
||||
{% set setting_input = { "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} %}
|
||||
|
||||
{% 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 %}
|
||||
|
|
@ -96,7 +96,7 @@
|
|||
<!-- multiple settings -->
|
||||
<div data-{{ current_endpoint }}-settings-multiple="{{ multiple }}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full my-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting, value in plugin["settings"].items() %}
|
||||
{% set setting_input = { "name" : setting, "context" : value.get("context"), "help" : value.get("help"), "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : False} %}
|
||||
{% set setting_input = { "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} %}
|
||||
|
||||
{# render only setting that match the multiple id and context #}
|
||||
{% if value['multiple'] == multiple and (
|
||||
|
|
|
|||
150
src/ui/templates/settings_simple.html
vendored
150
src/ui/templates/settings_simple.html
vendored
|
|
@ -1,127 +1,77 @@
|
|||
{% set current_endpoint = current_endpoint or url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-') %}
|
||||
<!-- plugin item -->
|
||||
|
||||
{% for plugin in plugin_simple %}
|
||||
<div data-simple id="{{ plugin['plugin_id'] }}-simple"
|
||||
class="w-full px-1">
|
||||
{% for setting_simple in plugin_simple %}
|
||||
{% set setting_input = { "name" : setting_simple.get('setting_id'), "method" : setting_simple.get('setting').get("method", "default"), "help" : setting_simple.get('setting').get("help"), "label" : setting_simple.get('setting').get("label"), "id" : setting_simple.get('setting').get("id"), "type" : setting_simple.get('setting').get("type"), "default" : setting_simple.get('setting').get("default", "default"), "select" : setting_simple.get('setting').get("select"), "regex" : setting_simple.get('setting').get("regex"), "value" : setting_simple.get('setting').get("value"), "is_multiple" : True if setting_simple.get('setting').get("type") == "multiple" else False } %}
|
||||
<div data-simple id="{{ setting_simple['plugin_id'] }}-simple"
|
||||
class="w-full px-1 mb-2">
|
||||
<!-- title and desc -->
|
||||
<div class="col-span-12" data-setting-header>
|
||||
<div class="flex justify-start items-center">
|
||||
<h5 class="my-2 transition duration-300 ease-in-out ml-2 mr-1 font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ plugin['label'] }}
|
||||
<div class="flex flex-col justify-start items-start">
|
||||
<h5 class="ml-2 mr-1 mt-2 transition duration-300 ease-in-out font-bold text-base uppercase dark:text-white/90 mb-0">
|
||||
{{ setting_simple['title'] }}
|
||||
</h5>
|
||||
<p class="ml-2 mr-1 text-sm dark:text-gray-300 mb-0">{{ setting_simple['subtitle'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{# get number of multiple groups for the plugin #}
|
||||
{% set multList = [] %}
|
||||
{% if not setting_input.get('is_multiple') %}
|
||||
<!-- end title and desc -->
|
||||
<div class="w-full grid grid-cols-12">
|
||||
<!-- plugin settings not multiple -->
|
||||
{% for setting, value in plugin["setting"].items() %}
|
||||
{% set setting_input = { "name" : setting, "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : True} %}
|
||||
|
||||
{% if value['multiple'] and value['multiple'] not in multList %}
|
||||
{% if multList.append(value['multiple']) %}{% endif %}
|
||||
{% endif %}
|
||||
{% if not value['multiple'] %}
|
||||
<div data-setting-container data-{{ current_endpoint }}-type="{{ plugin['type'] }}" data-{{ current_endpoint }}-context="{{ value['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ value["id"] }}">
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ value["label"] }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}">
|
||||
<p class="popover-settings-text">{{ value['help'] }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
</div>
|
||||
<!-- end title and info -->
|
||||
{% include "setting_input.html"%}
|
||||
{% include "setting_select.html"%}
|
||||
{% include "setting_checkbox.html"%}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div data-setting-container data--simple-{{ current_endpoint }}-type="{{ setting_input['type'] }}" data--simple-{{ current_endpoint }}-context="{{ setting_input['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit--simple-{{ current_endpoint }}-{{ setting_input["id"] }}">
|
||||
{% include "setting_header.html" %}
|
||||
{% include "setting_input.html" %}
|
||||
{% include "setting_select.html" %}
|
||||
{% include "setting_checkbox.html" %}
|
||||
{% include "setting_invalid.html"%}
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end plugin settings not multiple -->
|
||||
{% if multList|length > 0 %}
|
||||
{% endif %}
|
||||
|
||||
{% if setting_input.get('is_multiple') %}
|
||||
<h5 data-multiple-title
|
||||
class="transition duration-300 ease-in-out ml-2 font-bold text-[1.1rem] uppercase dark:text-white/90 mt-2 mb-0">
|
||||
multiple settings
|
||||
</h5>
|
||||
{% endif %}
|
||||
{% for multiple in multList %}
|
||||
<!-- plugin multiple handler -->
|
||||
<div data-multiple-handler="{{ multiple }}"
|
||||
class="flex items-center mx-2 mb-2 mt-5 col-span-12 ">
|
||||
<h5 class="input-title max-w-[150px] sm:max-w-[350px]">{{ multiple.replace('-', ' ').replace('_', ' ')|upper }}</h5>
|
||||
<button data-{{ current_endpoint }}-multiple-add="{{ multiple }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Add
|
||||
</button>
|
||||
<button data-{{ current_endpoint }}-multiple-toggle="{{ multiple }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
SHOW / HIDE
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin multiple handler-->
|
||||
<!-- multiple settings -->
|
||||
<div data-{{ current_endpoint }}-settings-multiple="{{ multiple }}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full my-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting, value in plugin["setting"].items() %}
|
||||
{% set setting_input = { "name" : setting, "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default"), "select" : value.get("select"), "regex" : value.get("regex"), "is_multiple" : True} %}
|
||||
|
||||
{# render only setting that match the multiple id and context #}
|
||||
{% if value['multiple'] == multiple and (
|
||||
current_endpoint == "global-config"
|
||||
or current_endpoint == "services" and value['context'] == "multisite"
|
||||
) %}
|
||||
<div data-setting-container="{{ setting }}_SCHEMA" data-{{ current_endpoint }}-type="{{ plugin['type'] }}" data-{{ current_endpoint }}-context="{{ value['context'] }}" class="relative mx-2 md:mx-3 my-2 md:my-3 col-span-12 md:col-span-6 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ value["id"] }}_SCHEMA">
|
||||
{% for multiple in multiple_settings %}
|
||||
<!-- plugin multiple handler -->
|
||||
<div data-multiple-handler="{{ multiple }}"
|
||||
class="flex items-center mx-2 mb-2 mt-5 col-span-12 ">
|
||||
<h5 class="input-title max-w-[150px] sm:max-w-[350px]">{{ multiple.replace('-', ' ').replace('_', ' ')|upper }}</h5>
|
||||
<button data--simple-{{ current_endpoint }}-multiple-add="{{ multiple }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Add
|
||||
</button>
|
||||
<button data--simple-{{ current_endpoint }}-multiple-toggle="{{ multiple }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-sky-500 hover:bg-sky-500/80 focus:bg-sky-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
SHOW / HIDE
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin multiple handler-->
|
||||
<!-- multiple settings -->
|
||||
<div data--simple-{{ current_endpoint }}-settings-multiple="{{ multiple }}_SCHEMA" class="bg-gray-50 dark:bg-slate-900/30 hidden w-full my-4 grid-cols-12 border dark:border-gray-700 rounded">
|
||||
{% for setting, value in plugin["settings"].items() %}
|
||||
{% set setting_input = { "name" : setting, "context" : value.get("context"), "help" : value.get("help"), "label" : value.get("label"), "id" : value.get("id"), "type" : value.get("type"), "default" : value.get("default", "default"), "select" : value.get("select"), "regex" : value.get("regex"), "value" : value.get("value"), "is_multiple" : True} %}
|
||||
<div data-setting-container="{{ setting }}_SCHEMA" data--simple-{{ current_endpoint }}-type="{{ plugin['type'] }}" data--simple-{{ 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--simple-{{ current_endpoint }}-{{ value["id"] }}_SCHEMA">
|
||||
<!-- title and info -->
|
||||
<div class="flex items-center my-1 relative z-10">
|
||||
<h5 class="input-title">{{ value["label"] }}</h5>
|
||||
<!-- popover -->
|
||||
<button type="button" data-popover-btn="{{ setting }}_SCHEMA">
|
||||
<svg class="popover-settings-svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div role="alert"
|
||||
aria-description="show detail"
|
||||
class="popover-settings-container hidden"
|
||||
data-popover-content="{{ setting }}_SCHEMA">
|
||||
<p class="popover-settings-text">{{ value['help'] }}</p>
|
||||
</div>
|
||||
<!-- end popover -->
|
||||
</div>
|
||||
|
||||
{% include "setting_input.html"%}
|
||||
{% include "setting_select.html"%}
|
||||
{% include "setting_checkbox.html"%}
|
||||
{% include "setting_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>
|
||||
{% endfor %}
|
||||
<div data-multiple-delete-container
|
||||
class="col-span-12 flex justify-center my-4">
|
||||
<button data--simple-{{ current_endpoint }}-multiple-delete="{{ plugin['name'] }}" type="button" class="ml-3 dark:brightness-90 inline-block px-3 py-1.5 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-red-500 hover:bg-red-500/80 focus:bg-red-500/80 leading-normal text-md ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
<!-- end plugin settings -->
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end multiple settings -->
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<!-- end plugin item -->
|
||||
|
|
|
|||
Loading…
Reference in a new issue