Verified Commit d84d8f69 authored by Štěpán Henek's avatar Štěpán Henek 🌩

subordinates: tab splitted into two separate pages

parent 13276910
......@@ -46,6 +46,8 @@ class BaseConfigPage(object):
menu_order = 50
slug: typing.Optional[str] = None
page_name: typing.Optional[str] = None
userfriendly_title: typing.Optional[str]
menu_title: typing.Optional[str] = None
subpages: typing.Iterable[typing.Type['ConfigPageMixin']] = []
@staticmethod
......@@ -444,23 +446,22 @@ class RemoteConfigPage(ConfigPageMixin, remote.RemoteHandler):
return ConfigPageMixin.is_enabled_static(cls)
class SubordinatesConfigPage(ConfigPageMixin, subordinates.SubordinatesConfigHandler):
class SubordinatesSetupPage(ConfigPageMixin, subordinates.SubordinatesConfigHandler):
slug = "subordinates"
menu_order = 1 # submenu
template = "config/subordinates"
userfriendly_title = gettext("Set up")
template = "config/subordinates_setup"
menu_title = gettext("Set up")
userfriendly_title = gettext("Managed devices: Set up")
template_type = "jinja2"
def render(self, **kwargs):
data = current_state.backend.perform("subordinates", "list")
kwargs["subordinates"] = data["subordinates"]
return super().render(**kwargs)
def save(self, *args, **kwargs):
super(SubordinatesConfigPage, self).save(no_messages=True, *args, **kwargs)
super(SubordinatesSetupPage, self).save(no_messages=True, *args, **kwargs)
data = self.form.callback_results
if data["result"]:
messages.success(_(
......@@ -484,11 +485,9 @@ class SubordinatesConfigPage(ConfigPageMixin, subordinates.SubordinatesConfigHan
def _ajax_list_subordinates(self):
data = current_state.backend.perform("subordinates", "list")
view = bottle.request.GET.decode().get("view")
return template(
"config/_subordinates_list.html.j2",
"config/_subordinates_list_setup.html.j2",
subordinates=data["subordinates"],
view = view,
template_adapter=bottle.Jinja2Template,
)
......@@ -630,7 +629,54 @@ class SubordinatesConfigPage(ConfigPageMixin, subordinates.SubordinatesConfigHan
"config_ajax_form", page_name="subordinates", form_name="subsub-form")
return form, prepare_message
elif form_name == "wifi-form":
raise bottle.HTTPError(404, "No form '%s' not found." % form_name)
class SubordinatesWifiPage(ConfigPageMixin):
slug = "subordinates-wifi"
menu_order = 2 # submenu
template = "config/subordinates_wifi"
menu_title = gettext("Wi-Fi")
userfriendly_title = gettext("Managed devices: Wi-Fi")
template_type = "jinja2"
def render(self, **kwargs):
data = current_state.backend.perform("subordinates", "list")
kwargs["subordinates"] = data["subordinates"]
return super().render(**kwargs)
@classmethod
def is_visible(cls):
if current_state.backend.name != "mqtt":
return False
return ConfigPageMixin.is_visible_static(cls)
@classmethod
def is_enabled(cls):
if current_state.backend.name != "mqtt":
return False
return ConfigPageMixin.is_enabled_static(cls)
def _ajax_list_subordinates(self):
data = current_state.backend.perform("subordinates", "list")
return template(
"config/_subordinates_list_wifi.html.j2",
subordinates=data["subordinates"],
template_adapter=bottle.Jinja2Template,
)
def call_ajax_action(self, action):
if action == "list":
return self._ajax_list_subordinates()
raise ValueError("Unknown AJAX action.")
def get_page_form(self, form_name: str, data: dict, controller_id: str) -> typing.Tuple[
fapi.ForisAjaxForm, typing.Callable[[dict], typing.Tuple['str', 'str']]
]:
"""Returns appropriate foris form and handler to generate response
"""
if form_name == "wifi-form":
form = wifi.WifiEditForm(data, controller_id=controller_id)
def prepare_message(results: dict) -> dict:
......@@ -647,7 +693,7 @@ class SubordinatesConfigPage(ConfigPageMixin, subordinates.SubordinatesConfigHan
}
return message
form.url = reverse("config_ajax_form", page_name="subordinates", form_name="wifi-form")
form.url = reverse("config_ajax_form", page_name="subordinates-wifi", form_name="wifi-form")
return form, prepare_message
raise bottle.HTTPError(404, "No form '%s' not found." % form_name)
......@@ -658,9 +704,22 @@ class SubordinatesJoinedPage(JoinedPages):
name = "subordinates-main"
subpages: typing.Iterable[typing.Type['ConfigPageMixin']] = [
SubordinatesConfigPage,
SubordinatesSetupPage,
SubordinatesWifiPage,
]
@classmethod
def is_visible(cls):
if current_state.backend.name != "mqtt":
return False
return ConfigPageMixin.is_visible_static(cls)
@classmethod
def is_enabled(cls):
if current_state.backend.name != "mqtt":
return False
return ConfigPageMixin.is_enabled_static(cls)
class ProfileConfigPage(ConfigPageMixin, profile.ProfileHandler):
slug = "profile"
......
......@@ -194,7 +194,6 @@ class SubsubordinatesEditForm(fapi.ForisAjaxForm):
class SubordinatesWifiHandler(BaseConfigHandler):
userfriendly_title = gettext("Wi-Fi")
def get_form(self):
ajax_form = WifiEditForm(self.data)
......
{% macro sub_buttons(controller_id, enabled, form_class) -%}
<form action="{{ url("config_ajax", page_name="subordinates") }}" method="post" class="subordinate-buttons {{ form_class }}">
<input type="hidden" name="controller_id" value="{{ controller_id }}">
<input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}">
{% if enabled %}
<button name="action" value="disable" type="submit"><i class="fas fa-pause"></i></button>
{% else %}
<button name="action" value="enable" type="submit"><i class="fas fa-play"></i></button>
{% endif %}
<button name="action" value="delete" type="submit"><i class="fas fa-trash-alt"></i> </button>
<button name="action" value="edit" type="submit"><i class="fas fa-edit"></i></button>
</form>
{%- endmacro %}
{% macro convert_state(enabled, sup_enabled) -%}
{% if enabled and sup_enabled %}
<i class="fas fa-question-circle state"></i>
{% else %}
<i class="fas fa-pause-circle state"></i>
{% endif %}
{%- endmacro %}
{%- macro should_be_connected_class(enabled, sup_enabled) %}
{% if enabled and sup_enabled %} sub-connection{% endif %}
{%- endmacro %}
{% if subordinates %}
<table id="subordinates-table">
<thead><th>{% trans %}ID{% endtrans %}</th><th>{% trans %}State{% endtrans %}</th><th></th></thead>
<tbody>
{% for sub in subordinates %}
<tr id="sub-{{ sub.controller_id }}" class="sub-line {{ should_be_connected_class(sub.enabled, True) }}">
<td>{{ sub.options.custom_name or sub.controller_id }}</td>
<td>
{{ convert_state(sub.enabled, True) }}
</td>
<td>{{ sub_buttons(sub.controller_id, sub.enabled, "sub-form") }}</td>
</tr>
{% for subsub in sub.subsubordinates %}
<tr id="sub-{{ subsub.controller_id }}" class="sub-line {{ should_be_connected_class(subsub.enabled, sub.enabled) }}">
<td class="indented-item"><i class="fas fa-level-up-alt rotate-90"></i>
{{ subsub.options.custom_name or subsub.controller_id }}
</td>
<td>
{{ convert_state(subsub.enabled, sub.enabled) }}
</td>
<td>{{ sub_buttons(subsub.controller_id, subsub.enabled, "subsub-form") }}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
{% else %}
<p id="subordinates-table">{% trans %}Currently there are no managed devices.{% endtrans %}</p>
{% endif %}
......@@ -5,19 +5,6 @@
<button name="action" value="edit" type="submit" style="display: none"><i class="fas fa-edit"></i></button>
</form>
{% endmacro -%}
{% macro sub_buttons(controller_id, enabled, form_class) -%}
<form action="{{ url("config_ajax", page_name="subordinates") }}" method="post" class="subordinate-buttons {{ form_class }}">
<input type="hidden" name="controller_id" value="{{ controller_id }}">
<input type="hidden" name="csrf_token" value="{{ get_csrf_token() }}">
{% if enabled %}
<button name="action" value="disable" type="submit"><i class="fas fa-pause"></i></button>
{% else %}
<button name="action" value="enable" type="submit"><i class="fas fa-play"></i></button>
{% endif %}
<button name="action" value="delete" type="submit"><i class="fas fa-trash-alt"></i> </button>
<button name="action" value="edit" type="submit"><i class="fas fa-edit"></i></button>
</form>
{%- endmacro %}
{% macro convert_state(enabled, sup_enabled) -%}
{% if enabled and sup_enabled %}
<i class="fas fa-question-circle state"></i>
......@@ -30,10 +17,9 @@
{%- endmacro %}
{% if subordinates %}
<table id="subordinates-table">
{% if view == "wifi" %}
<thead><th>{% trans %}ID{% endtrans %}</th><th>{% trans %}State{% endtrans %}</th><th>{% trans %}Devices{% endtrans %}</th><th>{% trans %}Channels{% endtrans %}</th><th></th></thead>
<tbody>
{% for sub in subordinates %}
{% for sub in subordinates %}
<tr id="sub-{{ sub.controller_id }}" class="sub-line {{ should_be_connected_class(sub.enabled, True) }}">
<td>{{ sub.options.custom_name or sub.controller_id }}</td>
<td>
......@@ -45,7 +31,7 @@
{{ make_simple_edit_form(sub.controller_id, "wifi") }}
</td>
</tr>
{% for subsub in sub.subsubordinates %}
{% for subsub in sub.subsubordinates %}
<tr id="sub-{{ subsub.controller_id }}" class="sub-line {{ should_be_connected_class(subsub.enabled, sub.enabled) }}" >
<td class="indented-item"><i class="fas fa-level-up-alt rotate-90"></i>
{{ subsub.options.custom_name or subsub.controller_id }}
......@@ -59,34 +45,9 @@
{{ make_simple_edit_form(subsub.controller_id, "wifi") }}
</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
{% else %}
<thead><th>{% trans %}ID{% endtrans %}</th><th>{% trans %}State{% endtrans %}</th><th></th></thead>
<tbody>
{% for sub in subordinates %}
<tr id="sub-{{ sub.controller_id }}" class="sub-line {{ should_be_connected_class(sub.enabled, True) }}">
<td>{{ sub.options.custom_name or sub.controller_id }}</td>
<td>
{{ convert_state(sub.enabled, True) }}
</td>
<td>{{ sub_buttons(sub.controller_id, sub.enabled, "sub-form") }}</td>
</tr>
{% for subsub in sub.subsubordinates %}
<tr id="sub-{{ subsub.controller_id }}" class="sub-line {{ should_be_connected_class(subsub.enabled, sub.enabled) }}">
<td class="indented-item"><i class="fas fa-level-up-alt rotate-90"></i>
{{ subsub.options.custom_name or subsub.controller_id }}
</td>
<td>
{{ convert_state(subsub.enabled, sub.enabled) }}
</td>
<td>{{ sub_buttons(subsub.controller_id, subsub.enabled, "subsub-form") }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
</tbody>
{% endif %}
</table>
{% else %}
<p id="subordinates-table">{% trans %}Currently there are no subordinates.{% endtrans %}</p>
......
......@@ -7,7 +7,7 @@
{% macro render_menu_item(page, parent, display) -%}
{% if page.is_visible() and page.is_enabled() %}
<li class="{{ write_active(page) }}{% if parent %} submenu-item parent-name-{{ parent.name }}{% endif %}{% if active_config_page_key in page.subpage_slugs() %} subpage-active{% endif %}{% if not page.slug %} nav-expandable{% endif %}" {% if not display %}style="display: none;"{% endif %} data-self-name="{{ page.name if page.name else "" }}">
<a href="{{ url("config_page", page_name=page.slug) if page.slug else "#" }}">{% if parent %}<i class="fas fa-level-up-alt rotate-90"></i> {% endif %}{{ page.userfriendly_title }}
<a href="{{ url("config_page", page_name=page.slug) if page.slug else "#" }}">{% if parent %}<i class="fas fa-level-up-alt rotate-90"></i> {% endif %}{{ page.menu_title if page.menu_title else page.userfriendly_title }}
{% if page.subpages and active_config_page_key not in page.subpage_slugs() %}
<span title="{% trans %}Expandable{% endtrans %}" id="{{ page.slug or page.name }}_expand" class="expand-tag"><i class='fas fa-caret-square-down'></i></span>
{% elif page.get_menu_tag()["show"] %}
......
......@@ -9,7 +9,7 @@
On this tab you can set up other turris devices which can be controlled
by this device. You need to generate token on the remote tab on the device
you wan't to control. And insert the token here.
{%- endtrans %}
{% endtrans -%}
</p>
<h3>{% trans %}Add device{% endtrans %}</h3>
<form id="main-form" class="config-form" action="{{ request.fullpath }}" method="post" enctype="multipart/form-data" autocomplete="off" novalidate>
......@@ -24,10 +24,6 @@
</form>
{% if is_xhr is not defined %}
<h3>{% trans %}Device list{% endtrans %}</h3>
{% set subpage = request.params.get("view", "subordinates") %}
<a href="{{ request.fullpath }}?view=subordinates" class="button{% if subpage == "subordinates" %} disabled{% endif %}">{% trans %}Devices{% endtrans %}</a>
<a href="{{ request.fullpath }}?view=wifi" class="button{% if subpage == "wifi" %} disabled{% endif %}">{% trans %}Wifi{% endtrans %}</a>
<hr>
<div id="subordinates-message"></div>
<div id="subordinates-table">
{% trans %}Loading manged devices...{% endtrans %}
......@@ -36,29 +32,8 @@
<div id="subordinates-edit">
</div>
<script>
Foris.queryBackendWifi = async (controller_id) => {
let run = async () => {
try {
resp = await Foris.performBackendQuery(controller_id, "wifi", "get_settings");
$(`#sub-${controller_id}`).find(".wifi-count").text(resp.devices.length);
let channels = [];
for (let device of resp.devices) {
if (device.enabled) {
channels.push(device.channel == 0 ? "*": device.channel);
}
};
$(`#sub-${controller_id}`).find(".wifi-channels").text(channels.join(", "));
} catch(err) {
$(`#sub-${controller_id}`).find(".wifi-count").text("?");
$(`#sub-${controller_id}`).find(".wifi-channels").text("?");
}
};
run(); // call async don't wait for it
};
Foris.subordinatesGetView = () => (new URLSearchParams(window.location.search)).get("view") || "subordinates";
Foris.loadSubordinatesList = async () => {
let urlParams = new URLSearchParams(window.location.search);
let resp = await $.get('{{ url("config_ajax", page_name="subordinates") }}', {action: "list", view: Foris.subordinatesGetView()});
let resp = await $.get('{{ url("config_ajax", page_name="subordinates") }}', {action: "list"});
$("#subordinates-table").replaceWith(resp);
Foris.overrideSubordinatesButtons();
Foris.setSubordinatesTimeouts();
......@@ -139,30 +114,19 @@
break;
case "edit":
switch (Foris.subordinatesGetView()) {
case "subordinates":
if (form.attr("class").includes("subsub-form")) {
resp = await $.ajax({
type: "POST",
url: '{{ url("config_ajax_form", page_name="subordinates", form_name="subsub-form") }}',
data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&_update=1`,
});
} else {
resp = await $.ajax({
type: "POST",
url: '{{ url("config_ajax_form", page_name="subordinates", form_name="sub-form") }}',
data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&_update=1`,
});
}
break;
case "wifi":
resp = await $.ajax({
type: "POST",
url: '{{ url("config_ajax_form", page_name="subordinates", form_name="wifi-form") }}',
data: `&csrf_token=${form_data["csrf_token"]}&_controller_id=${form_data["controller_id"]}&_update=1`,
});
if (form.attr("class").includes("subsub-form")) {
resp = await $.ajax({
type: "POST",
url: '{{ url("config_ajax_form", page_name="subordinates", form_name="subsub-form") }}',
data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&_update=1`,
});
} else {
resp = await $.ajax({
type: "POST",
url: '{{ url("config_ajax_form", page_name="subordinates", form_name="sub-form") }}',
data: `&csrf_token=${form_data["csrf_token"]}&controller_id=${form_data["controller_id"]}&_update=1`,
});
}
Foris.subordinateInEditMode = true;
await $("#subordinates-edit").promise();
$("#subordinates-edit").replaceWith(resp);
$(".subordinate-buttons button").hide('slow');
......@@ -178,18 +142,14 @@
};
Foris.suboridnatesOverrideEditClose = async () => {
$("#subordinates-edit").find("a.button").click(async (e) => {
Foris.subordinateInEditMode = false;
e.preventDefault();
$("#subordinates-edit").hide('slow');
await $("#subordinates-edit").promise();
$("#subordinates-edit").replaceWith("<div id='subordinates-edit'></div>");
if (Foris.subordinatesGetView() == "subordinates") {
$(".subordinate-buttons button").show('slow');
await $(".subordinate-buttons button").promise();
}
$(".subordinate-buttons button").show('slow');
await $(".subordinate-buttons button").promise();
});
};
Foris.subordinateInEditMode = false;
Foris.subordinatesAlive = {};
Foris.subordinateKeepAliveTimeouts = {};
Foris.subordinateSetKeepAliveTimeout = (controller_id) => {
......@@ -201,7 +161,6 @@
state_element.addClass("state fas fa-exclamation-circle");
delete Foris.subordinateKeepAliveTimeouts[controller_id];
$(`div[data-controller-id=${controller_id}]`).replaceWith(`<div id='subordinates-edit' class='message error' data-controller-id='${controller_id}'>${Foris.messages.subordinatesSubordinatesFailed(controller_id)}</div>`);
Foris.subordinateInEditMode = false;
}, 3000);
};
Foris.updateSubordinateState = async (data) => {
......@@ -222,16 +181,12 @@
state_element.addClass("state fas fa-check-circle");
Foris.subordinateSetKeepAliveTimeout(data.id);
if (!Foris.subordinatesAlive[data.id]) { // query backend if needed
Foris.queryBackendWifi(data.id);
}
Foris.subordinatesAlive[data.id] = true;
if (!Foris.subordinateInEditMode) {
$(`#sub-${data.id}`).find("button[value=edit]").show("slow");
let message = $(`div[data-controller-id=${data.id}].message`);
message.hide("slow");
await message.promise();
message.replaceWith("<div id='subordinates-edit'></div>");
}
let message = $(`div[data-controller-id=${data.id}].message`);
message.hide("slow");
await message.promise();
message.replaceWith("<div id='subordinates-edit'></div>");
break;
case 'exitted':
state_element.addClass("state fas fa-exclamation-circle");
......
{% extends 'config/base.html.j2' %}
{% block config_base %}
{% if is_xhr is not defined %}
<div id="page-config" class="config-page">
{% endif %}
<p>
{%- trans %}
On this tab you can set up Wi-Fi of other devices controlled by this device.
{%- endtrans %}
</p>
{% if is_xhr is not defined %}
<h3>{% trans %}Device list{% endtrans %}</h3>
<div id="subordinates-message"></div>
<div id="subordinates-table">
{% trans %}Loading manged devices...{% endtrans %}
</div>
<br />
<div id="subordinates-edit">
</div>
<script>
Foris.queryBackendWifi = async (controller_id) => {
let run = async () => {
try {
resp = await Foris.performBackendQuery(controller_id, "wifi", "get_settings");
$(`#sub-${controller_id}`).find(".wifi-count").text(resp.devices.length);
let channels = [];
for (let device of resp.devices) {
if (device.enabled) {
channels.push(device.channel == 0 ? "*": device.channel);
}
};
$(`#sub-${controller_id}`).find(".wifi-channels").text(channels.join(", "));
} catch(err) {
$(`#sub-${controller_id}`).find(".wifi-count").text("?");
$(`#sub-${controller_id}`).find(".wifi-channels").text("?");
}
};
run(); // call async don't wait for it
};
Foris.loadSubordinatesList = async () => {
let resp = await $.get('{{ url("config_ajax", page_name="subordinates-wifi") }}', {action: "list"});
$("#subordinates-table").replaceWith(resp);
Foris.overrideSubordinatesButtons();
Foris.setSubordinatesTimeouts();
}
Foris.setSubordinatesTimeouts = () => {
for (timeout in Foris.subordinateKeepAliveTimeouts) {
clearTimeout(Foris.subordinateKeepAliveTimeouts[timeout]);
}
Foris.subordinateKeepAliveTimeouts = {};
$(".sub-connection").each((idx, val) => {
let id = $(val).attr("id");
if (id) {
Foris.subordinateSetKeepAliveTimeout(id.replace('sub-', ''));
}
});
};
Foris.overrideSubordinatesEditButton = async () => {
$("#subordinates-edit form").submit(async (e) => {
e.preventDefault();
let form = $(e.currentTarget);
resp = $.ajax({
type: "POST",
url: form.attr('action'),
data: form.serialize()
});
form.find("input, select, button").attr("disabled", "disabled");
let new_form = await resp;
$("#subordinates-edit").replaceWith(new_form);
await Foris.suboridnatesOverrideEditClose();
await Foris.overrideSubordinatesEditButton();
await Foris.loadSubordinatesList();
$(".subordinate-buttons button").hide();
});
};
Foris.overrideSubordinatesButtons = async () => {
$(".subordinate-buttons").submit(async (e) => {
e.preventDefault();
let form = $(e.currentTarget);
let action = $(e.originalEvent.explicitOriginalTarget).val();
let form_data = {};
let serialized = form.serializeArray();
for (record in serialized) {
form_data[serialized[record].name] = serialized[record].value;
}
let controller_id = form_data.controller_id;
let renderResponse = (resp) => {
$("#subordinates-message").replaceWith(resp);
};
let resp = null;
switch (action) {
case "edit":
Foris.subordinateInEditMode = true;
try {
resp = await $.ajax({
type: "POST",
url: '{{ url("config_ajax_form", page_name="subordinates-wifi", form_name="wifi-form") }}',
data: `&csrf_token=${form_data["csrf_token"]}&_controller_id=${form_data["controller_id"]}&_update=1`,
});
} catch(err) {
Foris.subordinateInEditMode = false;
return;
}
await $("#subordinates-edit").promise();
$("#subordinates-edit").replaceWith(resp);
$(".subordinate-buttons button").hide('slow');
await $(".subordinate-buttons button").promise();
$("#subordinates-edit").show('slow');
await $("#subordinates-edit").promise();
await Foris.suboridnatesOverrideEditClose();
Foris.overrideSubordinatesEditButton();
return;
}
$(".subordinate-buttons button").prop('disabled', true);
});
};
Foris.suboridnatesOverrideEditClose = async () => {
$("#subordinates-edit").find("a.button").click(async (e) => {
Foris.subordinateInEditMode = false;
e.preventDefault();
$("#subordinates-edit").hide('slow');
await $("#subordinates-edit").promise();
$("#subordinates-edit").replaceWith("<div id='subordinates-edit'></div>");
if (Foris.subordinatesGetView() == "subordinates") {
$(".subordinate-buttons button").show('slow');
await $(".subordinate-buttons button").promise();
}
});
};
Foris.subordinateInEditMode = false;
Foris.subordinatesAlive = {};
Foris.subordinateKeepAliveTimeouts = {};
Foris.subordinateSetKeepAliveTimeout = (controller_id) => {
let element = $(`#sub-${controller_id}`);
let state_element = element.find(".state");
Foris.subordinateKeepAliveTimeouts[controller_id] = setTimeout(() => {
Foris.subordinatesAlive[controller_id] = false;
state_element.removeClass();
state_element.addClass("state fas fa-exclamation-circle");
delete Foris.subordinateKeepAliveTimeouts[controller_id];
$(`div[data-controller-id=${controller_id}]`).replaceWith(`<div id='subordinates-edit' class='message error' data-controller-id='${controller_id}'>${Foris.messages.subordinatesSubordinatesFailed(controller_id)}</div>`);
Foris.subordinateInEditMode = false;
}, 3000);
};
Foris.updateSubordinateState = async (data) => {
let element = $(`#sub-${data.id}`);
let state_element = element.find(".state");
if (!document.hidden) {
await state_element.animate({opacity: '0.2'}, 50);
}
state_element.removeClass();
switch (data.state) {
case 'started':
state_element.addClass("state fas fa-circle");
break;
case 'running':
if (data.id in Foris.subordinateKeepAliveTimeouts) {
clearTimeout(Foris.subordinateKeepAliveTimeouts[data.id]);
}
state_element.addClass("state fas fa-check-circle");
Foris.subordinateSetKeepAliveTimeout(data.id);
if (!Foris.subordinatesAlive[data.id]) { // query backend if needed
Foris.queryBackendWifi(data.id);
}
Foris.subordinatesAlive[data.id] = true;
if (!Foris.subordinateInEditMode) {
$(`#sub-${data.id}`).find("button[value=edit]").show("slow");
let message = $(`div[data-controller-id=${data.id}].message`);
message.hide("slow");
await message.promise();
message.replaceWith("<div id='subordinates-edit'></div>");
}
break;
case 'exitted':
state_element.addClass("state fas fa-exclamation-circle");
break;
default:
state_element.addClass("state fas fa-question-circle");
break;
}
if (!document.hidden) {
await state_element.animate({opacity: '1.0'}, 50);
}
};
Foris.addWsHanlder("subordinates", async (msg) => {
switch(msg.action) {
case "add_sub":
case "add_subsub":
case "del":
case "set_enabled":
await Foris.loadSubordinatesList();
break;
}
});
Foris.addWsHanlder("remote", async (msg) => {
switch(msg.action) {
case "advertize":
Foris.updateSubordinateState(msg.data);
break;
};
}, '+');
$(document).ready(function() {
Foris.loadSubordinatesList();
Foris.afterAjaxUpdateFunctions.push(Foris.suboridnatesOverrideEditClose);
Foris.afterAjaxUpdateFunctions.push(Foris.overrideSubordinatesEditButton);
});
</script>
<style>
#subordinates-table .sub-line .state {
font-size: 1.5rem;
};
#subordinates-table td {
vertical-align: top;
};
</style>
</div>
{% endif %}
{% endblock %}
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