Commit 70abed28 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_jio: Implement read-only mode for parameter form

  This is equivalent to editable equal to false when render the gadget field.
parent 1e99a9aa
...@@ -72,8 +72,8 @@ ...@@ -72,8 +72,8 @@
); );
} }
function render_selection(json_field, default_value, is_required) { function render_selection(json_field, default_value, is_required, editable) {
var property_dict = {size: 1}, var input,
option_list = [domsugar('option', { option_list = [domsugar('option', {
value: "", value: "",
selected: (default_value === undefined) selected: (default_value === undefined)
...@@ -81,7 +81,12 @@ ...@@ -81,7 +81,12 @@
option_index, option_index,
selected, selected,
is_selected = (default_value === undefined), is_selected = (default_value === undefined),
data_format = "string"; data_format = "string",
property_dict = {
size: 1,
"placeholder": " ",
"class": "slapos-parameter"
};
if (json_field.type === "integer" || json_field.type === "number") { if (json_field.type === "integer" || json_field.type === "number") {
data_format = "number"; data_format = "number";
...@@ -118,14 +123,27 @@ ...@@ -118,14 +123,27 @@
if (is_required) { if (is_required) {
property_dict.required = true; property_dict.required = true;
} }
return domsugar('select', property_dict, option_list);
input = domsugar('select', property_dict, option_list);
if (!editable) {
input.classList.add("readonly");
input["aria-disabled"] = "true";
input["tab-index"] = "-1";
}
return input;
} }
function render_selection_oneof(json_field, default_value, is_required) { function render_selection_oneof(json_field, default_value, is_required, editable) {
var option_list = [domsugar('option', { var input,
value: "", option_list = [domsugar('option', {
selected: (default_value === undefined) value: "",
})]; selected: (default_value === undefined)
})],
property_dict = {
size: 1,
"placeholder": " ",
"class": "slapos-parameter"
};
json_field.oneOf.forEach(function (element) { json_field.oneOf.forEach(function (element) {
if ((element['const'] !== undefined) && (element.title !== undefined)) { if ((element['const'] !== undefined) && (element.title !== undefined)) {
...@@ -143,14 +161,24 @@ ...@@ -143,14 +161,24 @@
})); }));
} }
}); });
if (is_required) {
return domsugar('select', { property_dict.required = true;
size: 1 }
}, option_list); input = domsugar('select', property_dict, option_list);
if (!editable) {
input.classList.add("readonly");
input["aria-disabled"] = "true";
input["tab-index"] = "-1";
}
return input;
} }
function render_textarea(json_field, default_value, data_format, is_required) { function render_textarea(json_field, default_value, data_format, is_required, editable) {
var property_dict = {"data-format": data_format}; var input, property_dict = {
"data-format": data_format,
"placeholder": " ",
"class": "slapos-parameter"
};
if (default_value !== undefined) { if (default_value !== undefined) {
if (default_value instanceof Array) { if (default_value instanceof Array) {
property_dict.value = default_value.join("\n"); property_dict.value = default_value.join("\n");
...@@ -161,17 +189,23 @@ ...@@ -161,17 +189,23 @@
if (is_required) { if (is_required) {
property_dict.required = true; property_dict.required = true;
} }
return domsugar('textarea', property_dict); input = domsugar('textarea', property_dict);
if (!editable) {
input.setAttribute('readonly', true);
}
return input;
} }
function render_field(json_field, default_value, is_required) { function render_field(json_field, default_value, is_required, editable) {
var data_format, domsugar_input_dict = {}; var input,
data_format,
domsugar_input_dict = {"placeholder": " ", "class": "slapos-parameter"};
if (json_field['enum'] !== undefined) { if (json_field['enum'] !== undefined) {
return render_selection(json_field, default_value, is_required); return render_selection(json_field, default_value, is_required, editable);
} }
if (json_field.oneOf !== undefined) { if (json_field.oneOf !== undefined) {
return render_selection_oneof(json_field, default_value, is_required); return render_selection_oneof(json_field, default_value, is_required, editable);
} }
if (json_field.type === "boolean") { if (json_field.type === "boolean") {
...@@ -182,7 +216,7 @@ ...@@ -182,7 +216,7 @@
if (default_value === "false") { if (default_value === "false") {
default_value = false; default_value = false;
} }
return render_selection(json_field, default_value, is_required); return render_selection(json_field, default_value, is_required, editable);
} }
if (json_field.type === "array") { if (json_field.type === "array") {
...@@ -192,11 +226,11 @@ ...@@ -192,11 +226,11 @@
data_format = "array-number"; data_format = "array-number";
} }
} }
return render_textarea(json_field, default_value, data_format, is_required); return render_textarea(json_field, default_value, data_format, is_required, editable);
} }
if (json_field.type === "string" && json_field.textarea === true) { if (json_field.type === "string" && json_field.textarea === true) {
return render_textarea(json_field, default_value, "string", is_required); return render_textarea(json_field, default_value, "string", is_required, editable);
} }
if (default_value !== undefined) { if (default_value !== undefined) {
...@@ -217,11 +251,14 @@ ...@@ -217,11 +251,14 @@
if (is_required) { if (is_required) {
domsugar_input_dict.required = true; domsugar_input_dict.required = true;
} }
input = domsugar('input', domsugar_input_dict);
return domsugar('input', domsugar_input_dict); if (!editable) {
input.setAttribute('readonly', true);
}
return input;
} }
function render_subform(json_field, default_dict, root, path) { function render_subform(json_field, default_dict, root, path, editable) {
var div_input, var div_input,
key, key,
div, div,
...@@ -240,7 +277,7 @@ ...@@ -240,7 +277,7 @@
path = "/"; path = "/";
} }
if (json_field.patternProperties !== undefined) { if (editable && json_field.patternProperties !== undefined) {
if (json_field.patternProperties['.*'] !== undefined) { if (json_field.patternProperties['.*'] !== undefined) {
div = domsugar("div", { div = domsugar("div", {
...@@ -288,7 +325,8 @@ ...@@ -288,7 +325,8 @@
json_field.patternProperties['.*'], json_field.patternProperties['.*'],
default_dict[default_value], default_dict[default_value],
default_div, default_div,
path + "/" + default_value path + "/" + default_value,
editable
)); ));
} }
} }
...@@ -322,45 +360,46 @@ ...@@ -322,45 +360,46 @@
for (key in json_field.properties) { for (key in json_field.properties) {
if (json_field.properties.hasOwnProperty(key)) { if (json_field.properties.hasOwnProperty(key)) {
label = domsugar("label", { if (editable || default_dict[key] !== undefined) {
'text': json_field.properties[key].title label = domsugar("label", {
}); 'text': json_field.properties[key].title
});
is_required = false; is_required = false;
if ((Array.isArray(json_field.required)) && (json_field.required.includes(key))) { if ((Array.isArray(json_field.required)) && (json_field.required.includes(key))) {
is_required = true; is_required = true;
} }
if (json_field.properties[key].type === 'object') { if (json_field.properties[key].type === 'object') {
label.setAttribute("class", "slapos-parameter-dict-key"); label.setAttribute("class", "slapos-parameter-dict-key");
div_input = render_subform(json_field.properties[key], div_input = render_subform(json_field.properties[key],
default_dict[key], default_dict[key],
domsugar("div", {"class": "input"}), domsugar("div", {"class": "input"}),
path + "/" + key); path + "/" + key,
} else { editable);
input = render_field( } else {
json_field.properties[key], input = render_field(
default_dict[key], json_field.properties[key],
is_required default_dict[key],
); is_required,
input.name = path + "/" + key; editable
input.setAttribute("class", "slapos-parameter"); );
input.setAttribute("placeholder", " "); input.name = path + "/" + key;
div_input = domsugar("div", {"class": "input"}, [input]); div_input = domsugar("div", {"class": "input"}, [input]);
} }
default_used_list.push(key); default_used_list.push(key);
if (json_field.properties[key]['default'] !== undefined) { if (json_field.properties[key]['default'] !== undefined) {
div_input.appendChild( div_input.appendChild(
domsugar("span", domsugar("span",
{'text': '(default = ' + json_field.properties[key]['default'] + ')'}) {'text': '(default = ' + json_field.properties[key]['default'] + ')'})
);
}
div_input.appendChild(domsugar("span", {'class': 'error'}));
root.appendChild(
domsugar("div", {
"class": "subfield",
title: json_field.properties[key].description
}, [label, div_input])
); );
} }
div_input.appendChild(domsugar("span", {'class': 'error'}));
root.appendChild(
domsugar("div", {
"class": "subfield",
title: json_field.properties[key].description
}, [label, div_input])
);
} }
} }
for (key in default_dict) { for (key in default_dict) {
...@@ -379,10 +418,8 @@ ...@@ -379,10 +418,8 @@
editable) editable)
]); ]);
} else { } else {
input = render_field({"type": "string", "textarea": true}, default_dict[key], false); input = render_field({"type": "string", "textarea": true}, default_dict[key], false, editable);
input.name = path + "/" + key; input.name = path + "/" + key;
input.setAttribute("class", "slapos-parameter");
input.setAttribute("placeholder", " ");
div = domsugar("div", { div = domsugar("div", {
title: key, title: key,
"class": "subfield" "class": "subfield"
...@@ -683,6 +720,7 @@ ...@@ -683,6 +720,7 @@
var fieldset, var fieldset,
fieldset_list = g.element.querySelectorAll('fieldset'), fieldset_list = g.element.querySelectorAll('fieldset'),
div_error, div_error,
textarea,
show_raw_button = g.element.querySelector("button.slapos-show-raw-parameter"), show_raw_button = g.element.querySelector("button.slapos-show-raw-parameter"),
show_form_button = g.element.querySelector("button.slapos-show-form"); show_form_button = g.element.querySelector("button.slapos-show-form");
...@@ -715,16 +753,20 @@ ...@@ -715,16 +753,20 @@
} else { } else {
div_error = domsugar('div'); div_error = domsugar('div');
} }
textarea = domsugar('textarea', {
rows: "10",
cols: "80",
name: "text_content",
text: g.state.parameter_xml
});
if (!g.state.editable) {
textarea.setAttribute("readonly", true);
}
fieldset = domsugar('fieldset', [ fieldset = domsugar('fieldset', [
domsugar('div', { domsugar('div', {
'class': 'field' 'class': 'field'
}, [ }, [
domsugar('textarea', { textarea
rows: "10",
cols: "80",
name: "text_content",
text: g.state.parameter_xml
})
]), ]),
// div error // div error
div_error div_error
...@@ -748,6 +790,7 @@ ...@@ -748,6 +790,7 @@
shared = gadget.state.shared, shared = gadget.state.shared,
softwaretype = gadget.state.softwaretype, softwaretype = gadget.state.softwaretype,
softwareindex = gadget.state.softwareindex, softwareindex = gadget.state.softwareindex,
editable = gadget.state.editable,
to_hide = gadget.element.querySelector("button.slapos-show-form"), to_hide = gadget.element.querySelector("button.slapos-show-form"),
to_show = gadget.element.querySelector("button.slapos-show-raw-parameter"); to_show = gadget.element.querySelector("button.slapos-show-raw-parameter");
...@@ -776,7 +819,7 @@ ...@@ -776,7 +819,7 @@
lowest_index = 999, lowest_index = 999,
lowest_option_index; lowest_option_index;
if (restricted_softwaretype === true) { if (!editable || restricted_softwaretype === true) {
input.classList.add("readonly"); input.classList.add("readonly");
input["aria-disabled"] = "true"; input["aria-disabled"] = "true";
input["tab-index"] = "-1"; input["tab-index"] = "-1";
...@@ -812,7 +855,7 @@ ...@@ -812,7 +855,7 @@
}); });
option['data-id'] = option_index; option['data-id'] = option_index;
option['data-index'] = 999; option['data-index'] = 999;
option['data-shared'] = json['software-type'][option_index].shared option['data-shared'] = json['software-type'][option_index].shared;
if (json['software-type'][option_index]['software-type'] !== undefined) { if (json['software-type'][option_index]['software-type'] !== undefined) {
option.value = json['software-type'][option_index]['software-type']; option.value = json['software-type'][option_index]['software-type'];
...@@ -958,7 +1001,7 @@ ...@@ -958,7 +1001,7 @@
var fieldset_list = gadget.element.querySelectorAll('fieldset'), var fieldset_list = gadget.element.querySelectorAll('fieldset'),
fieldset = document.createElement("fieldset"); fieldset = document.createElement("fieldset");
fieldset = render_subform(json, parameter_dict, fieldset, undefined); fieldset = render_subform(json, parameter_dict, fieldset, undefined, editable);
fieldset_list[1].parentNode.replaceChild( fieldset_list[1].parentNode.replaceChild(
fieldset, fieldset,
fieldset_list[1] fieldset_list[1]
...@@ -1033,7 +1076,6 @@ ...@@ -1033,7 +1076,6 @@
return this.changeState({ return this.changeState({
// Not used parameters // Not used parameters
// editable: options.editable,
// hidden: options.hidden, // hidden: options.hidden,
// key: options.key, // key: options.key,
serialisation: options.serialisation, serialisation: options.serialisation,
...@@ -1043,6 +1085,7 @@ ...@@ -1043,6 +1085,7 @@
shared: options.value.parameter.shared, shared: options.value.parameter.shared,
softwaretype: options.value.parameter.softwaretype, softwaretype: options.value.parameter.softwaretype,
softwareindex: options.value.parameter.softwareindex, softwareindex: options.value.parameter.softwareindex,
editable: options.editable,
// Force refresh in any case // Force refresh in any case
render_timestamp: new Date().getTime() render_timestamp: new Date().getTime()
}); });
...@@ -1065,6 +1108,7 @@ ...@@ -1065,6 +1108,7 @@
return updateParameterForm(gadget); return updateParameterForm(gadget);
} }
// @ts-ignore
if (evt.target.className.indexOf("slapos-parameter") !== -1) { if (evt.target.className.indexOf("slapos-parameter") !== -1) {
// getContent is protected by a mutex which prevent // getContent is protected by a mutex which prevent
// onchangestate to be called in parallel // onchangestate to be called in parallel
...@@ -1077,14 +1121,17 @@ ...@@ -1077,14 +1121,17 @@
// Only handle click on BUTTON element // Only handle click on BUTTON element
var gadget = this, var gadget = this,
queue, queue,
// @ts-ignore
tag_name = evt.target.tagName; tag_name = evt.target.tagName;
if ((tag_name === 'LABEL') && if ((tag_name === 'LABEL') &&
// @ts-ignore
(evt.target.className.indexOf("slapos-parameter-dict-key") !== -1)) { (evt.target.className.indexOf("slapos-parameter-dict-key") !== -1)) {
return collapseParameter(evt.target); return collapseParameter(evt.target);
} }
if ((tag_name === 'SPAN') && if ((tag_name === 'SPAN') &&
// @ts-ignore
(evt.target.className.indexOf("bt_close") !== -1)) { (evt.target.className.indexOf("bt_close") !== -1)) {
return removeSubParameter(evt.target); return removeSubParameter(evt.target);
} }
...@@ -1099,6 +1146,7 @@ ...@@ -1099,6 +1146,7 @@
queue = gadget.getContent(); queue = gadget.getContent();
if ((tag_name === 'BUTTON') && if ((tag_name === 'BUTTON') &&
// @ts-ignore
(evt.target.className.indexOf("slapos-show-form") !== -1)) { (evt.target.className.indexOf("slapos-show-form") !== -1)) {
return queue return queue
.push(function () { .push(function () {
...@@ -1107,6 +1155,7 @@ ...@@ -1107,6 +1155,7 @@
} }
if ((tag_name === 'BUTTON') && if ((tag_name === 'BUTTON') &&
// @ts-ignore
(evt.target.className.indexOf("slapos-show-raw-parameter") !== -1)) { (evt.target.className.indexOf("slapos-show-raw-parameter") !== -1)) {
return queue return queue
.push(function () { .push(function () {
...@@ -1140,6 +1189,9 @@ ...@@ -1140,6 +1189,9 @@
gadget.state.shared = 1; gadget.state.shared = 1;
content_dict.shared = 1; content_dict.shared = 1;
} }
if (!gadget.state.editable) {
return gadget.state.parameter_xml;
}
if (text_content !== null) { if (text_content !== null) {
// Don't provide blank string since the parameter will not able to load // Don't provide blank string since the parameter will not able to load
// itself. If the user removed the values, provide an empty parameter default. // itself. If the user removed the values, provide an empty parameter default.
......
...@@ -280,7 +280,7 @@ ...@@ -280,7 +280,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>1004.26824.9734.39150</string> </value> <value> <string>1004.31309.44548.40652</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -298,7 +298,7 @@ ...@@ -298,7 +298,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1668799098.86</float> <float>1669089218.99</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment