diff --git a/src/ui/static/css/dashboard.css b/src/ui/static/css/dashboard.css index 93e85a1e6..d63e7a7ad 100644 --- a/src/ui/static/css/dashboard.css +++ b/src/ui/static/css/dashboard.css @@ -843,14 +843,6 @@ h6 { grid-column: auto; } -.col-span-6 { - grid-column: span 6 / span 6; -} - -.col-span-4 { - grid-column: span 4 / span 4; -} - .float-right { float: right; } @@ -931,16 +923,16 @@ h6 { margin-right: 0.625rem; } -.mx-4 { - margin-left: 1rem; - margin-right: 1rem; -} - .mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; } +.mx-4 { + margin-left: 1rem; + margin-right: 1rem; +} + .my-5 { margin-top: 1.25rem; margin-bottom: 1.25rem; @@ -1014,6 +1006,10 @@ h6 { margin-left: 1.5rem; } +.ml-2 { + margin-left: 0.5rem; +} + .mb-8 { margin-bottom: 2rem; } @@ -1038,10 +1034,6 @@ h6 { margin-top: 0.125rem; } -.ml-2 { - margin-left: 0.5rem; -} - .ml-0 { margin-left: 0px; } @@ -1182,10 +1174,6 @@ h6 { height: 25rem; } -.h-7 { - height: 1.75rem; -} - .h-1\/3 { height: 33.333333%; } @@ -1206,10 +1194,6 @@ h6 { max-height: 7.5rem; } -.max-h-16 { - max-height: 4rem; -} - .max-h-80 { max-height: 20rem; } @@ -1326,18 +1310,10 @@ h6 { width: 20rem; } -.w-7 { - width: 1.75rem; -} - .min-w-0 { min-width: 0px; } -.min-w-\[750px\] { - min-width: 750px; -} - .min-w-\[900px\] { min-width: 900px; } @@ -1444,11 +1420,6 @@ h6 { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.translate-y-12 { - --tw-translate-y: 3rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - .translate-x-1 { --tw-translate-x: 0.25rem; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -1489,11 +1460,6 @@ h6 { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.translate-y-19 { - --tw-translate-y: 4.75rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} - .rotate-180 { --tw-rotate: 180deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -1700,6 +1666,16 @@ h6 { border-top-right-radius: 0.25rem; } +.rounded-b-lg { + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; +} + +.rounded-t-lg { + border-top-left-radius: 0.5rem; + border-top-right-radius: 0.5rem; +} + .rounded-b { border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; @@ -1710,16 +1686,6 @@ h6 { border-top-right-radius: 1rem; } -.rounded-t-lg { - border-top-left-radius: 0.5rem; - border-top-right-radius: 0.5rem; -} - -.rounded-b-lg { - border-bottom-right-radius: 0.5rem; - border-bottom-left-radius: 0.5rem; -} - .border-2 { border-width: 2px; } @@ -1869,10 +1835,6 @@ h6 { background-color: rgb(64 187 107 / 0.8); } -.bg-opacity-0 { - --tw-bg-opacity: 0; -} - .bg-none { background-image: none; } @@ -2099,6 +2061,11 @@ h6 { padding-right: 0.75rem; } +.py-2\.5 { + padding-top: 0.625rem; + padding-bottom: 0.625rem; +} + .px-12 { padding-left: 3rem; padding-right: 3rem; @@ -2129,6 +2096,11 @@ h6 { padding-right: 0.125rem; } +.py-1\.5 { + padding-top: 0.375rem; + padding-bottom: 0.375rem; +} + .py-1\.4 { padding-top: 0.35rem; padding-bottom: 0.35rem; @@ -2144,31 +2116,6 @@ h6 { padding-bottom: 1.25rem; } -.py-0 { - padding-top: 0px; - padding-bottom: 0px; -} - -.py-0\.5 { - padding-top: 0.125rem; - padding-bottom: 0.125rem; -} - -.py-1\.5 { - padding-top: 0.375rem; - padding-bottom: 0.375rem; -} - -.py-0\.6 { - padding-top: 0.15rem; - padding-bottom: 0.15rem; -} - -.py-2\.5 { - padding-top: 0.625rem; - padding-bottom: 0.625rem; -} - .pb-0 { padding-bottom: 0px; } @@ -2310,10 +2257,6 @@ h6 { text-transform: uppercase; } -.lowercase { - text-transform: lowercase; -} - .capitalize { text-transform: capitalize; } @@ -2342,22 +2285,14 @@ h6 { line-height: 1; } -.leading-tight { - line-height: 1.25; -} - -.leading-3 { - line-height: 0.75rem; -} - -.leading-4 { - line-height: 1rem; -} - .leading-6 { line-height: 1.5rem; } +.leading-tight { + line-height: 1.25; +} + .tracking-tight-rem { letter-spacing: -0.025rem; } @@ -2967,6 +2902,16 @@ h6 { border-color: rgb(58 65 111 / var(--tw-border-opacity)); } +.dark .dark\:border-slate-850 { + --tw-border-opacity: 1; + border-color: rgb(17 28 68 / var(--tw-border-opacity)); +} + +.dark .dark\:border-gray-700 { + --tw-border-opacity: 1; + border-color: rgb(73 80 87 / var(--tw-border-opacity)); +} + .dark .dark\:bg-slate-900 { --tw-bg-opacity: 1; background-color: rgb(5 17 57 / var(--tw-bg-opacity)); @@ -3186,11 +3131,6 @@ h6 { grid-column-start: 5; } - .sm\:my-0 { - margin-top: 0px; - margin-bottom: 0px; - } - .sm\:mx-6 { margin-left: 1.5rem; margin-right: 1.5rem; @@ -3423,11 +3363,6 @@ h6 { margin-right: 2rem; } - .lg\:mx-0 { - margin-left: 0px; - margin-right: 0px; - } - .lg\:mt-0 { margin-top: 0px; } diff --git a/src/ui/static/js/services.js b/src/ui/static/js/services.js index 6ef5709c2..960399ba6 100644 --- a/src/ui/static/js/services.js +++ b/src/ui/static/js/services.js @@ -236,12 +236,32 @@ class ServiceModal { class Multiple { constructor(prefix) { this.prefix = prefix; - this.container = document.querySelector(`[${this.prefix}-modal-form]`); + this.container = document.querySelector("main"); + this.modalForm = document.querySelector(`[${this.prefix}-modal-form]`); this.init(); } init() { this.container.addEventListener("click", (e) => { + //edit button + try { + if ( + e.target.closest("button").getAttribute("services-action") === "edit" + ) { + //remove all multiples + this.removeMultiples(); + //set multiple service values + const servicesSettings = e.target + .closest("[services-service]") + .querySelector("[services-settings]") + .getAttribute("value"); + const obj = JSON.parse(servicesSettings); + this.updateModalMultiples(obj); + } + } catch (err) {} + }); + + this.modalForm.addEventListener("click", (e) => { //ADD BTN try { if ( @@ -252,37 +272,70 @@ class Multiple { const serviceName = btn.getAttribute(`${this.prefix}-multiple-add`); //get all multiple groups const multipleEls = document.querySelectorAll( - `[${this.prefix}-settings-multiple="${serviceName}"]` + `[${this.prefix}-settings-multiple*="${serviceName}"]` + ); + const count = Number( + multipleEls[1] + .getAttribute(`${this.prefix}-settings-multiple`) + .substring( + multipleEls[1].getAttribute(`${this.prefix}-settings-multiple`) + .length - 1 + ) ); - const multipleCount = multipleEls.length; //the default (schema) group is the last group - const schema = multipleEls[multipleEls.length - 1]; + const schema = document.querySelector( + `[${this.prefix}-settings-multiple="${serviceName}_SCHEMA"]` + ); //clone it and change name by total - 1 (schema is hidden) const clone = schema.cloneNode(true); - const cloneTitles = clone.querySelectorAll("h5"); - const cloneInps = clone.querySelectorAll("input"); - const cloneSelects = clone.querySelectorAll("select"); + console.log(clone.getAttribute("services-settings-multiple")); + const name = clone + .getAttribute("services-settings-multiple") + .replace(`SCHEMA`, `${count + 1}`); + clone.setAttribute("services-settings-multiple", name); + clone.classList.remove("hidden"); + clone.classList.add("grid"); - cloneTitles.forEach((title) => { - title.textContent = `${title.textContent} #${multipleCount}`; - }); + try { + const cloneContainer = clone.querySelectorAll( + "[setting-container]" + ); + cloneContainer.forEach((ctnr) => { + const newName = ctnr + .getAttribute("setting-container") + .replace("SCHEMA", `${count + 1}`); + ctnr.setAttribute("setting-container", newName); + }); + } catch (err) {} - cloneInps.forEach((inp) => { - const currID = inp.getAttribute("id"); - const currName = inp.getAttribute("name"); - inp.setAttribute("id", `${currID}_${multipleCount}`); - inp.setAttribute("name", `${currName}_${multipleCount}`); - }); + try { + const cloneTitles = clone.querySelectorAll("h5"); + cloneTitles.forEach((title) => { + title.textContent = `${title.textContent} #${count + 1}`; + }); + } catch (err) {} - cloneSelects.forEach((select) => { - const currID = select.getAttribute("id"); - const currName = select.getAttribute("name"); - select.setAttribute("id", `${currID}_${multipleCount}`); - select.setAttribute("name", `${currName}_${multipleCount}`); - }); + try { + const cloneInps = clone.querySelectorAll("input"); + cloneInps.forEach((inp) => { + const currID = inp.getAttribute("id"); + const currName = inp.getAttribute("name"); + inp.setAttribute("id", `${currID}_${count + 1}`); + inp.setAttribute("name", `${currName}_${count + 1}`); + }); + } catch (err) {} + + try { + const cloneSelects = clone.querySelectorAll("select"); + cloneSelects.forEach((select) => { + const currID = select.getAttribute("id"); + const currName = select.getAttribute("name"); + select.setAttribute("id", `${currID}_${count + 1}`); + select.setAttribute("name", `${currName}_${count + 1}`); + }); + } catch (err) {} //insert new group before first one - const firstMultiple = multipleEls[0]; - firstMultiple.insertAdjacentElement("beforebegin", clone); + schema.insertAdjacentElement("afterend", clone); } } catch (err) {} @@ -293,23 +346,146 @@ class Multiple { .closest("button") .hasAttribute(`${this.prefix}-multiple-delete`) ) { - //remove the first element (last created) - //unless it is the schema (length 1) - const btn = e.target.closest("button"); - const serviceName = btn.getAttribute( - `${this.prefix}-multiple-delete` + const multContainer = e.target.closest( + "[services-settings-multiple]" ); - const multipleEls = document.querySelectorAll( - `[${this.prefix}-settings-multiple="${serviceName}"]` - ); - if (multipleEls.length === 1) return; - const firstMultiple = multipleEls[0]; - firstMultiple.remove(); + multContainer.remove(); } //remove last child } catch (err) {} }); } + + removeMultiples() { + const multiPlugins = document.querySelectorAll( + `[${this.prefix}-settings-multiple]` + ); + multiPlugins.forEach((multiGrp) => { + if ( + !multiGrp.getAttribute("services-settings-multiple").includes("SCHEMA") + ) + multiGrp.remove(); + }); + } + + updateModalMultiples(settings) { + //filter to get only multiples of services + const multipleSettings = {}; + for (const [key, data] of Object.entries(settings)) { + if (!isNaN(key[key.length - 1]) && key[key.length - 2] === "_") { + multipleSettings[key] = { + value: data["value"], + method: data["method"], + }; + } + } + + //add them to the right plugin + for (const [key, data] of Object.entries(multipleSettings)) { + const num = key[key.length - 1]; + const getSchemaKey = key.substring(0, key.length - 2); + const getSchemaSetting = document.querySelector( + `[setting-container="${getSchemaKey}_SCHEMA"]` + ); + const cloneSchemaSetting = getSchemaSetting.cloneNode(true); + //replace info + cloneSchemaSetting.setAttribute("setting-container", key); + const title = cloneSchemaSetting.querySelector("h5"); + title.textContent = `${title.textContent} #${num}`; + //replace input info + try { + const inp = cloneSchemaSetting.querySelector("input"); + inp.setAttribute("id", `${key}`); + inp.setAttribute("name", `${key}`); + } catch (err) {} + //or select + try { + const select = cloneSchemaSetting.querySelector("select"); + select.setAttribute("id", `${key}`); + select.setAttribute("name", `${key}`); + } catch (err) {} + getSchemaSetting.insertAdjacentElement("beforebegin", cloneSchemaSetting); + } + //get multiple for all plugins + const multiPlugins = document.querySelectorAll( + `[${this.prefix}-settings-multiple]` + ); + + multiPlugins.forEach((defaultGrp) => { + //get group number for the multiples settings + const multipleEls = defaultGrp.querySelectorAll("[setting-container]"); + const multNum = new Set(); + multipleEls.forEach((setting) => { + const name = setting.getAttribute("setting-container"); + if (!isNaN(name[name.length - 1])) multNum.add(name[name.length - 1]); + }); + //create a different group for each number + multNum.forEach((num) => { + const newGroup = defaultGrp.cloneNode(true); + newGroup.classList.add("grid"); + newGroup.classList.remove("hidden"); + //change groupe name + const currName = newGroup.getAttribute( + `${this.prefix}-settings-multiple` + ); + newGroup.setAttribute( + `${this.prefix}-settings-multiple`, + currName.replace("SCHEMA", num) + ); + + //remove elements that not fit num unless schema if no custom value + const newGroupSettings = newGroup.querySelectorAll( + "[setting-container]" + ); + newGroupSettings.forEach((setting) => { + //remove logic + const settingName = setting.getAttribute("setting-container"); + if ( + (!settingName.endsWith(num) && !settingName.endsWith("SCHEMA")) || + (settingName.endsWith("SCHEMA") && + document.querySelector(`${settingName.replace("SCHEMA", num)}`)) + ) { + return setting.remove(); + } + //else update info by num + setting.setAttribute( + "setting-container", + setting.getAttribute("setting-container").replace(`SCHEMA`, num) + ); + const title = setting.querySelector("h5"); + if (!title.textContent.includes(`#${num}`)) + title.textContent = `${title.textContent} #${num}`; + //replace input info + try { + const inp = setting.querySelector("input"); + inp.setAttribute("id", setting.getAttribute("setting-container")); + inp.setAttribute("name", setting.getAttribute("setting-container")); + } catch (err) {} + //or select + try { + const select = setting.querySelector("select"); + select.setAttribute( + "id", + setting.getAttribute("setting-container") + ); + select.setAttribute( + "name", + setting.getAttribute("setting-container") + ); + } catch (err) {} + }); + defaultGrp.insertAdjacentElement("afterend", newGroup); + }); + }); + //remove custom multiple from schema + multiPlugins.forEach((defaultGrp) => { + const multipleEls = defaultGrp.querySelectorAll("[setting-container]"); + multipleEls.forEach((setting) => { + const settingName = setting.getAttribute("setting-container"); + if (!settingName.endsWith("SCHEMA")) setting.remove(); + }); + }); + } } const setCheckbox = new Checkbox("[services-modal-form]"); diff --git a/src/ui/static/js/utils.js b/src/ui/static/js/utils.js index e0209f8c8..d395ec80f 100644 --- a/src/ui/static/js/utils.js +++ b/src/ui/static/js/utils.js @@ -907,7 +907,6 @@ class FormatValue { init() { this.inputs.forEach((inp) => { - console.log(inp); inp.setAttribute("value", inp.getAttribute("value").trim()); }); } diff --git a/src/ui/templates/settings_plugins.html b/src/ui/templates/settings_plugins.html index 8847843a4..785406ac8 100644 --- a/src/ui/templates/settings_plugins.html +++ b/src/ui/templates/settings_plugins.html @@ -5,6 +5,7 @@ {% set plugins = config["CONFIG"].get_plugins() %} {% for plugin in plugins %} +