add draft on service page

*now show draft state on service card
*add input is_draft to send with form
*update script to get current draft state and a toggle button to update draft state for edit and new (useless for delete)
This commit is contained in:
Jordan Blasenhauer 2024-01-30 14:36:39 +01:00
parent 1eed27c141
commit 137b5ed4bb
7 changed files with 3648 additions and 84 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,7 @@ class Filter {
setTimeout(() => {
const value = document
.querySelector(
`[data-${this.prefix}-setting-select-text="reason"]`
`[data-${this.prefix}-setting-select-text="reason"]`,
)
.textContent.trim();
@ -159,7 +159,7 @@ class Dropdown {
const btn = e.target.closest("button");
const btnValue = btn.getAttribute("value");
const btnSetting = btn.getAttribute(
`data-${this.prefix}-setting-select-dropdown-btn`
`data-${this.prefix}-setting-select-dropdown-btn`,
);
//stop if same value to avoid new fetching
const isSameVal = this.isSameValue(btnSetting, btnValue);
@ -185,7 +185,7 @@ class Dropdown {
closeAllDrop() {
const drops = document.querySelectorAll(
`[data-${this.prefix}-setting-select-dropdown]`
`[data-${this.prefix}-setting-select-dropdown]`,
);
drops.forEach((drop) => {
drop.classList.add("hidden");
@ -193,8 +193,8 @@ class Dropdown {
document
.querySelector(
`svg[data-${this.prefix}-setting-select="${drop.getAttribute(
`data-${this.prefix}-setting-select-dropdown`
)}"]`
`data-${this.prefix}-setting-select-dropdown`,
)}"]`,
)
.classList.remove("rotate-180");
});
@ -202,7 +202,7 @@ class Dropdown {
isSameValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`
`[data-${this.prefix}-setting-select-text="${btnSetting}"]`,
);
const currVal = selectCustom.textContent;
return currVal === value ? true : false;
@ -210,30 +210,30 @@ class Dropdown {
setSelectNewValue(btnSetting, value) {
const selectCustom = document.querySelector(
`[data-${this.prefix}-setting-select="${btnSetting}"]`
`[data-${this.prefix}-setting-select="${btnSetting}"]`,
);
selectCustom.querySelector(
`[data-${this.prefix}-setting-select-text]`
`[data-${this.prefix}-setting-select-text]`,
).textContent = value;
}
hideDropdown(btnSetting) {
//hide dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
);
dropdownEl.classList.add("hidden");
dropdownEl.classList.remove("flex");
//svg effect
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`
`svg[data-${this.prefix}-setting-select="${btnSetting}"]`,
);
dropdownChevron.classList.remove("rotate-180");
}
changeDropBtnStyle(btnSetting, selectedBtn) {
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`
`[data-${this.prefix}-setting-select-dropdown="${btnSetting}"]`,
);
//reset dropdown btns
const btnEls = dropdownEl.querySelectorAll("button");
@ -243,7 +243,7 @@ class Dropdown {
"bg-primary",
"dark:bg-primary",
"text-gray-300",
"text-gray-300"
"text-gray-300",
);
btn.classList.add("bg-white", "dark:bg-slate-700", "text-gray-700");
});
@ -251,7 +251,7 @@ class Dropdown {
selectedBtn.classList.remove(
"bg-white",
"dark:bg-slate-700",
"text-gray-700"
"text-gray-700",
);
selectedBtn.classList.add("dark:bg-primary", "bg-primary", "text-gray-300");
}
@ -262,10 +262,10 @@ class Dropdown {
.getAttribute(`data-${this.prefix}-setting-select`);
//toggle dropdown
const dropdownEl = document.querySelector(
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`
`[data-${this.prefix}-setting-select-dropdown="${attribute}"]`,
);
const dropdownChevron = document.querySelector(
`svg[data-${this.prefix}-setting-select="${attribute}"]`
`svg[data-${this.prefix}-setting-select="${attribute}"]`,
);
dropdownEl.classList.toggle("hidden");
dropdownEl.classList.toggle("flex");
@ -318,7 +318,7 @@ class Unban {
setTimeout(() => {
// Check if at least one item is selected
const selected = this.listEl.querySelectorAll(
`input[data-checked="true"]`
`input[data-checked="true"]`,
);
// Case true, enable unban button
@ -340,7 +340,7 @@ class Unban {
if (this.unbanBtn.hasAttribute("disabled")) return;
// Get all selected items
const selected = this.listEl.querySelectorAll(
`input[data-checked="true"]`
`input[data-checked="true"]`,
);
const getDatas = [];
selected.forEach((el) => {
@ -366,7 +366,7 @@ class AddBanModal {
this.listEl = document.querySelector(`[data-bans-add-ban-list]`);
this.submitBtn = document.querySelector(`button[data-bans-modal-submit]`);
this.removeAllFieldBtn = document.querySelector(
"button[data-add-ban-delete-all-item]"
"button[data-add-ban-delete-all-item]",
);
this.formEl = document.querySelector("form[data-ban-add-form]");
this.itemCount = 0;
@ -561,7 +561,10 @@ class AddBanModal {
setDatepicker(id) {
const defaultDate = +(Date.now() + 3600000 * 24);
const inpEl = document.querySelector(`input#ban-end-${id}`);
inpEl.setAttribute("data-timestamp", defaultDate.toString().substring(0, 10));
inpEl.setAttribute(
"data-timestamp",
defaultDate.toString().substring(0, 10),
);
// instantiate datepicker
const dateOptions = {
@ -579,7 +582,10 @@ class AddBanModal {
// Case pick is before current date
if (pickStamp < nowStamp) {
inpEl.setAttribute("data-timestamp", defaultDate.toString().substring(0, 10));
inpEl.setAttribute(
"data-timestamp",
defaultDate.toString().substring(0, 10),
);
return instance.setDate(defaultDate);
}

View file

@ -19,32 +19,50 @@ class ServiceModal {
//modal forms
this.formNewEdit = this.modal.querySelector("[data-services-modal-form]");
this.formDelete = this.modal.querySelector(
"[data-services-modal-form-delete]"
"[data-services-modal-form-delete]",
);
this.submitBtn = document.querySelector(
"button[data-services-modal-submit]"
"button[data-services-modal-submit]",
);
//container
this.container = document.querySelector("main");
this.currAction = "";
this.init();
}
//store default config data on DOM
//to update modal data on new button click
getActionAndServName(target) {
getActionData(target) {
const action = target
.closest("button")
.getAttribute("data-services-action");
const serviceName = target
.closest("button")
.getAttribute("data-services-name");
return [action, serviceName];
const isDraft =
target
.closest("[data-services-service]")
.querySelector("[data-is-draft]")
.getAttribute("data-value") || "no";
return [action, serviceName, isDraft];
}
init() {
this.modal.addEventListener("click", (e) => {
// update draft mode
try {
if (e.target.closest("button").hasAttribute("data-toggle-draft-btn")) {
// Get current state
const currModeIsDraft = e.target
.querySelector('[data-toggle-draft="true"]')
.classList.contains("hidden")
? true
: false;
this.setIsDraft(currModeIsDraft);
}
} catch (e) {}
//close
try {
if (
@ -63,12 +81,18 @@ class ServiceModal {
"edit"
) {
//set form info and right form
const [action, serviceName] = this.getActionAndServName(e.target);
const [action, serviceName, isDraft] = this.getActionData(e.target);
const oldServName = e.target
.closest("[data-services-service]")
.querySelector("[data-old-service-name]")
.getAttribute("data-value");
this.setForm(action, serviceName, oldServName, this.formNewEdit);
this.setForm(
action,
serviceName,
oldServName,
this.formNewEdit,
isDraft,
);
//get service data and parse it
//multiple type logic is launch at same time on relate class
const servicesSettings = e.target
@ -90,8 +114,14 @@ class ServiceModal {
"clone"
) {
//set form info and right form
const [action, serviceName] = this.getActionAndServName(e.target);
this.setForm(action, serviceName, serviceName, this.formNewEdit);
const [action, serviceName, isDraft] = this.getActionData(e.target);
this.setForm(
action,
serviceName,
serviceName,
this.formNewEdit,
isDraft,
);
//set default value with method default
//get service data and parse it
//multiple type logic is launch at same time on relate class
@ -121,8 +151,14 @@ class ServiceModal {
"new"
) {
//set form info and right form
const [action, serviceName] = this.getActionAndServName(e.target);
this.setForm(action, serviceName, serviceName, this.formNewEdit);
const [action, serviceName, isDraft] = this.getActionData(e.target);
this.setForm(
action,
serviceName,
serviceName,
this.formNewEdit,
isDraft,
);
//set default value with method default
this.setSettingsDefault();
//server name is unset
@ -144,8 +180,14 @@ class ServiceModal {
"delete"
) {
//set form info and right form
const [action, serviceName] = this.getActionAndServName(e.target);
this.setForm(action, serviceName, serviceName, this.formDelete);
const [action, serviceName, isDraft] = this.getActionData(e.target);
this.setForm(
action,
serviceName,
serviceName,
this.formDelete,
isDraft,
);
//show modal
this.openModal();
}
@ -165,7 +207,7 @@ class ServiceModal {
"delete-btn",
"valid-btn",
"edit-btn",
"info-btn"
"info-btn",
);
this.submitBtn.classList.add(btnType);
}
@ -225,15 +267,15 @@ class ServiceModal {
//click the custom select dropdown to update select value
select.parentElement
.querySelector(
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`,
)
.click();
//set state to custom visible el
const btnCustom = document.querySelector(
`[data-setting-select=${select.getAttribute(
"data-setting-select-default"
)}]`
"data-setting-select-default",
)}]`,
);
this.setDisabledDefault(btnCustom, defaultMethod);
@ -248,9 +290,35 @@ class ServiceModal {
}
}
setForm(action, serviceName, oldServName, formEl) {
setIsDraft(isDraft) {
const draftVal = isDraft ? "yes" : "no";
const draftInps = [
this.formNewEdit.querySelector(`input[name="is_draft"]`),
this.formDelete.querySelector(`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 showEl = isDraft ? "true" : "false";
btn.querySelectorAll("[data-toggle-draft]").forEach((item) => {
if (item.getAttribute("data-toggle-draft") === showEl)
item.classList.remove("hidden");
if (item.getAttribute("data-toggle-draft") !== showEl)
item.classList.add("hidden");
});
}
setForm(action, serviceName, oldServName, formEl, isDraft) {
this.currAction = action;
this.setIsDraft(isDraft === "yes" ? true : false);
this.modalTitle.textContent = `${action} ${serviceName}`;
const operation = action === "clone" ? "new" : action;
formEl.setAttribute("id", `form-${operation}-${serviceName}`);
const opeInp = formEl.querySelector(`input[name="operation"]`);
opeInp.setAttribute("value", operation);
@ -272,9 +340,8 @@ class ServiceModal {
if (action === "delete") {
this.showDeleteForm();
formEl.querySelector(
`[data-services-modal-text]`
).textContent = `Are you sure you want to delete ${serviceName} ?`;
formEl.querySelector(`[data-services-modal-text]`).textContent =
`Are you sure you want to delete ${serviceName} ?`;
const nameInp = formEl.querySelector(`input[name="SERVER_NAME"]`);
nameInp.setAttribute("value", serviceName);
nameInp.value = serviceName;
@ -384,7 +451,7 @@ class ServiceModal {
if (inp.tagName === "SELECT") {
inp.parentElement
.querySelector(
`button[data-setting-select-dropdown-btn][value='${value}']`
`button[data-setting-select-dropdown-btn][value='${value}']`,
)
.click();
inp.setAttribute("data-method", method);
@ -489,7 +556,7 @@ class Multiple {
const attName = btn.getAttribute(`data-${this.prefix}-multiple-add`);
//get all multiple groups
const multipleEls = document.querySelectorAll(
`[data-${this.prefix}-settings-multiple*="${attName}"]`
`[data-${this.prefix}-settings-multiple*="${attName}"]`,
);
//case no schema
if (multipleEls.length <= 0) return;
@ -501,7 +568,7 @@ class Multiple {
//and keep the highest num
multipleEls.forEach((container) => {
const ctnrName = container.getAttribute(
"data-services-settings-multiple"
"data-services-settings-multiple",
);
const num = this.getSuffixNumOrFalse(ctnrName);
if (!isNaN(num) && num > topNum) topNum = num;
@ -512,7 +579,7 @@ class Multiple {
const setNum = +currNum === 0 ? `` : `_${currNum}`;
//the default (schema) group is the last group
const schema = document.querySelector(
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`
`[data-${this.prefix}-settings-multiple="${attName}_SCHEMA"]`,
);
//clone schema to create a group with new num
const schemaClone = schema.cloneNode(true);
@ -550,7 +617,7 @@ class Multiple {
.hasAttribute(`data-${this.prefix}-multiple-delete`)
) {
const multContainer = e.target.closest(
"[data-services-settings-multiple]"
"[data-services-settings-multiple]",
);
multContainer.remove();
}
@ -572,13 +639,13 @@ class Multiple {
? name.replace(`_${splitName[splitName.length - 1]}`, "").trim()
: name.trim();
const relateSetting = document.querySelector(
`[data-setting-container=${nameSuffixLess}_SCHEMA]`
`[data-setting-container=${nameSuffixLess}_SCHEMA]`,
);
const relateCtnr = relateSetting.closest(
"[data-services-settings-multiple]"
"[data-services-settings-multiple]",
);
const relateCtnrName = relateCtnr.getAttribute(
"data-services-settings-multiple"
"data-services-settings-multiple",
);
//then we sort the setting on the right container name by suffixe number
if (!(relateCtnrName in sortMultiples)) {
@ -596,7 +663,7 @@ class Multiple {
addOneMultGroup() {
const settings = document.querySelector("[data-services-modal-form]");
const multAddBtns = settings.querySelectorAll(
"[data-services-multiple-add]"
"[data-services-multiple-add]",
);
multAddBtns.forEach((btn) => {
//check if already one (SCHEMA exclude so length >= 2)
@ -611,7 +678,7 @@ class Multiple {
showMultByAtt(att) {
const multContainers = document.querySelectorAll(
`[data-services-settings-multiple^=${att}]`
`[data-services-settings-multiple^=${att}]`,
);
multContainers.forEach((container) => {
if (
@ -625,7 +692,7 @@ class Multiple {
toggleMultByAtt(att) {
const multContainers = document.querySelectorAll(
`[data-services-settings-multiple^=${att}]`
`[data-services-settings-multiple^=${att}]`,
);
multContainers.forEach((container) => {
if (
@ -641,7 +708,7 @@ class Multiple {
//get schema settings
const multiples = {};
const schemaSettings = document.querySelectorAll(
`[data-setting-container$="SCHEMA"]`
`[data-setting-container$="SCHEMA"]`,
);
// loop on every schema settings
schemaSettings.forEach((schema) => {
@ -667,11 +734,11 @@ class Multiple {
setMultipleToDOM(sortMultObj) {
//we loop on each multiple that contains values to render to DOM
for (const [schemaCtnrName, multGroupBySuffix] of Object.entries(
sortMultObj
sortMultObj,
)) {
//we need to access the DOM schema container
const schemaCtnr = document.querySelector(
`[data-services-settings-multiple="${schemaCtnrName}"]`
`[data-services-settings-multiple="${schemaCtnrName}"]`,
);
//now we have to loop on each multiple settings group
for (const [suffix, settings] of Object.entries(multGroupBySuffix)) {
@ -687,14 +754,14 @@ class Multiple {
for (const [name, data] of Object.entries(settings)) {
//get setting container of clone container
const settingContainer = schemaCtnrClone.querySelector(
`[data-setting-container="${name}"]`
`[data-setting-container="${name}"]`,
);
//replace input info and disabled state
this.setSetting(
data["value"],
data["method"],
data["global"],
settingContainer
settingContainer,
);
}
//send schema clone to DOM and show it
@ -709,7 +776,7 @@ class Multiple {
"data-services-settings-multiple",
schemaCtnrClone
.getAttribute("data-services-settings-multiple")
.replace("_SCHEMA", suffix)
.replace("_SCHEMA", suffix),
);
//rename title
@ -723,18 +790,18 @@ class Multiple {
//rename setting container
const settingCtnrs = schemaCtnrClone.querySelectorAll(
"[data-setting-container]"
"[data-setting-container]",
);
settingCtnrs.forEach((settingCtnr) => {
settingCtnr.setAttribute(
"data-setting-container",
settingCtnr
.getAttribute("data-setting-container")
.replace("_SCHEMA", suffix)
.replace("_SCHEMA", suffix),
);
settingCtnr.setAttribute(
"id",
settingCtnr.getAttribute("id").replace("_SCHEMA", suffix)
settingCtnr.getAttribute("id").replace("_SCHEMA", suffix),
);
});
@ -811,15 +878,15 @@ class Multiple {
//click the custom select dropdown btn value to update select value
select.parentElement
.querySelector(
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`
`button[data-setting-select-dropdown-btn][value='${defaultVal}']`,
)
.click();
//set state to custom visible el
const btnCustom = document.querySelector(
`[data-setting-select=${select.getAttribute(
"data-setting-select-default"
)}]`
"data-setting-select-default",
)}]`,
);
this.setDisabledMultServ(btnCustom, method, global);
@ -855,10 +922,10 @@ class Multiple {
selects.forEach((select) => {
const method = select.getAttribute("data-default-method");
const name = select.getAttribute(
"data-services-setting-select-default"
"data-services-setting-select-default",
);
const selDOM = document.querySelector(
`button[data-services-setting-select='${name}']`
`button[data-services-setting-select='${name}']`,
);
if (method === "ui" || method === "default") {
selDOM.removeAttribute("disabled", "");
@ -893,7 +960,7 @@ class Multiple {
hiddenIfNoMultiples() {
//hide multiple btn if no multiple exist on a plugin
const multiples = document.querySelectorAll(
`[data-${this.prefix}-settings-multiple]`
`[data-${this.prefix}-settings-multiple]`,
);
multiples.forEach((container) => {
if (container.querySelectorAll(`[data-setting-container]`).length <= 0)
@ -905,7 +972,7 @@ class Multiple {
removePrevMultiples() {
const multiPlugins = document.querySelectorAll(
`[data-${this.prefix}-settings-multiple]`
`[data-${this.prefix}-settings-multiple]`,
);
multiPlugins.forEach((multiGrp) => {
if (
@ -943,7 +1010,7 @@ const setModal = new ServiceModal();
const format = new FormatValue();
const setFilterGlobal = new FilterSettings(
"settings-filter",
"[data-service-content='settings']"
"[data-service-content='settings']",
);
const setMultiple = new Multiple("services");

View file

@ -50,7 +50,7 @@
</div>
<!-- action button -->
<div class="w-full justify-center flex mt-10">
<button
<button
data-plugins-modal-close
class="close-btn mb-4 mr-3 text-base"
>

View file

@ -37,9 +37,27 @@
>
<div data-services-settings class="hidden" data-value="{{service['settings']}}"></div>
<div data-old-service-name class="hidden" data-value="{{service['SERVER_NAME']['full_value']}}"></div>
<h5 class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
{{ service["SERVER_NAME"]['value'] }}
</h5>
<div data-is-draft class="hidden" data-value="{% if service.get('IS_DRAFT', "no") == "yes" %}yes{%else%}no{%endif%}"></div>
<div class="flex justify-between items-start">
<h5 class="transition duration-300 ease-in-out text-center sm:text-left mb-1 font-bold dark:text-white/90">
{{ service["SERVER_NAME"]['value'] }}
</h5>
{% if service.get('IS_DRAFT', "no") == "yes" %}
<button class="group relative">
<p class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">Draft</p>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
<path fill-rule="evenodd" d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z" clip-rule="evenodd" />
</svg>
</button>
{% else %}
<button class="group relative">
<p class="dark:text-gray-300 -z-10 opacity-0 group-hover:z-10 group-hover:opacity-100 transition fixed bg-white dark:bg-slate-800 rounded right-12 px-1 py-0.5">Online</p>
<svg data-toggle-draft="false" data-toggle-draft="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-gray-700 dark:fill-gray-300 cursor-pointer-none">
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
</svg>
</button>
{% endif %}
</div>
<h6 class="text-center sm:text-left mb-2 font-semibold text-gray-600 dark:text-white/80">{{ service["SERVER_NAME"]['method'] }}</h5>
<!-- detail list -->
@ -366,10 +384,11 @@
class="dark:brightness-90 z-20 mx-1 bg-emerald-500 hover:bg-emerald-500/80 focus:bg-emerald-500/80 inline-block p-3 font-bold text-center text-white uppercase align-middle transition-all rounded-lg cursor-pointer leading-normal text-xs ease-in tracking-tight-rem shadow-xs bg-150 bg-x-25 active:opacity-85 hover:shadow-md"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 fill-white">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184" />
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-white">
<path fill-rule="evenodd" d="M17.663 3.118c.225.015.45.032.673.05C19.876 3.298 21 4.604 21 6.109v9.642a3 3 0 0 1-3 3V16.5c0-5.922-4.576-10.775-10.384-11.217.324-1.132 1.3-2.01 2.548-2.114.224-.019.448-.036.673-.051A3 3 0 0 1 13.5 1.5H15a3 3 0 0 1 2.663 1.618ZM12 4.5A1.5 1.5 0 0 1 13.5 3H15a1.5 1.5 0 0 1 1.5 1.5H12Z" clip-rule="evenodd" />
<path d="M3 8.625c0-1.036.84-1.875 1.875-1.875h.375A3.75 3.75 0 0 1 9 10.5v1.875c0 1.036.84 1.875 1.875 1.875h1.875A3.75 3.75 0 0 1 16.5 18v2.625c0 1.035-.84 1.875-1.875 1.875h-9.75A1.875 1.875 0 0 1 3 20.625v-12Z" />
<path d="M10.5 10.5a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963 5.23 5.23 0 0 0-3.434-1.279h-1.875a.375.375 0 0 1-.375-.375V10.5Z" />
</svg>
</button>

View file

@ -9,12 +9,24 @@
class="overflow-y-auto mx-0 sm:mx-6 lg:mx-8 my-3 px-4 pt-4 pb-8 w-full sm:min-w-[500px] h-[90vh] flex flex-col break-words bg-white shadow-xl dark:bg-slate-850 dark:shadow-dark-xl rounded-2xl bg-clip-border"
>
<div class="w-full flex justify-between mb-2">
<p
data-services-modal-title
class="transition duration-300 ease-in-out dark:opacity-90 dark:text-gray-200 mb-2 font-sans font-semibold leading-normal uppercase text-md"
>
SERVICE MODAL
</p>
<div class="flex justify-start items-end">
<p
data-services-modal-title
class="transition duration-300 ease-in-out dark:opacity-90 dark:text-gray-200 mb-2 font-sans font-semibold leading-normal uppercase text-md"
>
SERVICE MODAL
</p>
<button data-toggle-draft-btn class="transition hover:brightness-75 dark:hover:brightness-110 ml-4 flex items-center border border-gray-700 dark:border-gray-300 rounded py-1 px-2">
<p data-toggle-draft="true" class="hidden dark:text-gray-300 mb-0 mr-2 pointer-events-none">Draft</p>
<p data-toggle-draft="false" class="hidden dark:text-gray-300 mb-0 mr-2 pointer-events-none">Online</p>
<svg data-toggle-draft="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="hidden w-5 h-5 fill-gray-700 dark:fill-gray-300 pointer-events-none">
<path fill-rule="evenodd" d="M10.5 3.798v5.02a3 3 0 0 1-.879 2.121l-2.377 2.377a9.845 9.845 0 0 1 5.091 1.013 8.315 8.315 0 0 0 5.713.636l.285-.071-3.954-3.955a3 3 0 0 1-.879-2.121v-5.02a23.614 23.614 0 0 0-3 0Zm4.5.138a.75.75 0 0 0 .093-1.495A24.837 24.837 0 0 0 12 2.25a25.048 25.048 0 0 0-3.093.191A.75.75 0 0 0 9 3.936v4.882a1.5 1.5 0 0 1-.44 1.06l-6.293 6.294c-1.62 1.621-.903 4.475 1.471 4.88 2.686.46 5.447.698 8.262.698 2.816 0 5.576-.239 8.262-.697 2.373-.406 3.092-3.26 1.47-4.881L15.44 9.879A1.5 1.5 0 0 1 15 8.818V3.936Z" clip-rule="evenodd" />
</svg>
<svg data-toggle-draft="false" data-toggle-draft="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="hidden w-5 h-5 fill-gray-700 dark:fill-gray-300 pointer-events-none">
<path d="M21.721 12.752a9.711 9.711 0 0 0-.945-5.003 12.754 12.754 0 0 1-4.339 2.708 18.991 18.991 0 0 1-.214 4.772 17.165 17.165 0 0 0 5.498-2.477ZM14.634 15.55a17.324 17.324 0 0 0 .332-4.647c-.952.227-1.945.347-2.966.347-1.021 0-2.014-.12-2.966-.347a17.515 17.515 0 0 0 .332 4.647 17.385 17.385 0 0 0 5.268 0ZM9.772 17.119a18.963 18.963 0 0 0 4.456 0A17.182 17.182 0 0 1 12 21.724a17.18 17.18 0 0 1-2.228-4.605ZM7.777 15.23a18.87 18.87 0 0 1-.214-4.774 12.753 12.753 0 0 1-4.34-2.708 9.711 9.711 0 0 0-.944 5.004 17.165 17.165 0 0 0 5.498 2.477ZM21.356 14.752a9.765 9.765 0 0 1-7.478 6.817 18.64 18.64 0 0 0 1.988-4.718 18.627 18.627 0 0 0 5.49-2.098ZM2.644 14.752c1.682.971 3.53 1.688 5.49 2.099a18.64 18.64 0 0 0 1.988 4.718 9.765 9.765 0 0 1-7.478-6.816ZM13.878 2.43a9.755 9.755 0 0 1 6.116 3.986 11.267 11.267 0 0 1-3.746 2.504 18.63 18.63 0 0 0-2.37-6.49ZM12 2.276a17.152 17.152 0 0 1 2.805 7.121c-.897.23-1.837.353-2.805.353-.968 0-1.908-.122-2.805-.353A17.151 17.151 0 0 1 12 2.276ZM10.122 2.43a18.629 18.629 0 0 0-2.37 6.49 11.266 11.266 0 0 1-3.746-2.504 9.754 9.754 0 0 1 6.116-3.985Z" />
</svg>
</button>
</div>
<button
class="-translate-y-1"
aria-label="close modal"
@ -66,6 +78,7 @@
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<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" />
{% include "settings_plugins.html" %}
@ -94,6 +107,7 @@
>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" value="delete" name="operation" />
<input type="hidden" value="no" name="is_draft" />
<input type="hidden" value="" name="SERVER_NAME" />
<div class="flex justify-center">