Fix checkbox not being sent when unchecked + double settings tab in UI

This commit is contained in:
Théophile Diot 2023-02-15 17:02:47 +01:00
parent 9358057211
commit 5799758993
No known key found for this signature in database
GPG Key ID: E752C80DB72BB014
6 changed files with 35 additions and 285 deletions

View File

@ -258,11 +258,12 @@ class Database:
if "id" not in plugin:
settings = plugin
plugin = {
"id": "default",
"id": "general",
"order": 999,
"name": "Default",
"description": "Default settings",
"name": "General",
"description": "The general settings for the server",
"version": "0.1",
"external": False,
}
else:
settings = plugin.pop("settings", {})

View File

@ -139,6 +139,15 @@ class Config:
if not exists("/usr/sbin/nginx"):
plugins = self.__db.get_plugins()
plugins.sort(key=lambda x: x["name"])
general_plugin = None
for x, plugin in enumerate(plugins):
if plugin["name"] == "General":
general_plugin = plugin
del plugins[x]
break
plugins.insert(0, general_plugin)
return plugins
plugins = []
@ -167,6 +176,22 @@ class Config:
plugins.append(plugin)
plugins.sort(key=lambda x: x["name"])
with open("/usr/share/bunkerweb/settings.json", "r") as f:
plugins.insert(
0,
{
"id": "general",
"order": 999,
"name": "General",
"description": "The general settings for the server",
"version": "0.1",
"external": False,
"page": False,
"settings": json_load(f),
},
)
return plugins
def get_settings(self) -> dict:

View File

@ -35,10 +35,6 @@ config["CONFIG"].get_config() %}
>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<!-- general container -->
{% include "settings_general.html" %}
<!-- end general container -->
<!-- plugin item -->
{% include "settings_plugins.html" %}
<!-- end plugin item -->

View File

@ -1,194 +0,0 @@
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-')
%}
<!-- plugin item -->
{% set plugins = config["CONFIG"].get_plugins() %}
{% set global_config = config["CONFIG"].get_config() %}
<!-- general container -->
<div plugin-item="general" class="w-full">
<!-- general conf -->
<div class="col-span-12" setting-header>
<h5 class="transition duration-300 ease-in-out dark:opacity-90 ml-2 font-bold text-md uppercase dark:text-white mb-0">GENERAL</h5>
<div class="transition duration-300 ease-in-out dark:opacity-90 ml-2 text-sm mb-2 dark:text-gray-400">
General config : HTTP, DNS, LOG, API...
</div>
</div>
<div
plugin-settings
class="w-full grid grid-cols-12"
id="edit-{{current_endpoint}}-general"
>
{% for
setting, value in config["CONFIG"].get_settings().items() %} {%
if current_endpoint == "global-config" and value["context"] == "global" and "label" in value %}
<div setting-container
class="mx-0 sm:mx-4 my-2 col-span-12 md:mx-6 md:my-3 md:col-span-6 2xl:col-span-4 xl:mx-4 2xl:my-2 3xl:col-span-3"
id="form-edit-{{current_endpoint}}-{{ value["id"] }}"
>
<!-- title and info -->
<div class="flex items-center my-1 relative">
<h5 class="transition duration-300 ease-in-out dark:opacity-90 text-sm sm:text-md font-bold m-0 dark:text-gray-300">{{value["label"]}}</h5>
<svg
popover-btn="{{ value["label"] }}"
class="cursor-pointer fill-blue-500 h-5 w-5 ml-2 hover:brightness-75"
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>
<!-- popover -->
<div class="hidden transition z-50 rounded-md p-3 left-0 -translate-y-7 bottom-0 absolute bg-blue-500"
popover-content="{{ value["label"] }}"
>
<p class="transition duration-300 ease-in-out dark:opacity-90 font-bold text-sm text-white m-0" > {{value['help']}}
</p>
</div>
<!-- end popover -->
</div>
<!-- end title and info -->
<!-- input -->
{% if value["type"] != "select" and value["type"] != "check" %}
<div class="relative flex items-center">
<input
default-value="{{global_config[setting]['value']}}" default-method="{{global_config[setting]['method']}}"
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %} id="{{setting}}" name="{{setting}}"
class="outline-none dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 disabled:opacity-75 focus:border-gray-300/0 focus:ring-1 focus:valid:ring-green-500 focus:invalid:ring-red-500 text-sm leading-5.6 ease block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700"
value="{% if global_config[setting]['value'] %} {{global_config[setting]['value']}} {% else %} {{value['default']}} {% endif %}" type="{{value['type']}}" pattern="{{value['regex']|safe}}" />
{% if value['type'] == "password" %}
<div setting-password-container class="absolute flex right-2 h-5 w-5">
<button type="button" setting-password="visible" class="h-5 w-5 flex items-center align-middle" type="button">
<svg class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg>
</button>
<button type="button" setting-password="invisible" class="hidden -translate-y-0.2 scale-110 h-5 w-5 items-center align-middle">
<svg class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg>
</button>
</div>
{%endif%}
</div>
{% endif %}
<!-- end input -->
<!-- select -->
{% if value["type"] == "select" %}
<!-- default hidden-->
<select id="{{setting}}" name="{{setting}}" select-default="{{value['id']}}" type="form-select" id="{{setting}}" name="{{setting}}"
class="hidden">
{% for item in value['select'] %}
<option value="{{item}}" {% if global_config[setting]['value'] and global_config[setting]['value'] == item or not global_config[setting]['value'] and value['default'] == item %} selected{% endif %}>{{item}}</option>
{% endfor %}
</select>
<!-- end default hidden-->
<!--custom-->
<div select-container class="relative">
{% for item in value['select'] %}
{% if global_config[setting]['value'] and global_config[setting]['value'] == item %}
<button
default-value="{{value['default']}}"
setting-select="{{value['id']}}"
value="{{global_config[setting]['value']}}"
type="button"
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %} class="disabled:opacity-75 dark:disabled:text-gray-300 disabled:text-gray-700 disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-primary flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
setting-select-text="{{value['id']}}"
value="{{global_config[setting]['value']}}"
>{{global_config[setting]['value']}}</span
>
<!-- chevron -->
<svg
setting-select="{{value['id']}}"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"
/>
</svg>
<!-- end chevron -->
</button>
{% elif not global_config[setting]['value'] and value['default'] == item %}
<button
setting-select="{{value['id']}}"
value="{{value['default']}}"
default-value="{{value['default']}}"
type="button"
class="duration-300 ease-in-out dark:opacity-90 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 focus:border-green-500 flex justify-between align-middle items-center text-left text-sm leading-5.6 ease w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500"
>
<span
setting-select-text="{{value['id']}}"
value="{{value['default']}}"
>{{value['default']}}</span
> <!-- chevron -->
<svg
setting-select="{{value['id']}}"
class="transition-transform h-4 w-4 fill-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<path
d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"
/>
</svg>
<!-- end chevron -->
</button>
{% endif %}
{% endfor %}
<!-- dropdown-->
<div
setting-select-dropdown="{{value['id']}}"
class="hidden z-[20] absolute h-full flex-col w-full mt-2 "
>
{% for item in value['select'] %}
{% if global_config[setting]['value'] and global_config[setting]['value'] == item or not global_config[setting]['value'] and value['default'] == item %}
<button type="button" value="{{item}}" setting-select-dropdown-btn="{{value['id']}}" type="button" class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-primary dark:bg-primary my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:text-gray-300 text-gray-300"
>{{item}}</button>
{% else %}
<button type="button" value="{{item}}" setting-select-dropdown-btn="{{value['id']}}" type="button" class="{% if loop.index == 1 %} border-t rounded-t {% endif %} {% if loop.index == loop.length %}rounded-b {% endif %} border-b border-l border-r border-gray-300 dark:hover:brightness-90 hover:brightness-90 bg-white text-gray-700 my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300"
>{{item}}</button>
{% endif %}
{% endfor %}
</div>
<!-- end dropdown-->
</div>
<!-- end custom-->
{% endif %}
<!-- checkbox -->
{% if value["type"] == "check" %}
<div checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<input id="{{setting}}" name="{{setting}}"
default-method="{{global_config[setting]['method']}}" default-value="{{value['default']}}"
{% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} disabled {% endif %}
{% if global_config[setting]['value'] and global_config[setting]['value'] == 'yes' or not global_config[setting]['value'] and value['default'] == 'yes' %} checked {% endif %} id="checkbox-{{value['id']}}"
class="relative {% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} pointer-events-none {% else %} cursor-pointer {% endif %} dark:border-slate-600 dark:bg-slate-700 z-10 checked:z-0 w-5 h-5 ease text-base rounded-1.4 checked:bg-primary checked:border-primary dark:checked:bg-primary dark:checked:border-primary duration-250 float-left mt-1 appearance-none border border-gray-300 bg-white bg-contain bg-center bg-no-repeat align-top transition-all disabled:bg-gray-400 disabled:border-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 disabled:text-gray-700 dark:disabled:text-gray-300"
type="checkbox"
pattern="{{value['regex']|safe}}"
value="{% if global_config[setting]['value'] %} {{global_config[setting]['value']}} {% else %} {{value['default']}} {% endif %}"
/>
<svg checkbox-handler="{{value['id']}}" class="pointer-events-none {% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} pointer-events-none {% else %} cursor-pointer {% endif %} 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" viewBox="0 0 512 512">
<path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"></path>
</svg>
</div>
{% endif %}
<!-- end checkbox -->
<!-- invalid feedback -->
<div class="hidden text-sm dark:text-red-500">
{{value['label']}} is invalid and must match this pattern: {{value['regex']|safe}}
</div>
<!--end invalid feedback -->
</div>
{% endif %} {% endfor %}
</div>
</div>
<!-- end general container -->

View File

@ -1,35 +1,14 @@
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-')
%}
{% set global_config = config["CONFIG"].get_config() %}
{% if current_endpoint == "services"%}
{% set plugins = [{
"id": "general",
"order": 999,
"name": "General",
"description": "The general settings for the server",
"version": "0.1",
"settings": {
"SERVER_NAME": {
"context": "multisite",
"default": "",
"help": "List of the virtual hosts served by bunkerweb.",
"id": "SERVER_NAME",
"label": "Server name",
"regex": ".*",
"type": "text",
}
}
}] + config["CONFIG"].get_plugins() %}
{% else %}
{% set plugins = config["CONFIG"].get_plugins() %}
{%endif%}
{% set plugins = config["CONFIG"].get_plugins() %}
<!-- plugin item -->
{% for plugin in plugins %}
<div
plugin-item="{{plugin['id']}}"
id="{{plugin['id']}}"
class="{% if current_endpoint == "global-config" or current_endpoint != "global-config" and loop.index != 1 %}hidden{%endif%} w-full"
class="{% if loop.index != 1 %}hidden{%endif%} w-full"
>
<!-- title and desc -->
<div class="col-span-12" setting-header>
@ -190,7 +169,6 @@
<!-- checkbox -->
{% if value["type"] == "check" %}
<div checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<input type="hidden" name="{{setting}}" value="no" default-value="no" default-method="default" />
<input id="{{setting}}" name="{{setting}}"
default-method="{{global_config[setting]['method']}}"
default-value="{{global_config[setting]['value']}}" {% if
@ -212,6 +190,7 @@
value="{% if global_config[setting]['value'] %}
{{global_config[setting]['value']}} {% else %} {{value['default']}} {% endif
%}" />
<input type="hidden" name="{{setting}}" value="no" default-value="no" default-method="default" />
<svg
checkbox-handler="{{value['id']}}"
class="pointer-events-none {% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} pointer-events-none {% else %} cursor-pointer {% endif %} absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"
@ -412,8 +391,6 @@
<!-- checkbox -->
{% if value["type"] == "check" %}
<div checkbox-handler="{{value['id']}}" class="relative mb-7 md:mb-0">
<input type="hidden" name="{{setting}}_SCHEMA" value="no" default-value="no" default-method="default" />
<input id="{{setting}}_SCHEMA" name="{{setting}}_SCHEMA"
default-method="{{global_config[setting]['method']}}"
default-value="{{global_config[setting]['value']}}" {% if
@ -435,6 +412,7 @@
value="{% if global_config[setting]['value'] %}
{{global_config[setting]['value']}} {% else %} {{value['default']}} {% endif
%}" />
<input type="hidden" name="{{setting}}_SCHEMA" value="no" default-value="no" default-method="default" />
<svg
checkbox-handler="{{value['id']}}"
class="pointer-events-none {% if global_config[setting]['method'] != 'ui' and global_config[setting]['method'] != 'default' %} pointer-events-none {% else %} cursor-pointer {% endif %} absolute fill-white dark:fill-gray-300 left-0 top-0 translate-x-1 translate-y-2 h-3 w-3"

View File

@ -1,66 +1,10 @@
{% set current_endpoint = url_for(request.endpoint)[1:].split("/")[-1].strip().replace('_', '-')
%}
{% if current_endpoint == "services"%}
{% set plugins = [{
"id": "general",
"order": 999,
"name": "General",
"description": "The general settings for the server",
"version": "0.1",
"settings": {
"SERVER_NAME": {
"context": "multisite",
"default": "",
"help": "List of the virtual hosts served by bunkerweb.",
"id": "SERVER_NAME",
"label": "Server name",
"regex": ".*",
"type": "text",
}
}
}] + config["CONFIG"].get_plugins() %}
{% else %}
{% set plugins = config["CONFIG"].get_plugins() %}
{%endif%}
{% set plugins = config["CONFIG"].get_plugins() %}
<div {{current_endpoint}}-tabs class="col-span-12 grid grid-cols-12 {% if current_endpoint == 'services' %}mb-4{% endif %}">
<!-- desktop tabs -->
<div {{current_endpoint}}-tabs-desktop class="hidden md:block col-span-12">
{% if current_endpoint != "services" %}
<!-- general tab -->
<button
tab-handler="general"
type="button"
class="brightness-90 border-primary dark:hover:bg-slate-800 dark:border-slate-600 dark:bg-slate-700 dark:text-gray-300 border my-1 relative inline-block px-3 py-3 font-bold text-center uppercase align-middle transition-all rounded-none cursor-pointer bg-white hover:bg-gray-100 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md"
>
<div class="w-full flex justify-between items-center">
<!-- text and icon -->
<span class="text-primary transition duration-300 ease-in-out dark:opacity-90 pl-3 pr-2 dark:text-gray-300">general</span>
<svg
popover-btn="general"
class="z-20 fill-blue-500 h-5 w-5 mr-2 hover:brightness-95"
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>
<!-- end text and icon -->
<!-- popover -->
<div
popover-content="general"
class="top-[60px] hidden transition z-50 rounded-md p-3 left-0 absolute bg-blue-500"
>
<p class="font-bold text-sm text-white m-0">
General config : HTTP, DNS, LOG, API...
</p>
</div>
<!-- end popover -->
</div>
</button>
<!-- end general tab-->
{% endif %}
<!-- tabs -->
{% for plugin in plugins %} {% if current_endpoint == "services" and plugin["settings"]
and check_settings(plugin["settings"], "multisite") or current_endpoint == "global-config" and plugin["settings"]
@ -68,7 +12,7 @@
<button
tab-handler="{{ plugin['id'] }}"
type="button"
class="z-1000 {% if current_endpoint != 'global-config' and loop.first %} brightness-90 {% endif %} border-primary dark:hover:bg-slate-800 dark:border-slate-600 dark:bg-slate-700 border my-1 relative inline-block px-3 py-3 font-bold text-center uppercase align-middle transition-all rounded-none cursor-pointer bg-white hover:bg-gray-100 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md"
class="z-1000 {% if loop.first %} brightness-90 {% endif %} border-primary dark:hover:bg-slate-800 dark:border-slate-600 dark:bg-slate-700 border my-1 relative inline-block px-3 py-3 font-bold text-center uppercase align-middle transition-all rounded-none cursor-pointer bg-white hover:bg-gray-100 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md"
>
<div class="w-full flex justify-between items-center">
<!-- text and icon -->