UI - introduced multiple config parameters (like reverse proxy) in frontend

This commit is contained in:
bunkerity 2020-12-27 14:42:52 +01:00
parent b5fe6335c7
commit f9b9b9546f
No known key found for this signature in database
GPG Key ID: 654FFF51CEF7CC47
9 changed files with 132 additions and 38 deletions

View File

@ -106,28 +106,38 @@
"default":"no"
},
{
"type":"text",
"label":"Reverse proxy url",
"env":"REVERSE_PROXY_URL",
"regex":".*",
"id":"reverse-proxy-url",
"default":""
},
{
"type":"text",
"label":"Reverse proxy host",
"env":"REVERSE_PROXY_HOST",
"regex":".*",
"id":"reverse-proxy-host",
"default":""
},
{
"type":"checkbox",
"label":"Reverse proxy ws",
"env":"REVERSE_PROXY_WS",
"regex":"^(yes|no)$",
"id":"reverse-proxy-ws",
"default":""
"type":"multiple",
"label":"Reverse proxy",
"id":"reverse-proxy-params",
"params":[
{
"type":"text",
"label":"Reverse proxy url",
"env":"REVERSE_PROXY_URL",
"regex":".*",
"id":"reverse-proxy-url",
"multiple":"Reverse proxy",
"default":""
},
{
"type":"text",
"label":"Reverse proxy host",
"env":"REVERSE_PROXY_HOST",
"regex":".*",
"id":"reverse-proxy-host",
"multiple":"Reverse proxy",
"default":""
},
{
"type":"checkbox",
"label":"Reverse proxy ws",
"env":"REVERSE_PROXY_WS",
"regex":"^(yes|no)$",
"id":"reverse-proxy-ws",
"multiple":"Reverse proxy",
"default":""
}
]
},
{
"type":"checkbox",

View File

@ -14,6 +14,8 @@ with open("/opt/entrypoint/config.json", "r") as f :
app.config["CONFIG"] = json.loads(f.read())
app.jinja_env.globals.update(env_to_summary_class=utils.env_to_summary_class)
app.jinja_env.globals.update(form_service_gen=utils.form_service_gen)
app.jinja_env.globals.update(form_service_gen_multiple=utils.form_service_gen_multiple)
app.jinja_env.globals.update(form_service_gen_multiple_values=utils.form_service_gen_multiple_values)
@app.route('/')
@app.route('/home')
@ -59,6 +61,8 @@ def services():
operation = ""
if request.method == "POST" :
print(request.form, flush=True)
# Check operation
if not "operation" in request.form or not request.form["operation"] in ["new", "edit", "delete"] :
return render_template("error.html", title="Error", error="Missing operation parameter on /services.")

View File

@ -29,7 +29,7 @@ function getData(id) {
for (var i = 0; i < elements.length; i++) {
element = elements[i];
if (element["type"] === "checkbox") {
if (element["value"] === "on") {
if (element["checked"]) {
data[element["name"]] = "yes";
}
else {
@ -78,3 +78,44 @@ function deleteInstance(id) {
post("delete", "instances", getData('form-instance-' + id));
return false;
}
var multiples = {};
function addMultiple(id, paramsEnc) {
var params = JSON.parse(paramsEnc);
var div = document.getElementById(id);
if (!multiples.hasOwnProperty(id)) {
multiples[id] = 0;
}
multiples[id]++;
for (var i = 0; i < params.length; i++) {
var input = "";
var input_id = id + "-" + params[i]["id"] + "-" + multiples[id].toString();
var input_name = params[i]["env"] + "_" + multiples[id].toString();
var input_label = params[i]["label"] + " #" + multiples[id].toString();
var input_value = params[i]["default"];
var pt = "";
if (params[i]["type"] == "text") {
input = `<input type="text" class="form-control" id="${input_id}" value="${input_value}" name="${input_name}">`;
}
else if (params[i]["type"] == "checkbox") {
if (input_value == "yes") {
input_value = "checked";
}
input = `<div class="form-check form-switch"><input type="checkbox" class="form-check-input" id="${input_id}" name="${input_name}" ${input_value}></div>`;
pt = "pt-0";
}
div.insertAdjacentHTML('beforeend', `<label for="${input_id}" class="col-4 col-form-label ${pt} mb-3" id="label-${input_id}">${input_label}</label><div class="col-8 mb-3" id="input-${input_id}">${input}</div>`);
}
}
function delMultiple(id, paramsEnc) {
if (multiples.hasOwnProperty(id) && multiples[id] > 0) {
var params = JSON.parse(paramsEnc);
for (var i = 0; i < params.length; i++) {
var input_id = id + "-" + params[i]["id"] + "-" + multiples[id].toString();
document.getElementById("label-" + input_id).remove();
document.getElementById("input-" + input_id).remove();
}
multiples[id]--;
}
}

View File

@ -1,3 +1,5 @@
{% set template_data = {"javascript": ""} %}
<!doctype html>
<html lang="en" class="h-100">

View File

@ -1,2 +1,5 @@
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/custom.js"></script>
<script>
{{ template_data.javascript|safe }}
</script>

View File

@ -13,7 +13,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger" onClick="deleteInstance('{{ id_server_name }}');">Delete</button>
<button type="button" class="btn btn-danger" onClick="deleteService('{{ id_server_name }}');">Delete</button>
</div>
</div>
</div>

View File

@ -23,7 +23,15 @@
{% for k, v in config["CONFIG"].items() %}
<div class="tab-pane fade {{ check.class }}" id="edit-{{ v["id"] }}-{{ id_server_name }}" role="tabpanel" aria-labelledby="edit-{{ v["id"] }}-{{ id_server_name }}-tab">
{% for param in v["params"] %}
{{ form_service_gen("edit", id_server_name, param["id"], param["label"], param["type"], service[param["env"]], param["env"])|safe }}
<div class="row mb-3" id="form-edit-{{ id_server_name }}-{{ param["id"] }}">
{% if param["type"] != "multiple" %}
{{ form_service_gen("form-edit-" + id_server_name + "-" + param["id"], param["label"], param["type"], service[param["env"]], param["env"])|safe }}
{% else %}
{{ form_service_gen_multiple("form-edit-" + id_server_name + "-" + param["id"], param["label"], param["params"])|safe }}
{% if template_data.update({"javascript": template_data.javascript + form_service_gen_multiple_values("form-edit-" + id_server_name + "-" + param["id"], param["params"], service)}) %}
{% endif %}
{% endif %}
</div>
{% endfor %}
</div>
{% if check.update({"class": ""}) %}
@ -34,7 +42,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onClick="editInstance('{{ id_server_name }}');">Save</button>
<button type="button" class="btn btn-primary" onClick="editService('{{ id_server_name }}');">Save</button>
</div>
</div>
</div>

View File

@ -22,7 +22,13 @@
{% for k, v in config["CONFIG"].items() %}
<div class="tab-pane fade {{ check.class }}" id="new-{{ v["id"] }}" role="tabpanel" aria-labelledby="new-{{ v["id"] }}-tab">
{% for param in v["params"] %}
{{ form_service_gen("new", "", param["id"], param["label"], param["type"], param["default"], param["env"])|safe }}
<div class="row mb-3" id="form-new-{{ param["id"] }}">
{% if param["type"] != "multiple" %}
{{ form_service_gen("form-new-" + param["id"], param["label"], param["type"], param["default"], param["env"])|safe }}
{% else %}
{{ form_service_gen_multiple("form-new-" + param["id"], param["label"], param["params"])|safe }}
{% endif %}
</div>
{% endfor %}
</div>
{% if check.update({"class": ""}) %}
@ -33,7 +39,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onClick="newInstance();">Save</button>
<button type="button" class="btn btn-primary" onClick="newService();">Save</button>
</div>
</div>
</div>

View File

@ -1,6 +1,6 @@
#!/usr/bin/python3
import datetime, re
import datetime, re, json
def log(event) :
print("[" + str(datetime.datetime.now().replace(microsecond=0)) + "] " + event, flush=True)
@ -24,18 +24,38 @@ def env_to_summary_class(var, value) :
return "check text-success"
return "times text-danger"
def form_service_gen(form, server, id, label, type, value, name) :
if form == "edit" :
new_id = "form-edit-" + server + "-" + id
elif form == "new" :
new_id = "form-new-" + id
def form_service_gen(id, label, type, value, name) :
pt = ""
if type == "text" :
input = '<input type="%s" class="form-control" id="%s" value="%s" name="%s">' % (type, new_id, value, name)
pt = ""
input = '<input type="%s" class="form-control" id="%s" value="%s" name="%s">' % (type, id, value, name)
elif type == "checkbox" :
checked = ""
if value == "yes" :
checked = "checked"
input = '<div class="form-check form-switch"><input type="%s" class="form-check-input" id="%s" name="%s" %s></div>' % (type, new_id, name, checked)
input = '<div class="form-check form-switch"><input type="%s" class="form-check-input" id="%s" name="%s" %s></div>' % (type, id, name, checked)
pt = "pt-0"
return '<div class="row mb-3"><label for="%s" class="col-4 col-form-label %s">%s</label><div class="col-8">%s</div></div>' % (new_id, pt, label, input)
return '<label for="%s" class="col-4 col-form-label %s">%s</label><div class="col-8">%s</div>' % (id, pt, label, input)
def form_service_gen_multiple(id, label, params) :
buttons = '<button class="btn btn-success" type="button" onClick="addMultiple(\'%s\', \'%s\');"><i class="fas fa-plus"></i> Add</button> <button class="btn btn-danger" type="button" onClick="delMultiple(\'%s\', \'%s\')"><i class="fas fa-trash"></i> Del</button>' % (id, json.dumps(params).replace("\"", "&quot;"), id, json.dumps(params).replace("\"", "&quot;"))
return '<label for="%s" class="col-4 col-form-label mb-3">%s</label><div class="col-8 mb-3" id="%s">%s</div>' % (id + "-btn", label, id + "-btn", buttons)
def form_service_gen_multiple_values(id, params, service) :
values = []
for env in service :
if env.startswith(params[0]["env"]) :
suffix = env.replace(params[0]["env"], "")
for param in params :
value = {}
value["id"] = param["id"]
value["env"] = param["env"]
value["label"] = param["label"]
value["type"] = param["type"]
if param["env"] + suffix in service :
value["default"] = service[param["env"] + suffix]
else :
value["default"] = param["default"]
values.append(value)
if len(values) > 0 :
return "addMultiple('%s', '%s'); " % (id, json.dumps(values))
return ""