mirror of https://git.48k.eu/ogcp
Update scopes tree dynamically
This patch adds a javascript function to update the scope tree (on/off) state. This javacript function is called every second, does a call to the new backend endpoint `/scopes/status` and updates the tree classes depending on the current data. The new `/scopes/status` endpoint just returns the scopes tree as json. This patch also adds an icon in the tree leafs, a filled green circle when the state is `on`, and a empty red circle when the state is `off`. There's also a new javascript function to unfold all collapses in the scope tree.multi-ogserver
parent
af938c3280
commit
4e519590af
|
@ -0,0 +1,54 @@
|
|||
const Endpoint = '/scopes/status';
|
||||
const Interval = 1000;
|
||||
let updateTimeoutId = null;
|
||||
|
||||
function updateScopeState() {
|
||||
if (updateTimeoutId) {
|
||||
clearTimeout(updateTimeoutId);
|
||||
}
|
||||
|
||||
updateTimeoutId = setTimeout(() => {
|
||||
updateTimeoutId = null;
|
||||
fetch(Endpoint)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
updateScopes(data.scope);
|
||||
})
|
||||
.catch((error) => { console.error(error); })
|
||||
.finally(() => {
|
||||
updateScopeState();
|
||||
});
|
||||
}, Interval);
|
||||
}
|
||||
|
||||
function updateScopes(scopes) {
|
||||
scopes.forEach((scope) => {
|
||||
if (scope.state) {
|
||||
const scopeId = `${scope.name}_${scope.id}`;
|
||||
const scopeEl = document.querySelector(`#${scopeId}`);
|
||||
const stateCls = ['state--on', 'state--off'];
|
||||
scopeEl.classList.remove(...stateCls);
|
||||
const stateClass = `state--${scope.state}`;
|
||||
scopeEl.classList.add(stateClass);
|
||||
|
||||
const iconEl = document.querySelector(`#${scopeId} .nav-icon`);
|
||||
const iconCls = ['fas', 'far', 'text-danger', 'text-success'];
|
||||
iconEl.classList.remove(...iconCls);
|
||||
let newIconCls = [];
|
||||
if (scope.state === 'on') {
|
||||
newIconCls.push('fas', 'text-success');
|
||||
} else {
|
||||
newIconCls.push('far', 'text-danger');
|
||||
}
|
||||
iconEl.classList.add(...newIconCls);
|
||||
}
|
||||
if (scope.scope) {
|
||||
// This is a level so we should update all childs
|
||||
updateScopes(scope.scope);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unfoldAll() {
|
||||
$('#scopes .collapse').collapse('show');
|
||||
}
|
|
@ -20,15 +20,28 @@
|
|||
|
||||
{% macro scopes_tree_collapse(scopes) -%}
|
||||
|
||||
<ul class="nav flex-column nav-pills">
|
||||
<ul id="scopes" class="nav flex-column nav-pills">
|
||||
{{ scopes_tree_collapse_level(scopes["scope"], 1) }}
|
||||
</ul>
|
||||
<script>
|
||||
// Launch the javascript on document ready, so all the global functions exists
|
||||
// in the scope
|
||||
document.addEventListener('readystatechange', () => {
|
||||
if (document.readyState === 'complete') {
|
||||
updateScopeState();
|
||||
unfoldAll();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endmacro %}
|
||||
|
||||
{% macro scopes_tree_collapse_level(scopes, i) -%}
|
||||
{% for scope in scopes %}
|
||||
<li class="nav-item {% if scope["state"] %}state--{{scope["state"] | lower}}{% endif %}">
|
||||
<li
|
||||
id="{{ scope["name"] }}_{{ scope["id"] }}"
|
||||
class="nav-item {% if scope["state"] %}state--{{scope["state"] | lower}}{% endif %}"
|
||||
>
|
||||
{% if " ".join(scope["ip"]) %}
|
||||
<input class="form-check-input" type="checkbox" form="scopesForm"
|
||||
value="{{ " ".join(scope["ip"]) }}"
|
||||
|
@ -37,6 +50,9 @@
|
|||
{% endif %}
|
||||
<a class="nav-link {% if not scope["scope"] %}disabled{% endif %}" href="#level{{i}}-{{loop.index}}"
|
||||
{% if scope["scope"] %}data-toggle="collapse"{% endif %}>
|
||||
{% if not scope["scope"] %}
|
||||
<i class="nav-icon fa-circle {% if scope['state'] == 'on' %}fas text-success{% else %}far text-danger{% endif %}"></i>
|
||||
{% endif %}
|
||||
{{ scope["name"] }}
|
||||
</a>
|
||||
{% if scope["scope"] %}
|
||||
|
|
|
@ -113,7 +113,7 @@ def add_state_and_ips(scope, clients, ips):
|
|||
if client:
|
||||
scope['state'] = client['state']
|
||||
else:
|
||||
scope['state'] = 'OFF'
|
||||
scope['state'] = 'off'
|
||||
scope['ip'] = [scope['ip']]
|
||||
scope['selected'] = set(scope['ip']).issubset(ips)
|
||||
else:
|
||||
|
@ -191,6 +191,12 @@ def logout():
|
|||
logout_user()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
@app.route('/scopes/status')
|
||||
@login_required
|
||||
def scopes_status():
|
||||
scopes, _clients = get_scopes()
|
||||
return jsonify(scopes)
|
||||
|
||||
@app.route('/scopes/')
|
||||
@login_required
|
||||
def scopes():
|
||||
|
|
Loading…
Reference in New Issue