mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
feature (admin): activity graph
This commit is contained in:
parent
dce68b81a3
commit
79aaf52dbd
4 changed files with 83 additions and 3 deletions
|
|
@ -3,6 +3,7 @@ import { createElement, createRender } from "../../lib/skeleton/index.js";
|
||||||
import { initConfig } from "./model_config.js";
|
import { initConfig } from "./model_config.js";
|
||||||
import componentLogForm from "./ctrl_activity_form.js";
|
import componentLogForm from "./ctrl_activity_form.js";
|
||||||
import componentLogViewer from "./ctrl_activity_viewer.js";
|
import componentLogViewer from "./ctrl_activity_viewer.js";
|
||||||
|
import componentLogGraph from "./ctrl_activity_graph.js";
|
||||||
import componentAuditor from "./ctrl_activity_audit.js";
|
import componentAuditor from "./ctrl_activity_audit.js";
|
||||||
import transition from "./animate.js";
|
import transition from "./animate.js";
|
||||||
import AdminHOC from "./decorator.js";
|
import AdminHOC from "./decorator.js";
|
||||||
|
|
@ -10,11 +11,12 @@ import AdminHOC from "./decorator.js";
|
||||||
export default AdminHOC(async function(render) {
|
export default AdminHOC(async function(render) {
|
||||||
const $page = createElement(`
|
const $page = createElement(`
|
||||||
<div class="component_logpage sticky">
|
<div class="component_logpage sticky">
|
||||||
<h2>Events</h2>
|
<h2>System Logs</h2>
|
||||||
<div class="component_logviewer"></div>
|
<div class="component_logviewer"></div>
|
||||||
|
<div class="component_stats"></div>
|
||||||
<div class="component_logger"></div>
|
<div class="component_logger"></div>
|
||||||
|
|
||||||
<h2>Activity Report</h2>
|
<h2>Audit Report</h2>
|
||||||
<div class="component_audit"></div>
|
<div class="component_audit"></div>
|
||||||
<div>
|
<div>
|
||||||
`);
|
`);
|
||||||
|
|
@ -23,5 +25,6 @@ export default AdminHOC(async function(render) {
|
||||||
|
|
||||||
componentLogViewer(createRender($page.querySelector(".component_logviewer")));
|
componentLogViewer(createRender($page.querySelector(".component_logviewer")));
|
||||||
componentLogForm(createRender($page.querySelector(".component_logger")));
|
componentLogForm(createRender($page.querySelector(".component_logger")));
|
||||||
|
componentLogGraph(createRender($page.querySelector(".component_stats")));
|
||||||
componentAuditor(createRender($page.querySelector(".component_audit")));
|
componentAuditor(createRender($page.querySelector(".component_audit")));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
29
public/assets/pages/adminpage/ctrl_activity_graph.css
Normal file
29
public/assets/pages/adminpage/ctrl_activity_graph.css
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
.component_stats {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.component_stats .chart {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
.component_stats .chart .bar {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
border-bottom: 1px solid var(--light);
|
||||||
|
|
||||||
|
background: var(--border);
|
||||||
|
border: 2px solid var(--border);
|
||||||
|
}
|
||||||
|
.component_stats .chart .bar[title="0"], .component_stats .chart .bar[title="1"], .component_stats .chart .bar[title="2"] {
|
||||||
|
border-top-left-radius: 0px;
|
||||||
|
border-top-right-radius: 0px;
|
||||||
|
}
|
||||||
|
.component_stats .legend {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: var(--light);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
48
public/assets/pages/adminpage/ctrl_activity_graph.js
Normal file
48
public/assets/pages/adminpage/ctrl_activity_graph.js
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { createElement } from "../../lib/skeleton/index.js";
|
||||||
|
import rxjs, { effect } from "../../lib/rx.js";
|
||||||
|
import { get as getLogs } from "./model_log.js";
|
||||||
|
import { loadCSS } from "../../helpers/loader.js";
|
||||||
|
|
||||||
|
export default async function(render) {
|
||||||
|
await loadCSS(import.meta.url, "./ctrl_activity_graph.css");
|
||||||
|
|
||||||
|
effect(getLogs().pipe(
|
||||||
|
rxjs.map((log) => {
|
||||||
|
const times = log.trim().split("\n").map((line) => new Date(line.substring(0, 19)).getTime());
|
||||||
|
const start = times[0];
|
||||||
|
const end = times[times.length - 1];
|
||||||
|
|
||||||
|
const size = 30
|
||||||
|
const bars = Array(size).fill(0);
|
||||||
|
const width = (end - start) / size;
|
||||||
|
for (const t of times) {
|
||||||
|
const idx = Math.min(size - 1, Math.max(0, Math.floor((t - start) / width)));
|
||||||
|
bars[idx] += 1;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
bars,
|
||||||
|
start: new Date(start).toLocaleTimeString(),
|
||||||
|
end: new Date(end).toLocaleTimeString(),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
rxjs.tap(({ bars, start, end }) => {
|
||||||
|
const max = Math.max(1, ...bars);
|
||||||
|
const $root = document.createDocumentFragment();
|
||||||
|
const $chart = createElement(`<div class="chart"></div>`);
|
||||||
|
for (let i = 0; i < bars.length; i++) {
|
||||||
|
const $bar = createElement(`<div class="bar" title="${bars[i]}"></div>`)
|
||||||
|
$bar.style.height = Math.sqrt(bars[i]) / Math.sqrt(max) * 100 + "%";
|
||||||
|
$chart.appendChild($bar);
|
||||||
|
}
|
||||||
|
$root.appendChild($chart);
|
||||||
|
$root.appendChild(createElement(`
|
||||||
|
<div class="legend">
|
||||||
|
<span>${start}</span>
|
||||||
|
<span>${end}</span>
|
||||||
|
</div>
|
||||||
|
`));
|
||||||
|
render($root);
|
||||||
|
}),
|
||||||
|
rxjs.catchError(() => rxjs.EMPTY),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ export default async function(render) {
|
||||||
<a href="${getLogUrl()}" download="${logname()}">
|
<a href="${getLogUrl()}" download="${logname()}">
|
||||||
<button class="component_button primary">Download</button>
|
<button class="component_button primary">Download</button>
|
||||||
</a>
|
</a>
|
||||||
<br/><br/>
|
<br><br>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
const $log = qs($page, "pre");
|
const $log = qs($page, "pre");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue