Add tabbed interface to dashboard
This commit is contained in:
parent
207facedc2
commit
b67266d3b3
1 changed files with 80 additions and 14 deletions
|
@ -9,8 +9,17 @@
|
||||||
<body class="section">
|
<body class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="title">ngxstat Reports</h1>
|
<h1 class="title">ngxstat Reports</h1>
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control has-icons-left">
|
<div class="tabs is-toggle" id="report-tabs">
|
||||||
|
<ul>
|
||||||
|
<li class="is-active" data-tab="overview"><a>Overview</a></li>
|
||||||
|
<li data-tab="all"><a>All Domains</a></li>
|
||||||
|
<li data-tab="domain"><a>Per Domain</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="controls" class="field is-grouped mb-4">
|
||||||
|
<div id="interval-control" class="control has-icons-left is-hidden">
|
||||||
<div class="select is-small">
|
<div class="select is-small">
|
||||||
<select id="interval-select">
|
<select id="interval-select">
|
||||||
{% for interval in intervals %}
|
{% for interval in intervals %}
|
||||||
|
@ -20,7 +29,7 @@
|
||||||
</div>
|
</div>
|
||||||
<span class="icon is-small is-left"><i data-feather="clock"></i></span>
|
<span class="icon is-small is-left"><i data-feather="clock"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="control has-icons-left">
|
<div id="domain-control" class="control has-icons-left is-hidden">
|
||||||
<div class="select is-small">
|
<div class="select is-small">
|
||||||
<select id="domain-select">
|
<select id="domain-select">
|
||||||
<option value="">All Domains</option>
|
<option value="">All Domains</option>
|
||||||
|
@ -32,13 +41,24 @@
|
||||||
<span class="icon is-small is-left"><i data-feather="server"></i></span>
|
<span class="icon is-small is-left"><i data-feather="server"></i></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="overview-section">
|
||||||
<div id="overview" class="box mb-5">
|
<div id="overview" class="box mb-5">
|
||||||
<h2 class="subtitle">Overview</h2>
|
<h2 class="subtitle">Overview</h2>
|
||||||
<p>Total logs: <span id="stat-total">-</span></p>
|
<p>Total logs: <span id="stat-total">-</span></p>
|
||||||
<p>Date range: <span id="stat-start">-</span> to <span id="stat-end">-</span></p>
|
<p>Date range: <span id="stat-start">-</span> to <span id="stat-end">-</span></p>
|
||||||
<p>Unique domains: <span id="stat-domains">-</span></p>
|
<p>Unique domains: <span id="stat-domains">-</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div id="reports-container"></div>
|
<div id="overview-reports"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="all-section" class="is-hidden">
|
||||||
|
<div id="reports-all"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="domain-section" class="is-hidden">
|
||||||
|
<div id="reports-domain"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
|
@ -47,7 +67,19 @@
|
||||||
<script>
|
<script>
|
||||||
const intervalSelect = document.getElementById('interval-select');
|
const intervalSelect = document.getElementById('interval-select');
|
||||||
const domainSelect = document.getElementById('domain-select');
|
const domainSelect = document.getElementById('domain-select');
|
||||||
const container = document.getElementById('reports-container');
|
const intervalControl = document.getElementById('interval-control');
|
||||||
|
const domainControl = document.getElementById('domain-control');
|
||||||
|
const tabs = document.querySelectorAll('#report-tabs li');
|
||||||
|
const sections = {
|
||||||
|
overview: document.getElementById('overview-section'),
|
||||||
|
all: document.getElementById('all-section'),
|
||||||
|
domain: document.getElementById('domain-section')
|
||||||
|
};
|
||||||
|
const containers = {
|
||||||
|
overview: document.getElementById('overview-reports'),
|
||||||
|
all: document.getElementById('reports-all'),
|
||||||
|
domain: document.getElementById('reports-domain')
|
||||||
|
};
|
||||||
const totalElem = document.getElementById('stat-total');
|
const totalElem = document.getElementById('stat-total');
|
||||||
const startElem = document.getElementById('stat-start');
|
const startElem = document.getElementById('stat-start');
|
||||||
const endElem = document.getElementById('stat-end');
|
const endElem = document.getElementById('stat-end');
|
||||||
|
@ -55,6 +87,7 @@
|
||||||
|
|
||||||
let currentInterval = intervalSelect.value;
|
let currentInterval = intervalSelect.value;
|
||||||
let currentDomain = domainSelect.value;
|
let currentDomain = domainSelect.value;
|
||||||
|
let currentTab = 'overview';
|
||||||
|
|
||||||
function initReport(rep, base) {
|
function initReport(rep, base) {
|
||||||
fetch(base + '/' + rep.json)
|
fetch(base + '/' + rep.json)
|
||||||
|
@ -119,10 +152,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadReports() {
|
function loadReports() {
|
||||||
let path = currentInterval;
|
let path;
|
||||||
if (currentDomain) {
|
let container;
|
||||||
|
if (currentTab === 'overview') {
|
||||||
|
path = 'global';
|
||||||
|
container = containers.overview;
|
||||||
|
} else if (currentTab === 'all') {
|
||||||
|
path = currentInterval;
|
||||||
|
container = containers.all;
|
||||||
|
} else {
|
||||||
|
container = containers.domain;
|
||||||
|
if (!currentDomain) {
|
||||||
|
container.innerHTML = '<p>Select a domain</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
path = 'domains/' + currentDomain + '/' + currentInterval;
|
path = 'domains/' + currentDomain + '/' + currentInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch(path + '/reports.json')
|
fetch(path + '/reports.json')
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(reports => {
|
.then(reports => {
|
||||||
|
@ -135,9 +181,26 @@
|
||||||
initReport(rep, path);
|
initReport(rep, path);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
feather.replace();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function switchTab(name) {
|
||||||
|
currentTab = name;
|
||||||
|
tabs.forEach(tab => {
|
||||||
|
tab.classList.toggle('is-active', tab.dataset.tab === name);
|
||||||
|
});
|
||||||
|
Object.entries(sections).forEach(([key, section]) => {
|
||||||
|
section.classList.toggle('is-hidden', key !== name);
|
||||||
|
});
|
||||||
|
intervalControl.classList.toggle('is-hidden', name === 'overview');
|
||||||
|
domainControl.classList.toggle('is-hidden', name !== 'domain');
|
||||||
|
if (name === 'overview') {
|
||||||
|
loadStats();
|
||||||
|
}
|
||||||
|
loadReports();
|
||||||
|
}
|
||||||
|
|
||||||
intervalSelect.addEventListener('change', () => {
|
intervalSelect.addEventListener('change', () => {
|
||||||
currentInterval = intervalSelect.value;
|
currentInterval = intervalSelect.value;
|
||||||
loadReports();
|
loadReports();
|
||||||
|
@ -148,8 +211,11 @@
|
||||||
loadReports();
|
loadReports();
|
||||||
});
|
});
|
||||||
|
|
||||||
loadReports();
|
tabs.forEach(tab => {
|
||||||
loadStats();
|
tab.addEventListener('click', () => switchTab(tab.dataset.tab));
|
||||||
|
});
|
||||||
|
|
||||||
|
switchTab('overview');
|
||||||
feather.replace();
|
feather.replace();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue