mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
start handling multiple settings
This commit is contained in:
parent
a5d504df3a
commit
6d2905c392
12 changed files with 9239 additions and 27 deletions
File diff suppressed because one or more lines are too long
|
|
@ -3002,13 +3002,21 @@ plugins = [
|
|||
},
|
||||
]
|
||||
|
||||
template_settings = {"ERRORS": "", "USE_UI": "no", "USE_CORS": "no"}
|
||||
template_settings = {
|
||||
"ERRORS": "",
|
||||
"USE_UI": "no",
|
||||
"USE_CORS": "no",
|
||||
"REVERSE_PROXY_HOST_1": "template1",
|
||||
"REVERSE_PROXY_HOST_2": "template2",
|
||||
}
|
||||
|
||||
# Service settings
|
||||
service_settings = {
|
||||
"ERRORS": {"value": "", "global": True, "method": "scheduler"},
|
||||
"USE_UI": {"value": "yes", "global": True, "method": "ui"},
|
||||
"USE_CORS": {"value": "yes", "global": True, "method": "scheduler"},
|
||||
"REVERSE_PROXY_HOST_1": {"value": "service1", "global": True, "method": "ui"},
|
||||
"REVERSE_PROXY_HOST": {"value": "service", "global": True, "method": "ui"},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3106,7 +3114,7 @@ def set_raw(template, plugins_base, service_settings):
|
|||
for plugin in plugins:
|
||||
for setting, value in plugin.get("settings").items():
|
||||
# avoid some methods from services_settings
|
||||
if setting in service_settings and service_settings[setting].get("method", "ui") not in ("ui", "default"):
|
||||
if setting in service_settings and service_settings[setting].get("method", "ui") not in ("ui", "default", "manual"):
|
||||
continue
|
||||
|
||||
raw_value = False
|
||||
|
|
@ -3150,12 +3158,20 @@ def set_advanced(template, plugins_base, service_settings):
|
|||
service_settings,
|
||||
)
|
||||
|
||||
set_multiples(plugins)
|
||||
set_multiples(template, plugins, service_settings)
|
||||
|
||||
return plugins
|
||||
|
||||
|
||||
def set_multiples(format_plugins):
|
||||
def get_multiple_from_template(template, plugins):
|
||||
pass
|
||||
|
||||
|
||||
def get_multiple_from_settings(template, settings):
|
||||
pass
|
||||
|
||||
|
||||
def set_multiples(template, format_plugins, service_settings):
|
||||
"""
|
||||
Set the multiples settings for each plugin.
|
||||
"""
|
||||
|
|
@ -3166,10 +3182,17 @@ def set_multiples(format_plugins):
|
|||
# Get multiples
|
||||
multiples = {}
|
||||
settings_to_delete = []
|
||||
total_settings = len(plugin.get("settings"))
|
||||
zindex = 0
|
||||
for setting, value in plugin.get("settings").items():
|
||||
|
||||
if not value.get("multiple"):
|
||||
continue
|
||||
|
||||
zindex += 1
|
||||
|
||||
value["containerClass"] = f"z-{total_settings - zindex}"
|
||||
|
||||
mult_name = value.get("multiple")
|
||||
# Get the multiple value and set it as key if not in multiples dict
|
||||
if mult_name not in multiples:
|
||||
|
|
@ -3182,9 +3205,20 @@ def set_multiples(format_plugins):
|
|||
for setting in settings_to_delete:
|
||||
del plugin["settings"][setting]
|
||||
|
||||
# Case all settings are disabled or at least one setting has a method different than "ui" or "default" or "manual"
|
||||
# we need to add key "removeDisabled" to True
|
||||
for setting, value in multiples.items():
|
||||
if all([v.get("disabled") for v in value.values()]) or any([v.get("method") not in ("ui", "default", "manual") for v in value.values()]):
|
||||
plugin["removeDisabled"] = True
|
||||
|
||||
if len(multiples):
|
||||
plugin["multiples"].update(multiples)
|
||||
|
||||
# Now that we have for each plugin the multiples settings, we need to do the following
|
||||
# get all settings from template that are multiples
|
||||
# get all settings from service settings / global config that are multiples
|
||||
# separate them per multiple group (no prefix, _1, _2, etc.)
|
||||
|
||||
return format_plugins
|
||||
|
||||
|
||||
|
|
@ -3197,10 +3231,14 @@ def format_setting(
|
|||
service_settings,
|
||||
):
|
||||
"""
|
||||
Format a setting in ordert to be used with form builder.
|
||||
Format a setting in order to be used with form builder.
|
||||
This will only set value for none multiple settings.
|
||||
Additionnel set_multiples function will handle multiple settings.
|
||||
"""
|
||||
# add zindex for container
|
||||
setting_value["containerClass"] = f"z-{total_settings - loop_id}"
|
||||
# add zindex for field in case not a multiple
|
||||
# Case multiple, this will be set on the group level
|
||||
if not "multiple" in setting_value:
|
||||
setting_value["containerClass"] = f"z-{total_settings - loop_id}"
|
||||
|
||||
# regex by pattern
|
||||
setting_value["pattern"] = setting_value.get("regex", "")
|
||||
|
|
@ -3230,19 +3268,24 @@ def format_setting(
|
|||
setting_value["value"] = setting_value.get("default")
|
||||
|
||||
# Start by setting template value if exists
|
||||
if setting_name in template_settings:
|
||||
if setting_name in template_settings and not "multiple" in setting_value:
|
||||
# Update value or set default as value
|
||||
setting_value["value"] = template_settings.get(setting_name, setting_value.get("default"))
|
||||
|
||||
# Then override by service settings if not a multiple
|
||||
# Case multiple, we need to keep the default value and override only each multiple group
|
||||
if setting_name in service_settings and not "multiple" in setting_value:
|
||||
setting_value["value"] = service_settings[setting_name].get("value", setting_value.get("value", setting_value.get("default")))
|
||||
setting_value["method"] = service_settings[setting_name].get("method", "ui")
|
||||
|
||||
# Then override by service settings
|
||||
if setting_name in service_settings:
|
||||
setting_value["value"] = service_settings[setting_name].get("value", setting_value.get("value", setting_value.get("default")))
|
||||
setting_value["disabled"] = False if service_settings[setting_name].get("method", "ui") in ("ui", "default") else True
|
||||
setting_value["disabled"] = False if service_settings[setting_name].get("method", "ui") in ("ui", "default", "manual") else True
|
||||
|
||||
# Prepare popover checking "help", "context"
|
||||
popovers = []
|
||||
|
||||
if (setting_value.get("disabled", False)) and service_settings[setting_name].get("method", "ui") not in ("ui", "default"):
|
||||
if (setting_value.get("disabled", False)) and service_settings[setting_name].get("method", "ui") not in ("ui", "default", "manual"):
|
||||
popovers.append(
|
||||
{
|
||||
"iconName": "trespass",
|
||||
|
|
@ -3301,7 +3344,7 @@ def global_config_builder():
|
|||
|
||||
|
||||
output = global_config_builder()
|
||||
with open("globalconfig64.txt", "w") as f:
|
||||
with open("globalconfig.json", "w") as f:
|
||||
json.dump(output, f, indent=4)
|
||||
|
||||
output_base64_bytes = base64.b64encode(bytes(json.dumps(output), "utf-8"))
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -532,6 +532,15 @@ body {
|
|||
@apply py-4 sm:gap-x-8 gap-y-8 col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
||||
.layout-settings-multiple {
|
||||
@apply py-5 col-span-12 grid grid-cols-12 w-full relative;
|
||||
}
|
||||
|
||||
.layout-settings-multiple-group {
|
||||
@apply mt-4 rounded border border-gray-500/50 dark:border-gray-500 p-4 sm:gap-x-8 gap-y-8 col-span-12 grid grid-cols-12 w-full relative bg-gray-200/50 dark:bg-gray-800/80;
|
||||
}
|
||||
|
||||
|
||||
/* MESSAGE */
|
||||
.msg-container {
|
||||
@apply col-span-12 w-full;
|
||||
|
|
@ -1122,16 +1131,21 @@ body {
|
|||
|
||||
/* BTN GROUP */
|
||||
|
||||
.button-group-default {
|
||||
@apply flex justify-center items-center;
|
||||
|
||||
.button-group-content {
|
||||
@apply flex justify-center items-center mx-4;
|
||||
}
|
||||
|
||||
.button-group-multiple {
|
||||
@apply flex justify-center items-center mx-4;
|
||||
}
|
||||
|
||||
.button-group-instance {
|
||||
@apply flex justify-end items-center;
|
||||
@apply flex justify-end items-center mx-4;
|
||||
}
|
||||
|
||||
.button-group-modal {
|
||||
@apply flex justify-center items-center mt-4;
|
||||
@apply flex justify-center items-center mt-4 mx-4;
|
||||
}
|
||||
|
||||
/* LIST COMPONENT */
|
||||
|
|
@ -1274,6 +1288,10 @@ body {
|
|||
@apply capitalize-first break-word dark:text-gray-300 col-span-12 break-words w-full max-w-[80%] sm:max-w-[600px] font-bold leading-normal text-sm mb-0 lowercase;
|
||||
}
|
||||
|
||||
.subtitle-multiple {
|
||||
@apply capitalize-first break-word dark:text-gray-300 col-span-12 break-words max-w-[80%] sm:max-w-[600px] font-bold leading-normal text-sm mb-0 lowercase;
|
||||
}
|
||||
|
||||
/* STAT COMPONENT */
|
||||
|
||||
.stat-content-container.no-icon {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -9,7 +9,9 @@ import Combobox from "@components/Forms/Field/Combobox.vue";
|
|||
import Button from "@components/Widget/Button.vue";
|
||||
import Text from "@components/Widget/Text.vue";
|
||||
import Filter from "@components/Widget/Filter.vue";
|
||||
import GroupMultiple from "@components/Forms/Group/Multiple.vue";
|
||||
import { plugin_types } from "@utils/variables";
|
||||
|
||||
import {
|
||||
useCheckPluginsValidity,
|
||||
useUpdateTempSettings,
|
||||
|
|
@ -197,13 +199,6 @@ const filters = [
|
|||
},
|
||||
];
|
||||
|
||||
const unmatch = {
|
||||
text: "dashboard_no_match",
|
||||
icon: {
|
||||
iconName: "search",
|
||||
},
|
||||
};
|
||||
|
||||
function filter(filterData) {
|
||||
setValidity();
|
||||
data.format = filterData;
|
||||
|
|
@ -306,6 +301,7 @@ onUnmounted(() => {
|
|||
<Fields :setting="setting" />
|
||||
</template>
|
||||
</Container>
|
||||
<GroupMultiple v-if="plugin.multiples" :multiples="plugin.multiples" />
|
||||
</Container>
|
||||
</template>
|
||||
<Button
|
||||
|
|
|
|||
128
src/client/vite/src/components/Forms/Group/Multiple.vue
Normal file
128
src/client/vite/src/components/Forms/Group/Multiple.vue
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
<script setup>
|
||||
import { reactive, defineProps } from "vue";
|
||||
import { contentIndex } from "@utils/tabindex.js";
|
||||
import ButtonGroup from "@components/Widget/ButtonGroup.vue";
|
||||
import Fields from "@components/Form/Fields.vue";
|
||||
import Subtitle from "@components/Widget/Subtitle.vue";
|
||||
import Container from "@components/Widget/Container.vue";
|
||||
|
||||
/**
|
||||
@name Forms/Group/Multiple.vue
|
||||
@description This Will regroup all multiples settings with add and remove logic.
|
||||
This component under the hood is rendering default fields but by group with possibility to add or remove a multiple group.
|
||||
@example
|
||||
{
|
||||
"columns": {"pc": 6, "tablet": 12, "mobile": 12},
|
||||
"multiples": {
|
||||
"custom-headers": {
|
||||
"CUSTOM_HEADER": {
|
||||
"context": "multisite",
|
||||
"default": "",
|
||||
"help": "Custom header to add (HeaderName: HeaderValue).",
|
||||
"id": "custom-header",
|
||||
"label": "Custom header (HeaderName: HeaderValue)",
|
||||
"regex": "^([\\w\\-]+: .+)?$",
|
||||
"type": "text",
|
||||
"multiple": "custom-headers",
|
||||
"containerClass": "z-13",
|
||||
"pattern": "^([\\w\\-]+: .+)?$",
|
||||
"inpType": "input",
|
||||
"name": "Custom header (HeaderName: HeaderValue)",
|
||||
"columns": {
|
||||
"pc": 4,
|
||||
"tablet": 6,
|
||||
"mobile": 12
|
||||
},
|
||||
"disabled": false,
|
||||
"value": "",
|
||||
"popovers": [
|
||||
{
|
||||
"iconName": "disk",
|
||||
"text": "inp_popover_multisite"
|
||||
},
|
||||
{
|
||||
"iconName": "info",
|
||||
"text": "Custom header to add (HeaderName: HeaderValue)."
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
@param {object<object>} multiples - The multiples settings to display. This needs to be a dict of settings using default field format.
|
||||
@param {object} [columns={"pc": "12", "tablet": "12", "mobile": "12}] - Field has a grid system. This allow to get multiple field in the same row if needed.
|
||||
@param {string} [containerClass=""] - Additionnal class to add to the container
|
||||
@param {string} [tadId=contentIndex] - The tabindex of the field, by default it is the contentIndex
|
||||
*/
|
||||
|
||||
const props = defineProps({
|
||||
// id && value && method
|
||||
multiples: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "",
|
||||
},
|
||||
columns: {
|
||||
type: [Object, Boolean],
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
containerClass: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "",
|
||||
},
|
||||
tabId: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: contentIndex,
|
||||
},
|
||||
});
|
||||
|
||||
const multiples = reactive({
|
||||
// Store value of multiple group
|
||||
// By default, all multiples are visible
|
||||
// But when clicking toggle, we can hide them by removing the key from the array
|
||||
visible: [],
|
||||
});
|
||||
|
||||
const buttonAdd = {
|
||||
text: "action_add",
|
||||
color: "success",
|
||||
size: "normal",
|
||||
type: "button",
|
||||
containerClass: "flex justify-center",
|
||||
};
|
||||
|
||||
const buttonToggle = {
|
||||
text: "action_toggle",
|
||||
color: "info",
|
||||
size: "normal",
|
||||
type: "button",
|
||||
containerClass: "flex justify-center",
|
||||
};
|
||||
|
||||
function addGroup() {}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-for="(multObj, multName, id) in props.multiples">
|
||||
{{ id }}
|
||||
<Container
|
||||
data-is="multiple"
|
||||
class="layout-settings-multiple"
|
||||
:columns="props.columns"
|
||||
:containerClass="props.containerClass"
|
||||
>
|
||||
<Container class="col-span-12 flex items-center">
|
||||
<Subtitle :subtitle="multName.replaceAll('-', ' ')" />
|
||||
<ButtonGroup :buttons="[buttonAdd, buttonToggle]" />
|
||||
</Container>
|
||||
|
||||
<Container class="layout-settings-multiple-group">
|
||||
<template v-for="(setting, value) in props.multiples[multName]">
|
||||
<Fields :setting="setting" :tabId="props.tabId" />
|
||||
</template>
|
||||
</Container>
|
||||
</Container>
|
||||
</template>
|
||||
</template>
|
||||
|
|
@ -90,6 +90,7 @@ onMounted(() => {
|
|||
'text-el',
|
||||
props.bold ? 'bold' : '',
|
||||
props.uppercase ? 'uppercase' : '',
|
||||
props.subtitleClass,
|
||||
]"
|
||||
>
|
||||
{{ $t(props.subtitle, $t("dashboard_placeholder", props.subtitle)) }}
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@
|
|||
"action_delete_all": "delete all {name}",
|
||||
"action_previous": "previous",
|
||||
"action_next": "next",
|
||||
"action_toggle": "toggle {name}",
|
||||
"home_version": "version",
|
||||
"home_all_features_available": "all features are available",
|
||||
"home_awaiting_compliance": "awaiting compliance",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -238,6 +238,7 @@ export default {
|
|||
"lg:p-2",
|
||||
"scale-90",
|
||||
"scale-95",
|
||||
"w-fit",
|
||||
],
|
||||
important: true,
|
||||
darkMode: "class",
|
||||
|
|
|
|||
|
|
@ -1406,6 +1406,7 @@ def global_config():
|
|||
|
||||
# Display global config
|
||||
global_config = app.config["DB"].get_config(global_only=True, methods=True)
|
||||
print(global_config, flush=True)
|
||||
return render_template("global_config.html", global_config=global_config, dumped_global_config=dumps(global_config))
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue