mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
multiple advance mode now working
This commit is contained in:
parent
f5a8eadf3e
commit
cc9fd039ad
3 changed files with 225 additions and 355 deletions
|
|
@ -937,6 +937,8 @@ def services():
|
|||
|
||||
error = 0
|
||||
|
||||
print(variables, flush=True)
|
||||
|
||||
# Reload instances
|
||||
manage_bunkerweb(
|
||||
"services",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ import {
|
|||
} from "./utils/settings.js";
|
||||
|
||||
class Settings {
|
||||
constructor(formEl, mode = "advanced") {
|
||||
constructor(formEl, mode = "advanced", prefix = "services") {
|
||||
this.prefix = prefix;
|
||||
this.mode = mode;
|
||||
this.multSettingsName = JSON.parse(
|
||||
document
|
||||
|
|
@ -21,15 +22,12 @@ class Settings {
|
|||
this.switchModeBtn =
|
||||
document.querySelector("[data-toggle-settings-mode-btn]") || null;
|
||||
|
||||
this.submitBtn = this.formEl.querySelector(
|
||||
"button[data-services-modal-submit]",
|
||||
this.submitBtn = this.container.querySelector(
|
||||
`button[data-${this.prefix}-modal-submit]`,
|
||||
);
|
||||
|
||||
this.darkMode = document.querySelector("[data-dark-toggle]");
|
||||
this.isDarkMode = this.darkMode.checked;
|
||||
// simple el
|
||||
this.nextBtn = null;
|
||||
this.backBtn = null;
|
||||
|
||||
if (this.mode === "simple") {
|
||||
this.nextBtn = this.container.querySelector("button[data-simple-next]");
|
||||
|
|
@ -39,13 +37,9 @@ class Settings {
|
|||
this.serverNameInps = this.container.querySelectorAll(
|
||||
'input[name="SERVER_NAME"][data-setting-input]',
|
||||
);
|
||||
this.submitBtns = this.container.querySelectorAll(
|
||||
"button[data-services-modal-submit]",
|
||||
);
|
||||
// add editor for configs in simple mode
|
||||
this.simpleEditorEls = [];
|
||||
this.initSimpleEditors();
|
||||
|
||||
// add editor for configs in simple mode
|
||||
this.editorEls = [];
|
||||
this.currAction = "";
|
||||
this.currMethod = "";
|
||||
this.oldServName = "";
|
||||
|
|
@ -56,15 +50,14 @@ class Settings {
|
|||
init() {
|
||||
window.addEventListener("load", () => {
|
||||
this.hiddenIfNoMultiples();
|
||||
this.initEditors();
|
||||
});
|
||||
// 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.formNewEdit, this.simpleForm].forEach((form) => {
|
||||
form.addEventListener("input", (e) => {
|
||||
this.checkVisibleInpsValidity();
|
||||
});
|
||||
this.container.addEventListener("input", (e) => {
|
||||
this.checkVisibleInpsValidity();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -73,99 +66,35 @@ class Settings {
|
|||
this.updateEditorMode();
|
||||
});
|
||||
|
||||
this.container.addEventListener("click", (e) => {
|
||||
//edit action
|
||||
// MODAL ACTIONS
|
||||
window.addEventListener("click", (e) => {
|
||||
//edit / clone action
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"edit" ||
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"clone" ||
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"edit"
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-action`) === "edit" ||
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-action`) === "clone"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target,
|
||||
);
|
||||
|
||||
//get service data and parse it
|
||||
//multiple type logic is launch at same time on relate class
|
||||
const settings = this.getSettingsNoMultiple(e.target);
|
||||
this.updateModalData(settings, false, false, false);
|
||||
//show modal
|
||||
this.openModal();
|
||||
this.updateData(e.target, false, false, false);
|
||||
}
|
||||
} catch (err) {}
|
||||
// clone action
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"clone"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target,
|
||||
);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
serviceName,
|
||||
this.formNewEdit,
|
||||
isDraft,
|
||||
method,
|
||||
);
|
||||
//set default value with method default
|
||||
//get service data and parse it
|
||||
// multiple type logic is launch at same time on relate class
|
||||
const settings = this.getSettingsNoMultiple(e.target);
|
||||
}
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
//new action
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"new"
|
||||
e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-action`) === "new"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target,
|
||||
);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
serviceName,
|
||||
this.formNewEdit,
|
||||
isDraft,
|
||||
method,
|
||||
);
|
||||
|
||||
//set default value with method default
|
||||
this.updateModalData({}, true, true, true, true);
|
||||
this.updateData(e.target, true, true, true, true);
|
||||
}
|
||||
} catch (err) {}
|
||||
//delete action
|
||||
try {
|
||||
if (
|
||||
e.target.closest("button").getAttribute("data-services-action") ===
|
||||
"delete"
|
||||
) {
|
||||
//set form info and right form
|
||||
const [action, serviceName, isDraft, method] = this.getActionData(
|
||||
e.target,
|
||||
);
|
||||
this.setForm(
|
||||
action,
|
||||
serviceName,
|
||||
serviceName,
|
||||
this.formDelete,
|
||||
isDraft,
|
||||
method,
|
||||
);
|
||||
//show modal
|
||||
this.openModal();
|
||||
}
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
// security
|
||||
try {
|
||||
if (
|
||||
|
|
@ -174,11 +103,12 @@ class Settings {
|
|||
.getAttribute("data-setting-select-dropdown-btn") ==
|
||||
"security-level"
|
||||
) {
|
||||
this.updateSecuLevel();
|
||||
this.updateData(e.target, true, true, true, false);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
|
||||
// SIMPLE MODE ACTIONS
|
||||
if (this.mode === "simple") {
|
||||
this.nextBtn.addEventListener("click", () => {
|
||||
this.nextSimpleStep();
|
||||
|
|
@ -196,6 +126,139 @@ class Settings {
|
|||
}, 20);
|
||||
});
|
||||
}
|
||||
|
||||
// MULTIPLE ACTIONS
|
||||
this.container.addEventListener("click", (e) => {
|
||||
// Add btn
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-multiple-add`)
|
||||
) {
|
||||
//get plugin from btn
|
||||
const btn = e.target.closest("button");
|
||||
const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`);
|
||||
//get all multiple groups
|
||||
const multipleEls = this.container.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple*="${attName}"]`,
|
||||
);
|
||||
//case no schema
|
||||
if (multipleEls.length <= 0) return;
|
||||
|
||||
//get the next container number logic
|
||||
//default is 0
|
||||
let topNum = 0;
|
||||
//loop on curr multiples, get the name suffix for each
|
||||
//and keep the highest num
|
||||
multipleEls.forEach((container) => {
|
||||
const ctnrName = container.getAttribute(
|
||||
`data-${this.prefix}-settings-multiple`,
|
||||
);
|
||||
const num = this.getSuffixNumOrFalse(ctnrName);
|
||||
if (!isNaN(num) && num > topNum) topNum = num;
|
||||
});
|
||||
//the final number is num
|
||||
//num is total - 1 because of hidden SCHEMA container
|
||||
const currNum = `${multipleEls.length >= 2 ? topNum + 1 : topNum}`;
|
||||
const setNum = +currNum === 0 ? `` : `_${currNum}`;
|
||||
//the default (schema) group is the last group
|
||||
const schema = this.container.querySelector(
|
||||
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`,
|
||||
);
|
||||
//clone schema to create a group with new num
|
||||
const schemaClone = schema.cloneNode(true);
|
||||
|
||||
//add special attribute for disabled logic
|
||||
this.changeCloneSuffix(schemaClone, setNum);
|
||||
//set disabled / enabled state
|
||||
this.setDisabledMultNew(schemaClone);
|
||||
this.showClone(schema, schemaClone);
|
||||
//insert new group before first one
|
||||
//show all groups
|
||||
this.showMultByAtt(attName);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
//TOGGLE BTN
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-multiple-toggle`)
|
||||
) {
|
||||
const att = e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-multiple-toggle`);
|
||||
this.toggleMultByAtt(att);
|
||||
}
|
||||
//remove last child
|
||||
} catch (err) {}
|
||||
|
||||
//REMOVE BTN
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-multiple-delete`)
|
||||
) {
|
||||
// We are not removing it really, just hiding it and update values to default
|
||||
// By setting default value, group will be send to server and delete (because a setting with default value is useless to keep)
|
||||
const multContainer = e.target.closest(
|
||||
`[data-${this.prefix}-settings-multiple]`,
|
||||
);
|
||||
multContainer.classList.add("hidden-multiple");
|
||||
// get setting container
|
||||
const settings = multContainer.querySelectorAll(
|
||||
`[data-setting-container]`,
|
||||
);
|
||||
settings.forEach((setting) => {
|
||||
// for regular input
|
||||
try {
|
||||
const inps = setting.querySelectorAll("input");
|
||||
inps.forEach((inp) => {
|
||||
// case checkbox
|
||||
if (inp.getAttribute("type") === "checkbox") {
|
||||
const defaultVal = inp.getAttribute("data-default") || "";
|
||||
|
||||
if (defaultVal === "yes" && !inp.checked) {
|
||||
inp.click();
|
||||
}
|
||||
}
|
||||
|
||||
// case regular
|
||||
if (inp.getAttribute("type") !== "checkbox") {
|
||||
const defaultVal = inp.getAttribute("data-default") || "";
|
||||
inp.setAttribute("value", defaultVal);
|
||||
inp.value = defaultVal;
|
||||
}
|
||||
});
|
||||
} catch (e) {}
|
||||
// for select
|
||||
try {
|
||||
const selects = setting.querySelectorAll(
|
||||
"button[data-setting-select]",
|
||||
);
|
||||
selects.forEach((select) => {
|
||||
const defaultVal = select.getAttribute("data-default") || "";
|
||||
select
|
||||
.querySelector("data-setting-select-text")
|
||||
.setAttribute("data-value", defaultVal);
|
||||
select.querySelector("data-setting-select-text").textContent =
|
||||
defaultVal;
|
||||
const dropdown = this.container.querySelector(
|
||||
`[data-setting-select-dropdown="${select.getAttribute(
|
||||
"data-setting-select",
|
||||
)}"]`,
|
||||
);
|
||||
dropdown.querySelector(`button[value=${defaultVal}]`).click();
|
||||
});
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
//remove last child
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
resetSimpleMode() {
|
||||
|
|
@ -210,15 +273,11 @@ class Settings {
|
|||
const firstStep = this.simpleForm.querySelector("[data-step='1']");
|
||||
firstStep.classList.remove("hidden");
|
||||
this.updateSimpleActions();
|
||||
// we want to update settings by current security level
|
||||
this.updateSecuLevel();
|
||||
}
|
||||
|
||||
initSimpleEditors() {
|
||||
const simpleEditors = this.container.querySelectorAll(
|
||||
"[data-simple-editor]",
|
||||
);
|
||||
simpleEditors.forEach((editorEl) => {
|
||||
initEditors() {
|
||||
const editors = this.container.querySelectorAll("[data-editor]");
|
||||
editors.forEach((editorEl) => {
|
||||
const editor = ace.edit(editorEl.getAttribute("id"));
|
||||
// Handle
|
||||
if (this.isDarkMode) {
|
||||
|
|
@ -228,14 +287,12 @@ class Settings {
|
|||
}
|
||||
//editor options
|
||||
editor.setShowPrintMargin(false);
|
||||
this.simpleEditorEls.push(editor);
|
||||
this.editorEls.push(editor);
|
||||
});
|
||||
|
||||
this.updateSecuLevelEditorContent();
|
||||
}
|
||||
|
||||
updateEditorMode() {
|
||||
this.simpleEditorEls.forEach((editor) => {
|
||||
this.editorEls.forEach((editor) => {
|
||||
if (this.isDarkMode) {
|
||||
editor.setTheme("ace/theme/dracula");
|
||||
} else {
|
||||
|
|
@ -244,54 +301,12 @@ class Settings {
|
|||
});
|
||||
}
|
||||
|
||||
updateSecuLevelEditorContent() {
|
||||
const secuLevelValue = this.simpleForm
|
||||
.querySelector('[data-setting-select-text="security-level"]')
|
||||
.textContent.toLowerCase()
|
||||
.trim();
|
||||
|
||||
this.simpleEditorEls.forEach((editorEl) => {
|
||||
const editorContent = this.container
|
||||
.querySelector(
|
||||
`textarea#${editorEl.container
|
||||
.getAttribute("id")
|
||||
.replace(
|
||||
"-editor",
|
||||
"-content",
|
||||
)}[data-simple-default-editor-content]`,
|
||||
)
|
||||
.getAttribute(`data-content-${secuLevelValue}`);
|
||||
editorEl.setValue(editorContent);
|
||||
});
|
||||
}
|
||||
|
||||
updateSecuLevel() {
|
||||
// Add timeout to let dropdown update attribute values
|
||||
// This avoid using previous value
|
||||
setTimeout(() => {
|
||||
const secuLevelValue = this.simpleForm
|
||||
.querySelector('[data-setting-select-text="security-level"]')
|
||||
.textContent.toLowerCase()
|
||||
.trim();
|
||||
|
||||
// Update settings by security level
|
||||
this.setSettingsByAtt(
|
||||
this.simpleForm,
|
||||
"data-default-method",
|
||||
`data-security-level-${secuLevelValue}`,
|
||||
);
|
||||
|
||||
// Update configs
|
||||
this.updateSecuLevelEditorContent();
|
||||
}, 30);
|
||||
}
|
||||
|
||||
nextSimpleStep() {
|
||||
// get current step
|
||||
const currStep = this.simpleForm.querySelector("[data-step]:not(.hidden)");
|
||||
const currStep = this.container.querySelector("[data-step]:not(.hidden)");
|
||||
const currStepNum = currStep.getAttribute("data-step");
|
||||
// get next step and next step + 1 to determine if continue or save
|
||||
const nextStep = this.simpleForm.querySelector(
|
||||
const nextStep = this.container.querySelector(
|
||||
`[data-step="${+currStepNum + 1}"]`,
|
||||
);
|
||||
// hide current step and show next one
|
||||
|
|
@ -304,10 +319,10 @@ class Settings {
|
|||
|
||||
prevSimpleStep() {
|
||||
// get current step
|
||||
const currStep = this.simpleForm.querySelector("[data-step]:not(.hidden)");
|
||||
const currStep = this.container.querySelector("[data-step]:not(.hidden)");
|
||||
const currStepNum = currStep.getAttribute("data-step");
|
||||
// get next step and next step + 1 to determine if continue or save
|
||||
const prevStep = this.simpleForm.querySelector(
|
||||
const prevStep = this.container.querySelector(
|
||||
`[data-step="${+currStepNum - 1}"]`,
|
||||
);
|
||||
|
||||
|
|
@ -320,14 +335,14 @@ class Settings {
|
|||
}
|
||||
|
||||
updateSimpleActions() {
|
||||
const currStep = this.simpleForm.querySelector("[data-step]:not(.hidden)");
|
||||
const currStep = this.container.querySelector("[data-step]:not(.hidden)");
|
||||
const currStepNum = currStep.getAttribute("data-step");
|
||||
// get next step and next step + 1 to determine if continue or save
|
||||
const prevStep = this.simpleForm.querySelector(
|
||||
const prevStep = this.container.querySelector(
|
||||
`[data-step="${+currStepNum - 1}"]`,
|
||||
);
|
||||
|
||||
const nextStep = this.simpleForm.querySelector(
|
||||
const nextStep = this.container.querySelector(
|
||||
`[data-step="${+currStepNum + 1}"]`,
|
||||
);
|
||||
|
||||
|
|
@ -381,7 +396,7 @@ class Settings {
|
|||
inpName === "operation" ||
|
||||
inpName === "settings-filter" ||
|
||||
inp.hasAttribute("data-combobox") ||
|
||||
(containerEl === this.simpleForm && inpName === "SERVER_NAME")
|
||||
(this.mode === "simple" && inpName === "SERVER_NAME")
|
||||
)
|
||||
return true;
|
||||
}
|
||||
|
|
@ -396,7 +411,7 @@ class Settings {
|
|||
inpName === "operation" ||
|
||||
inpName === "settings-filter" ||
|
||||
inp.hasAttribute("data-combobox") ||
|
||||
(containerEl === this.simpleForm && inpName === "SECURITY_LEVEL")
|
||||
(this.mode === "simple" && inpName === "SECURITY_LEVEL")
|
||||
)
|
||||
return true;
|
||||
}
|
||||
|
|
@ -516,7 +531,7 @@ class Settings {
|
|||
});
|
||||
}
|
||||
|
||||
updateOperation() {
|
||||
updateOperation(operation) {
|
||||
// update operation and other hidden inputs for all mode in modal
|
||||
const operationInps = this.container.querySelectorAll(
|
||||
'input[name="operation"]',
|
||||
|
|
@ -567,13 +582,17 @@ class Settings {
|
|||
// Get global needed data
|
||||
this.currAction = target
|
||||
.closest("button")
|
||||
.getAttribute("data-services-action");
|
||||
this.oldServName = target
|
||||
.closest("[data-services-service]")
|
||||
.querySelector("[data-old-service-name]")
|
||||
.getAttribute("data-value");
|
||||
.getAttribute(`data-${this.prefix}-action`);
|
||||
|
||||
this.oldServName = "";
|
||||
if (this.currAction !== "new")
|
||||
this.oldServName = target
|
||||
.closest(`[data-${this.prefix}-service]`)
|
||||
.querySelector("[data-old-name]")
|
||||
.getAttribute("data-value");
|
||||
|
||||
// Update metadata, hidden inputs and visual content
|
||||
const operation = this.currAction === "clone" ? "new" : this.currAction;
|
||||
this.updateOperation(this.currAction === "clone" ? "new" : this.currAction);
|
||||
this.updateOldNameValue();
|
||||
this.changeSubmitBtn();
|
||||
|
|
@ -586,11 +605,12 @@ class Settings {
|
|||
.closest("[data-settings]")
|
||||
.getAttribute("data-settings");
|
||||
const settings = JSON.parse(targetSettings);
|
||||
console.log(settings);
|
||||
this.setRegularInps(settings, forceEnabled, setMethodUI, emptyServerName);
|
||||
this.setMultipleInps(settings, forceEnabled, setMethodUI, emptyServerName);
|
||||
this.setMultipleInps(settings);
|
||||
|
||||
// Reset simple mode, we want to override default value by default security level
|
||||
this.resetSimpleMode();
|
||||
if (this.mode === "simple") this.resetSimpleMode();
|
||||
|
||||
// Global reset
|
||||
this.resetFilterInp();
|
||||
|
|
@ -686,16 +706,11 @@ class Settings {
|
|||
this.removePrevMultiples();
|
||||
//keep only multiple settings value
|
||||
const multipleSettings = this.getMultiplesOnly(settings);
|
||||
|
||||
const sortMultiples =
|
||||
this.sortMultipleByContainerAndSuffixe(multipleSettings);
|
||||
|
||||
// Need to set method as ui if clone
|
||||
const isClone =
|
||||
e.target.closest("button").getAttribute(`data-${this.prefix}-action`) ===
|
||||
"clone"
|
||||
? true
|
||||
: false;
|
||||
const isClone = this.currAction === "clone" ? true : false;
|
||||
this.setMultipleToDOM(sortMultiples, isClone);
|
||||
// Show at least one mult group
|
||||
this.addOneMultGroup();
|
||||
|
|
@ -705,7 +720,7 @@ class Settings {
|
|||
//get schema settings
|
||||
const multiples = {};
|
||||
|
||||
const schemaSettings = this.formContainer.querySelectorAll(
|
||||
const schemaSettings = this.container.querySelectorAll(
|
||||
`[data-setting-container$="SCHEMA"]`,
|
||||
);
|
||||
|
||||
|
|
@ -731,13 +746,14 @@ class Settings {
|
|||
}
|
||||
|
||||
addOneMultGroup() {
|
||||
const multAddBtns = this.formContainer.querySelectorAll(
|
||||
const multAddBtns = this.container.querySelectorAll(
|
||||
`[data-${this.prefix}-multiple-add]`,
|
||||
);
|
||||
console.log("mult groups, ", multAddBtns);
|
||||
multAddBtns.forEach((btn) => {
|
||||
const att = btn.getAttribute(`data-${this.prefix}-multiple-add`);
|
||||
//check if already one (SCHEMA exclude so length >= 2)
|
||||
const multGroups = this.formContainer.querySelectorAll(
|
||||
const multGroups = this.container.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple^="${att}"]`,
|
||||
);
|
||||
if (multGroups.length >= 2) return;
|
||||
|
|
@ -848,7 +864,7 @@ class Settings {
|
|||
const nameSuffixLess = isSuffixe
|
||||
? name.replace(`_${splitName[splitName.length - 1]}`, "").trim()
|
||||
: name.trim();
|
||||
const relateSetting = this.formContainer.querySelector(
|
||||
const relateSetting = this.container.querySelector(
|
||||
`[data-setting-container=${nameSuffixLess}_SCHEMA]`,
|
||||
);
|
||||
if (!relateSetting) continue;
|
||||
|
|
@ -872,7 +888,7 @@ class Settings {
|
|||
}
|
||||
|
||||
//put multiple on the right plugin, on schema container
|
||||
setMultipleToDOM(sortMultObj, setMethodUI = false) {
|
||||
setMultipleToDOM(sortMultObj) {
|
||||
//we loop on each multiple that contains values to render to DOM
|
||||
for (const [schemaCtnrName, multGroupBySuffix] of Object.entries(
|
||||
sortMultObj,
|
||||
|
|
@ -1024,167 +1040,9 @@ class Settings {
|
|||
.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class MultipleActions {
|
||||
constructor(prefix, formContainerSelector) {
|
||||
this.prefix = prefix;
|
||||
this.form = document.querySelector(formContainerSelector);
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.form.addEventListener("click", (e) => {
|
||||
// Add btn
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-multiple-add`)
|
||||
) {
|
||||
//get plugin from btn
|
||||
const btn = e.target.closest("button");
|
||||
const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`);
|
||||
//get all multiple groups
|
||||
const multipleEls = this.form.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple*="${attName}"]`,
|
||||
);
|
||||
//case no schema
|
||||
if (multipleEls.length <= 0) return;
|
||||
|
||||
//get the next container number logic
|
||||
//default is 0
|
||||
let topNum = 0;
|
||||
//loop on curr multiples, get the name suffix for each
|
||||
//and keep the highest num
|
||||
multipleEls.forEach((container) => {
|
||||
const ctnrName = container.getAttribute(
|
||||
`data-${this.prefix}-settings-multiple`,
|
||||
);
|
||||
const num = this.getSuffixNumOrFalse(ctnrName);
|
||||
if (!isNaN(num) && num > topNum) topNum = num;
|
||||
});
|
||||
//the final number is num
|
||||
//num is total - 1 because of hidden SCHEMA container
|
||||
const currNum = `${multipleEls.length >= 2 ? topNum + 1 : topNum}`;
|
||||
const setNum = +currNum === 0 ? `` : `_${currNum}`;
|
||||
//the default (schema) group is the last group
|
||||
const schema = this.form.querySelector(
|
||||
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`,
|
||||
);
|
||||
//clone schema to create a group with new num
|
||||
const schemaClone = schema.cloneNode(true);
|
||||
|
||||
//add special attribute for disabled logic
|
||||
this.changeCloneSuffix(schemaClone, setNum);
|
||||
//set disabled / enabled state
|
||||
this.setDisabledMultNew(schemaClone);
|
||||
this.showClone(schema, schemaClone);
|
||||
//insert new group before first one
|
||||
//show all groups
|
||||
this.showMultByAtt(attName);
|
||||
}
|
||||
} catch (err) {}
|
||||
|
||||
//TOGGLE BTN
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-multiple-toggle`)
|
||||
) {
|
||||
const att = e.target
|
||||
.closest("button")
|
||||
.getAttribute(`data-${this.prefix}-multiple-toggle`);
|
||||
this.toggleMultByAtt(att);
|
||||
}
|
||||
//remove last child
|
||||
} catch (err) {}
|
||||
|
||||
//REMOVE BTN
|
||||
try {
|
||||
if (
|
||||
e.target
|
||||
.closest("button")
|
||||
.hasAttribute(`data-${this.prefix}-multiple-delete`)
|
||||
) {
|
||||
// We are not removing it really, just hiding it and update values to default
|
||||
// By setting default value, group will be send to server and delete (because a setting with default value is useless to keep)
|
||||
const multContainer = e.target.closest(
|
||||
`[data-${this.prefix}-settings-multiple]`,
|
||||
);
|
||||
multContainer.classList.add("hidden-multiple");
|
||||
// get setting container
|
||||
const settings = multContainer.querySelectorAll(
|
||||
`[data-setting-container]`,
|
||||
);
|
||||
settings.forEach((setting) => {
|
||||
// for regular input
|
||||
try {
|
||||
const inps = setting.querySelectorAll("input");
|
||||
inps.forEach((inp) => {
|
||||
// case checkbox
|
||||
if (inp.getAttribute("type") === "checkbox") {
|
||||
const defaultVal = inp.getAttribute("data-default") || "";
|
||||
|
||||
if (defaultVal === "yes" && !inp.checked) {
|
||||
inp.click();
|
||||
}
|
||||
}
|
||||
|
||||
// case regular
|
||||
if (inp.getAttribute("type") !== "checkbox") {
|
||||
const defaultVal = inp.getAttribute("data-default") || "";
|
||||
inp.setAttribute("value", defaultVal);
|
||||
inp.value = defaultVal;
|
||||
}
|
||||
});
|
||||
} catch (e) {}
|
||||
// for select
|
||||
try {
|
||||
const selects = setting.querySelectorAll(
|
||||
"button[data-setting-select]",
|
||||
);
|
||||
selects.forEach((select) => {
|
||||
const defaultVal = select.getAttribute("data-default") || "";
|
||||
select
|
||||
.querySelector("data-setting-select-text")
|
||||
.setAttribute("data-value", defaultVal);
|
||||
select.querySelector("data-setting-select-text").textContent =
|
||||
defaultVal;
|
||||
const dropdown = this.form.querySelector(
|
||||
`[data-setting-select-dropdown="${select.getAttribute(
|
||||
"data-setting-select",
|
||||
)}"]`,
|
||||
);
|
||||
dropdown.querySelector(`button[value=${defaultVal}]`).click();
|
||||
});
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
//remove last child
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
changeCloneSuffix(schemaCtnrClone, suffix) {
|
||||
//rename multiple container
|
||||
schemaCtnrClone.setAttribute(
|
||||
`data-${this.prefix}-settings-multiple`,
|
||||
schemaCtnrClone
|
||||
.getAttribute(`data-${this.prefix}-settings-multiple`)
|
||||
.replace("_SCHEMA", suffix),
|
||||
);
|
||||
}
|
||||
|
||||
showClone(schemaCtnr, schemaCtnrClone) {
|
||||
schemaCtnr.insertAdjacentElement("afterend", schemaCtnrClone);
|
||||
schemaCtnrClone.classList.remove("hidden");
|
||||
schemaCtnrClone.classList.add("grid");
|
||||
}
|
||||
|
||||
showMultByAtt(att) {
|
||||
const multContainers = this.form.querySelectorAll(
|
||||
const multContainers = this.container.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple^=${att}]`,
|
||||
);
|
||||
multContainers.forEach((container) => {
|
||||
|
|
@ -1198,7 +1056,7 @@ class MultipleActions {
|
|||
}
|
||||
|
||||
toggleMultByAtt(att) {
|
||||
const multContainers = this.form.querySelectorAll(
|
||||
const multContainers = this.container.querySelectorAll(
|
||||
`[data-${this.prefix}-settings-multiple^=${att}]`,
|
||||
);
|
||||
multContainers.forEach((container) => {
|
||||
|
|
@ -1236,7 +1094,7 @@ class MultipleActions {
|
|||
const name = select.getAttribute(
|
||||
`data-${this.prefix}-setting-select-default`,
|
||||
);
|
||||
const selDOM = this.form.querySelector(
|
||||
const selDOM = this.container.querySelector(
|
||||
`button[data-${this.prefix}-setting-select='${name}']`,
|
||||
);
|
||||
if (method === "ui" || method === "default") {
|
||||
|
|
@ -1324,7 +1182,9 @@ class ServiceModal {
|
|||
//set form info and right form
|
||||
this.setFormModal(e.target);
|
||||
}
|
||||
} catch (err) { console.log(err);}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1350,12 +1210,13 @@ class ServiceModal {
|
|||
.querySelector("[data-service-method]")
|
||||
.getAttribute("data-value") || "no";
|
||||
|
||||
let oldServName = '';
|
||||
let oldServName = "";
|
||||
|
||||
if(action !== "new") target
|
||||
.closest("[data-services-service]")
|
||||
.querySelector("[data-old-service-name]")
|
||||
.getAttribute("data-value") || '';
|
||||
if (action !== "new")
|
||||
target
|
||||
.closest("[data-services-service]")
|
||||
.querySelector("[data-old-name]")
|
||||
.getAttribute("data-value") || "";
|
||||
this.currMethod = method;
|
||||
|
||||
return [action, serviceName, oldServName, isDraft, method];
|
||||
|
|
@ -1392,7 +1253,9 @@ class ServiceModal {
|
|||
this.formDelete.classList.remove("hidden");
|
||||
this.formDelete.querySelector(`[data-services-modal-text]`).textContent =
|
||||
`Are you sure you want to delete ${serviceName} ?`;
|
||||
const nameInp = this.formDelete.querySelector(`input[name="SERVER_NAME"]`);
|
||||
const nameInp = this.formDelete.querySelector(
|
||||
`input[name="SERVER_NAME"]`,
|
||||
);
|
||||
nameInp.setAttribute("value", serviceName);
|
||||
nameInp.value = serviceName;
|
||||
}
|
||||
|
|
@ -1840,8 +1703,10 @@ const setFilterGlobal = new FilterSettings(
|
|||
"services",
|
||||
);
|
||||
|
||||
|
||||
// const settings = new Settings(document.querySelector("[data-advanced][data-services-modal-form]"), "advanced");
|
||||
const settings = new Settings(
|
||||
document.querySelector("[data-advanced][data-services-modal-form]"),
|
||||
"advanced",
|
||||
);
|
||||
// const setAdvancedMultiple = new MultipleActions("services", document.querySelector("[data-advanced][data-services-modal-form]"));
|
||||
|
||||
const checkServiceModalKeyword = new CheckNoMatchFilter(
|
||||
|
|
|
|||
9
src/ui/templates/services.html
vendored
9
src/ui/templates/services.html
vendored
|
|
@ -25,7 +25,7 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
<input class="hidden" data-plugins-multiple='{{multiple_settings}}'' />
|
||||
<input class="hidden" data-plugins-multiple='{{multiple_settings}}' />
|
||||
<!-- actions -->
|
||||
<div data-{{attribute_name}}-service
|
||||
class="col-span-12 relative flex justify-center min-w-0 break-words rounded-2xl bg-clip-border">
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
<div data-service-method class="hidden" data-value="ui"></div>
|
||||
<button data-{{attribute_name}}-action="new"
|
||||
data-{{attribute_name}}-name="service"
|
||||
data-settings="{}"
|
||||
type="button"
|
||||
class="dark:bg-green-500/90 duration-300 dark:text-gray-100 w-80 flex justify-center items-center px-6 py-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer bg-green-500 hover:bg-green-500/80 focus:bg-green-500/80 leading-normal text-base ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 hover:-translate-y-px active:opacity-85 hover:shadow-md">
|
||||
<span class="mr-2">new service</span>
|
||||
|
|
@ -103,9 +104,11 @@
|
|||
{% for service in services %}
|
||||
{% set id_server_name = service["SERVER_NAME"]['value'].replace(".", "-") %}
|
||||
<div data-{{attribute_name}}-card
|
||||
data-settings="{{ service['settings'] }}"
|
||||
|
||||
data-{{attribute_name}}-service="{{ service['SERVER_NAME']['value'] }}"
|
||||
class="dark:brightness-110 overflow-hidden hover:scale-102 transition col-span-12 lg:col-span-6 3xl:col-span-4 p-4 w-full shadow-md break-words bg-white dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border">
|
||||
<div data-old-service-name
|
||||
<div data-old-name
|
||||
class="hidden"
|
||||
data-value="{{ service['SERVER_NAME']['full_value'] }}"></div>
|
||||
<div data-is-draft
|
||||
|
|
@ -278,7 +281,7 @@
|
|||
data-settings="{{ service['settings'] }}"
|
||||
{% endif %}
|
||||
{% if button['name'] == "new"%}
|
||||
data-settings="{}""
|
||||
data-settings="{}"
|
||||
{% endif %}
|
||||
data-{{attribute_name}}-action="{{ button['name'] }}"
|
||||
aria-label="{{ button['label'] }}"
|
||||
|
|
|
|||
Loading…
Reference in a new issue