push
This commit is contained in:
156
templates/dashboards/widget_new.html
Normal file
156
templates/dashboards/widget_new.html
Normal file
@@ -0,0 +1,156 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Add widget - {{ dashboard.name }} - MikroMon{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<div>
|
||||
<h1 class="h4 mb-0">Add widget</h1>
|
||||
<div class="text-muted">Dashboard: <span class="fw-semibold">{{ dashboard.name }}</span></div>
|
||||
</div>
|
||||
<a class="btn btn-outline-secondary" href="{{ url_for('dashboards.view', dashboard_id=dashboard.id) }}"><i class="fa-solid fa-arrow-left me-1"></i>Back</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-7">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-4">
|
||||
<form method="post" novalidate id="widgetForm">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Title</label>
|
||||
{{ form.title(class_="form-control") }}
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Preset</label>
|
||||
{{ form.preset_key(class_="form-select", id="presetSelect") }}
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Device</label>
|
||||
<select class="form-select" name="device_id" id="deviceSelect" required>
|
||||
<option value="">— select —</option>
|
||||
{% for d in devices %}
|
||||
<option value="{{ d.id }}">{{ d.name }} ({{ d.host }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 d-none" id="itemWrap">
|
||||
<label class="form-label" id="itemLabel">Item</label>
|
||||
<select class="form-select" id="itemSelect">
|
||||
<option value="">— select —</option>
|
||||
</select>
|
||||
<div class="form-text">E.g. interface / queue (depends on preset).</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label class="form-label">Refresh (seconds)</label>
|
||||
{{ form.refresh_seconds(class_="form-control", type="number", min="1") }}
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="collapse" data-bs-target="#advJson">
|
||||
<i class="fa-solid fa-code me-1"></i>Advanced (JSON)
|
||||
</button>
|
||||
<div class="collapse mt-2" id="advJson">
|
||||
{{ form.query_json(class_="form-control font-monospace", rows="6", placeholder='{"connector":"rest","endpoint":"/...","params":{}}') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 mt-4">
|
||||
<button class="btn btn-primary" type="submit"><i class="fa-solid fa-plus me-1"></i>Add</button>
|
||||
<a class="btn btn-outline-secondary" href="{{ url_for('dashboards.view', dashboard_id=dashboard.id) }}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body p-4">
|
||||
<div class="fw-semibold mb-2"><i class="fa-solid fa-wand-magic-sparkles me-2"></i>Wizard mode</div>
|
||||
<div class="text-muted small">
|
||||
If the preset requires selecting an item (e.g. interface), the list will load automatically after choosing a device.
|
||||
If you fill the JSON manually, the JSON will be used.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
(function(){
|
||||
const presets = {{ presets|tojson }};
|
||||
const presetSelect = document.getElementById('presetSelect');
|
||||
const deviceSelect = document.getElementById('deviceSelect');
|
||||
const itemWrap = document.getElementById('itemWrap');
|
||||
const itemSelect = document.getElementById('itemSelect');
|
||||
const itemLabel = document.getElementById('itemLabel');
|
||||
|
||||
function presetNeedsItem(p){
|
||||
if(!p) return false;
|
||||
const params = p.params || {};
|
||||
return Object.prototype.hasOwnProperty.call(params, 'name');
|
||||
}
|
||||
|
||||
async function loadItems(){
|
||||
const presetKey = presetSelect.value;
|
||||
const deviceId = deviceSelect.value;
|
||||
const p = presets[presetKey];
|
||||
if(!deviceId || !presetNeedsItem(p)){
|
||||
itemWrap.classList.add('d-none');
|
||||
itemSelect.innerHTML = '<option value="">— select —</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
itemWrap.classList.remove('d-none');
|
||||
itemLabel.textContent = String(presetKey).includes('queue') ? 'Queue' : 'Interface / item';
|
||||
itemSelect.innerHTML = '<option value="">Loading…</option>';
|
||||
|
||||
try{
|
||||
const url = new URL("{{ url_for('api.preset_items') }}", window.location.origin);
|
||||
url.searchParams.set('device_id', deviceId);
|
||||
url.searchParams.set('preset_key', presetKey);
|
||||
const r = await fetch(url.toString(), {credentials:'same-origin'});
|
||||
const j = await r.json();
|
||||
const items = (j && j.data && j.data.items) ? j.data.items : [];
|
||||
itemSelect.innerHTML = '<option value="">— select —</option>' + items.map(x => `<option value="${x}">${x}</option>`).join('');
|
||||
}catch(e){
|
||||
itemSelect.innerHTML = '<option value="">Load error</option>';
|
||||
}
|
||||
}
|
||||
|
||||
presetSelect?.addEventListener('change', loadItems);
|
||||
deviceSelect?.addEventListener('change', loadItems);
|
||||
|
||||
document.getElementById('widgetForm')?.addEventListener('submit', ()=>{
|
||||
const adv = document.getElementById('{{ form.query_json.id }}');
|
||||
if(!adv) return;
|
||||
if(adv.value && adv.value.trim()) return;
|
||||
|
||||
const presetKey = presetSelect.value;
|
||||
const p = presets[presetKey];
|
||||
if(!p) return;
|
||||
|
||||
const q = {
|
||||
connector: p.connector || 'rest',
|
||||
endpoint: p.endpoint,
|
||||
params: Object.assign({}, (p.params||{})),
|
||||
extract: p.extract || {},
|
||||
preset_key: presetKey
|
||||
};
|
||||
if(presetNeedsItem(p) && itemSelect.value){
|
||||
q.params.name = itemSelect.value;
|
||||
}
|
||||
adv.value = JSON.stringify(q);
|
||||
});
|
||||
|
||||
loadItems();
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user