History Page
This commit is contained in:
parent
113cf7cb18
commit
ffc2d2fdbe
22 changed files with 153 additions and 48 deletions
|
|
@ -16,6 +16,8 @@ replace:
|
|||
cp tmp History-*.js && \
|
||||
cat HostPage-*.js | sed 's/index-.*\.js/index.js/g' > tmp && \
|
||||
cp tmp HostPage-*.js && \
|
||||
cat MacHistory-*.js | sed 's/index-.*\.js/index.js/g' > tmp && \
|
||||
cp tmp MacHistory-*.js && \
|
||||
rm tmp index-*
|
||||
|
||||
all: build replace
|
||||
|
|
@ -1,10 +1,33 @@
|
|||
/* VARS */
|
||||
:root {
|
||||
--transparent-light: #ffffff15;
|
||||
}
|
||||
|
||||
/* Sort button */
|
||||
.my-btn {
|
||||
height: 100%;
|
||||
background-color: #00000000;
|
||||
color: var(--bs-primary);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
padding: 1px;
|
||||
border-radius: 15%;
|
||||
}
|
||||
.my-btn:hover {
|
||||
background-color: var(--transparent-light);
|
||||
}
|
||||
|
||||
/* History box */
|
||||
.my-box-on::before, .my-box-off::before {
|
||||
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='18'></svg>");
|
||||
border-left: thin solid black;
|
||||
}
|
||||
.my-box-on {
|
||||
background-color: var(--bs-success);
|
||||
}
|
||||
.my-box-off {
|
||||
background-color: var(--bs-gray-500);
|
||||
}
|
||||
.my-box-on:hover, .my-box-off:hover {
|
||||
background-color: #0000001a;
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ function TableHead() {
|
|||
return (
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 3em;"></th>
|
||||
<th style="width: 2em;"></th>
|
||||
<th>Name <i class="bi bi-sort-down-alt my-btn" onclick={[handleSort, "Name"]}></i></th>
|
||||
<th>Iface <i class="bi bi-sort-down-alt my-btn" onclick={[handleSort, "Iface"]}></i></th>
|
||||
<th>IP <i class="bi bi-sort-down-alt my-btn" onclick={[handleSort, "IP"]}></i></th>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ function TableRow(_props: any) {
|
|||
</td>
|
||||
<td>{now}</td>
|
||||
<td>
|
||||
<a href={edit}><i class="bi bi-pencil-square my-btn"></i></a>
|
||||
<a href={edit}><i class="bi bi-three-dots-vertical my-btn p-2"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
|
|
|
|||
18
frontend/src/components/HostPage/HistCard.tsx
Normal file
18
frontend/src/components/HostPage/HistCard.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import MacHistory from "../MacHistory"
|
||||
|
||||
function HistCard(_props: any) {
|
||||
|
||||
return (
|
||||
<div class="card border-primary">
|
||||
<div class="card-header">History</div>
|
||||
<div class="card-body">
|
||||
{_props.mac !== ""
|
||||
? <MacHistory mac={_props.mac}></MacHistory>
|
||||
: <>Loading...</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default HistCard
|
||||
|
|
@ -1,28 +1,27 @@
|
|||
import { apiDelHost, apiEditHost } from "../../functions/api";
|
||||
import { currentHost } from "../../functions/exports";
|
||||
|
||||
function HostCard() {
|
||||
function HostCard(_props: any) {
|
||||
|
||||
let name:string = "";
|
||||
|
||||
const handleInput = async (n: string) => {
|
||||
|
||||
name = n;
|
||||
await apiEditHost(currentHost().ID, name, '');
|
||||
await apiEditHost(_props.host.ID, name, '');
|
||||
};
|
||||
|
||||
const handleToggle = async () => {
|
||||
|
||||
if (name == "") {
|
||||
name = currentHost().Name;
|
||||
name = _props.host.Name;
|
||||
}
|
||||
|
||||
await apiEditHost(currentHost().ID, name, 'toggle');
|
||||
await apiEditHost(_props.host.ID, name, 'toggle');
|
||||
};
|
||||
|
||||
const handleDel = async () => {
|
||||
|
||||
await apiDelHost(currentHost().ID);
|
||||
await apiDelHost(_props.host.ID);
|
||||
window.location.href = '/';
|
||||
};
|
||||
|
||||
|
|
@ -34,40 +33,40 @@ function HostCard() {
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>{currentHost().ID}</td>
|
||||
<td>{_props.host.ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>
|
||||
<input type="text" class="form-control" value={currentHost().Name}
|
||||
<input type="text" class="form-control" value={_props.host.Name}
|
||||
onInput={e => handleInput(e.target.value)}></input>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DNS name</td>
|
||||
<td>{currentHost().DNS}</td>
|
||||
<td>{_props.host.DNS}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Iface</td>
|
||||
<td>{currentHost().Iface}</td>
|
||||
<td>{_props.host.Iface}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IP</td>
|
||||
<td>
|
||||
<a href={"http://" + currentHost().IP} target="_blank">{currentHost().IP}</a>
|
||||
<a href={"http://" + _props.host.IP} target="_blank">{_props.host.IP}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MAC</td>
|
||||
<td>{currentHost().Mac}</td>
|
||||
<td>{_props.host.Mac}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hardware</td>
|
||||
<td>{currentHost().Hw}</td>
|
||||
<td>{_props.host.Hw}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>{currentHost().Date}</td>
|
||||
<td>{_props.host.Date}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Known</td>
|
||||
|
|
@ -75,7 +74,7 @@ function HostCard() {
|
|||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
onClick={handleToggle}
|
||||
checked={currentHost().Known == 1
|
||||
checked={_props.host.Known == 1
|
||||
? true
|
||||
: false
|
||||
}
|
||||
|
|
@ -85,7 +84,7 @@ function HostCard() {
|
|||
</tr>
|
||||
<tr>
|
||||
<td>Online</td>
|
||||
<td>{currentHost().Now == 1
|
||||
<td>{_props.host.Now == 1
|
||||
? <i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>
|
||||
: <i class="bi bi-circle-fill" style="color:var(--bs-gray-500);"></i>
|
||||
}</td>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { createSignal, For } from "solid-js";
|
||||
import { apiPortScan } from "../../functions/api";
|
||||
import { currentHost } from "../../functions/exports";
|
||||
|
||||
|
||||
function Ping() {
|
||||
function Ping(_props: any) {
|
||||
|
||||
let stop = false;
|
||||
|
||||
|
|
@ -31,7 +29,7 @@ function Ping() {
|
|||
break;
|
||||
}
|
||||
setCurPort(i.toString());
|
||||
portOpened = await apiPortScan(currentHost().IP, i);
|
||||
portOpened = await apiPortScan(_props.IP, i);
|
||||
if (portOpened) {
|
||||
setFoundPorts([...foundPorts(), i]);
|
||||
}
|
||||
|
|
@ -67,7 +65,7 @@ function Ping() {
|
|||
}
|
||||
<div class="mt-2">
|
||||
<For each={foundPorts()}>{(port) =>
|
||||
<a class="me-4" href={"http://" + currentHost().IP + ":" + port} target="_blank">{port}</a>
|
||||
<a class="me-4" href={"http://" + _props.IP + ":" + port} target="_blank">{port}</a>
|
||||
}</For>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
29
frontend/src/components/MacHistory.tsx
Normal file
29
frontend/src/components/MacHistory.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { createSignal, For, onMount } from "solid-js";
|
||||
import { apiGetHistory } from "../functions/api";
|
||||
import { Host } from "../functions/exports";
|
||||
|
||||
function MacHistory(_props: any) {
|
||||
|
||||
const [hist, setHist] = createSignal<Host[]>([]);
|
||||
|
||||
onMount(async () => {
|
||||
let h:Host[] = [];
|
||||
h = await apiGetHistory(_props.mac);
|
||||
if (h != null) {
|
||||
h.sort((a:Host, b:Host) => (a.Date < b.Date ? 1 : -1));
|
||||
if (_props.show > 0) {
|
||||
h = h.slice(0, _props.show);
|
||||
}
|
||||
setHist(h);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<For each={hist()}>{h =>
|
||||
<i title={"Date:"+h.Date+"\nIface:"+h.Iface+"\nIP:"+h.IP+"\nKnown:"+h.Known}
|
||||
class={h.Now === 0?"my-box-off":"my-box-on"}></i>
|
||||
}</For>
|
||||
)
|
||||
}
|
||||
|
||||
export default MacHistory
|
||||
|
|
@ -60,3 +60,10 @@ export const apiPortScan = async (ip:string, port:number) => {
|
|||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const apiGetHistory = async (mac:string) => {
|
||||
const url = apiPath+'/api/history/'+mac;
|
||||
const hosts = await (await fetch(url)).json();
|
||||
|
||||
return hosts;
|
||||
};
|
||||
|
|
@ -89,5 +89,3 @@ export const [ifaces, setIfaces] = createSignal<string[]>([]);
|
|||
export const [appConfig, setAppConfig] = createSignal<Conf>(emptyConf);
|
||||
|
||||
export const [editNames, setEditNames] = createSignal(false);
|
||||
|
||||
export const [currentHost, setCurrentHost] = createSignal<Host>(emptyHost);
|
||||
|
|
@ -1,10 +1,32 @@
|
|||
import { For } from "solid-js"
|
||||
import Filter from "../components/Filter"
|
||||
import { allHosts } from "../functions/exports"
|
||||
import MacHistory from "../components/MacHistory"
|
||||
|
||||
function History() {
|
||||
|
||||
return (
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
History page
|
||||
<div class="card border-primary">
|
||||
<div class="card-header d-flex justify-left">
|
||||
<Filter></Filter>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-striped table-hover">
|
||||
<tbody>
|
||||
<For each={allHosts()}>{(host, index) =>
|
||||
<tr>
|
||||
<td class="opacity-50" style="width: 2em;">{index()}.</td>
|
||||
<td>
|
||||
<a href={"/host/"+host.ID}>{host.Name}</a><br></br>
|
||||
<a href={"http://"+host.IP}>{host.IP}</a>
|
||||
</td>
|
||||
<td>
|
||||
<MacHistory mac={host.Mac} show={200}></MacHistory>
|
||||
</td>
|
||||
</tr>
|
||||
}</For>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
import { useParams } from "@solidjs/router";
|
||||
import { onMount } from "solid-js";
|
||||
import { createSignal, onMount } from "solid-js";
|
||||
|
||||
import { apiGetHost } from "../functions/api";
|
||||
import { setCurrentHost } from "../functions/exports";
|
||||
|
||||
import HostCard from "../components/HostPage/HostCard";
|
||||
import Ping from "../components/HostPage/Ping";
|
||||
import HistCard from "../components/HostPage/HistCard";
|
||||
import { emptyHost, Host } from "../functions/exports";
|
||||
|
||||
function HostPage() {
|
||||
|
||||
const [currentHost, setCurrentHost] = createSignal<Host>(emptyHost);
|
||||
|
||||
onMount(async () => {
|
||||
const params = useParams();
|
||||
const host = await apiGetHost(params.id);
|
||||
|
|
@ -17,14 +20,21 @@ function HostPage() {
|
|||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<HostCard></HostCard>
|
||||
<HostCard host={currentHost()}></HostCard>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<Ping></Ping>
|
||||
<Ping IP={currentHost().IP}></Ping>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-md">
|
||||
<HistCard mac={currentHost().Mac}></HistCard>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,11 +54,3 @@ type Stat struct {
|
|||
Known int
|
||||
Unknown int
|
||||
}
|
||||
|
||||
// GuiData - all data sent to html page
|
||||
type GuiData struct {
|
||||
Config Conf
|
||||
Host Host
|
||||
Themes []string
|
||||
Version string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
import{t}from"./index.js";var r=t("<div class=row><div class=col-md>History page");function o(){return r()}export{o as default};
|
||||
1
internal/web/public/assets/History-DlXapsnh.js
Normal file
1
internal/web/public/assets/History-DlXapsnh.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{t as _,i as e,e as i,k as x,b as C,s as v,l as S,F}from"./index.js";var I=_('<div class="card border-primary"><div class="card-header d-flex justify-left"></div><div class=card-body><table class="table table-striped table-hover"><tbody></tbody>'),M=_("<tr><td class=opacity-50 style=width:2em;>.</td><td><a></a><br><a></a></td><td>");function j(){return(()=>{var s=I(),d=s.firstChild,$=d.nextSibling,h=$.firstChild,m=h.firstChild;return e(d,i(x,{})),e(m,i(F,{get each(){return S()},children:(t,u)=>(()=>{var n=M(),l=n.firstChild,y=l.firstChild,c=l.nextSibling,a=c.firstChild,g=a.nextSibling,o=g.nextSibling,p=c.nextSibling;return e(l,u,y),e(a,()=>t.Name),e(o,()=>t.IP),e(p,i(H,{get mac(){return t.Mac},show:200})),C(r=>{var f="/host/"+t.ID,b="http://"+t.IP;return f!==r.e&&v(a,"href",r.e=f),b!==r.t&&v(o,"href",r.t=b),r},{e:void 0,t:void 0}),n})()})),s})()}export{j as default};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{t as o,i as l,k as t,j as K,b as x,s as O,l as A,m as et,h as q,c as v,e as I,F as lt,n as it,o as nt,u as rt,p as at,q as st}from"./index.js";var dt=o('<div class="card border-primary"><div class=card-header>Host</div><div class="card-body table-responsive"><table class="table table-striped table-hover"><tbody><tr><td>ID</td><td></td></tr><tr><td>Name</td><td><input type=text class=form-control></td></tr><tr><td>DNS name</td><td></td></tr><tr><td>Iface</td><td></td></tr><tr><td>IP</td><td><a target=_blank></a></td></tr><tr><td>MAC</td><td></td></tr><tr><td>Hardware</td><td></td></tr><tr><td>Date</td><td></td></tr><tr><td>Known</td><td><div class="form-check form-switch"><input class=form-check-input type=checkbox></div></td></tr><tr><td>Online</td><td></td></tr></tbody></table><button type=button class="btn btn-outline-danger">Delete host'),ct=o('<i class="bi bi-check-circle-fill"style=color:var(--bs-success);>'),ot=o('<i class="bi bi-circle-fill"style=color:var(--bs-gray-500);>');function $t(){let e="";const s=async b=>{e=b,await A(t().ID,e,"")},$=async()=>{e==""&&(e=t().Name),await A(t().ID,e,"toggle")},C=async()=>{await et(t().ID),window.location.href="/"};return(()=>{var b=dt(),_=b.firstChild,y=_.nextSibling,u=y.firstChild,w=u.firstChild,f=w.firstChild,k=f.firstChild,n=k.nextSibling,r=f.nextSibling,c=r.firstChild,a=c.nextSibling,p=a.firstChild,g=r.nextSibling,N=g.firstChild,m=N.nextSibling,i=g.nextSibling,d=i.firstChild,S=d.nextSibling,h=i.nextSibling,B=h.firstChild,G=B.nextSibling,D=G.firstChild,H=h.nextSibling,R=H.firstChild,T=R.nextSibling,E=H.nextSibling,z=E.firstChild,J=z.nextSibling,M=E.nextSibling,L=M.firstChild,Q=L.nextSibling,F=M.nextSibling,U=F.firstChild,V=U.nextSibling,W=V.firstChild,j=W.firstChild,X=F.nextSibling,Y=X.firstChild,Z=Y.nextSibling,tt=u.nextSibling;return l(n,()=>t().ID),p.$$input=P=>s(P.target.value),l(m,()=>t().DNS),l(S,()=>t().Iface),l(D,()=>t().IP),l(T,()=>t().Mac),l(J,()=>t().Hw),l(Q,()=>t().Date),j.$$click=$,l(Z,(()=>{var P=K(()=>t().Now==1);return()=>P()?ct():ot()})()),tt.$$click=C,x(()=>O(D,"href","http://"+t().IP)),x(()=>p.value=t().Name),x(()=>j.checked=t().Known==1),b})()}q(["input","click"]);var bt=o('<div class="card border-primary"><div class=card-header>Port Scan</div><div class=card-body><form class=input-group><input type=text class=form-control placeholder=1><input type=text class=form-control placeholder=65535><button type=button class="btn btn-primary">Scan</button></form><div class=mt-2>'),_t=o('<div class="d-flex justify-content-between mt-2"><button type=button class="btn btn-warning">Stop/Continue</button><div>Scanning port: '),ut=o("<a class=me-4 target=_blank>");function ft(){let e=!1;const[s,$]=v(""),[C,b]=v(""),[_,y]=v(""),[u,w]=v([]),f=async()=>{e=!1;let n=Number(s());(Number.isNaN(n)||n<1||n>65535)&&(n=1);let r=Number(C());(Number.isNaN(r)||r<1||r>65535)&&(r=65535);let c;for(let a=n;a<=r&&!e;a++)y(a.toString()),c=await it(t().IP,a),c&&w([...u(),a])},k=()=>{e?($(_()),f()):e=!0};return(()=>{var n=bt(),r=n.firstChild,c=r.nextSibling,a=c.firstChild,p=a.firstChild,g=p.nextSibling,N=g.nextSibling,m=a.nextSibling;return p.$$input=i=>$(i.target.value),g.$$input=i=>b(i.target.value),N.$$click=f,l(c,(()=>{var i=K(()=>_()!="");return()=>i()?(()=>{var d=_t(),S=d.firstChild,h=S.nextSibling;return h.firstChild,S.$$click=k,l(h,_,null),d})():[]})(),m),l(m,I(lt,{get each(){return u()},children:i=>(()=>{var d=ut();return l(d,i),x(()=>O(d,"href","http://"+t().IP+":"+i)),d})()})),n})()}q(["input","click"]);var pt=o("<div class=row><div class=col-md></div><div class=col-md>");function ht(){return nt(async()=>{const e=rt(),s=await at(e.id);st(s)}),(()=>{var e=pt(),s=e.firstChild,$=s.nextSibling;return l(s,I($t,{})),l($,I(ft,{})),e})()}export{ht as default};
|
||||
1
internal/web/public/assets/HostPage-CWNBClYI.js
Normal file
1
internal/web/public/assets/HostPage-CWNBClYI.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{t as c,i as e,j as N,b as p,s as O,m as K,n as et,h as q,c as S,e as x,F as lt,p as it,q as rt,o as nt,u as at,r as st}from"./index.js";var ct=c('<div class="card border-primary"><div class=card-header>Host</div><div class="card-body table-responsive"><table class="table table-striped table-hover"><tbody><tr><td>ID</td><td></td></tr><tr><td>Name</td><td><input type=text class=form-control></td></tr><tr><td>DNS name</td><td></td></tr><tr><td>Iface</td><td></td></tr><tr><td>IP</td><td><a target=_blank></a></td></tr><tr><td>MAC</td><td></td></tr><tr><td>Hardware</td><td></td></tr><tr><td>Date</td><td></td></tr><tr><td>Known</td><td><div class="form-check form-switch"><input class=form-check-input type=checkbox></div></td></tr><tr><td>Online</td><td></td></tr></tbody></table><button type=button class="btn btn-outline-danger">Delete host'),ot=c('<i class="bi bi-check-circle-fill"style=color:var(--bs-success);>'),$t=c('<i class="bi bi-circle-fill"style=color:var(--bs-gray-500);>');function bt(t){let l="";const i=async u=>{l=u,await K(t.host.ID,l,"")},r=async()=>{l==""&&(l=t.host.Name),await K(t.host.ID,l,"toggle")},$=async()=>{await et(t.host.ID),window.location.href="/"};return(()=>{var u=ct(),h=u.firstChild,w=h.nextSibling,f=w.firstChild,P=f.firstChild,_=P.firstChild,I=_.firstChild,a=I.nextSibling,s=_.nextSibling,b=s.firstChild,d=b.nextSibling,g=d.firstChild,m=s.nextSibling,k=m.firstChild,C=k.nextSibling,n=m.nextSibling,o=n.firstChild,y=o.nextSibling,v=n.nextSibling,B=v.firstChild,G=B.nextSibling,D=G.firstChild,M=v.nextSibling,L=M.firstChild,R=L.nextSibling,E=M.nextSibling,T=E.firstChild,z=T.nextSibling,F=E.nextSibling,J=F.firstChild,Q=J.nextSibling,j=F.nextSibling,U=j.firstChild,V=U.nextSibling,W=V.firstChild,A=W.firstChild,X=j.nextSibling,Y=X.firstChild,Z=Y.nextSibling,tt=f.nextSibling;return e(a,()=>t.host.ID),g.$$input=H=>i(H.target.value),e(C,()=>t.host.DNS),e(y,()=>t.host.Iface),e(D,()=>t.host.IP),e(R,()=>t.host.Mac),e(z,()=>t.host.Hw),e(Q,()=>t.host.Date),A.$$click=r,e(Z,(()=>{var H=N(()=>t.host.Now==1);return()=>H()?ot():$t()})()),tt.$$click=$,p(()=>O(D,"href","http://"+t.host.IP)),p(()=>g.value=t.host.Name),p(()=>A.checked=t.host.Known==1),u})()}q(["input","click"]);var ut=c('<div class="card border-primary"><div class=card-header>Port Scan</div><div class=card-body><form class=input-group><input type=text class=form-control placeholder=1><input type=text class=form-control placeholder=65535><button type=button class="btn btn-primary">Scan</button></form><div class=mt-2>'),ht=c('<div class="d-flex justify-content-between mt-2"><button type=button class="btn btn-warning">Stop/Continue</button><div>Scanning port: '),ft=c("<a class=me-4 target=_blank>");function _t(t){let l=!1;const[i,r]=S(""),[$,u]=S(""),[h,w]=S(""),[f,P]=S([]),_=async()=>{l=!1;let a=Number(i());(Number.isNaN(a)||a<1||a>65535)&&(a=1);let s=Number($());(Number.isNaN(s)||s<1||s>65535)&&(s=65535);let b;for(let d=a;d<=s&&!l;d++)w(d.toString()),b=await it(t.IP,d),b&&P([...f(),d])},I=()=>{l?(r(h()),_()):l=!0};return(()=>{var a=ut(),s=a.firstChild,b=s.nextSibling,d=b.firstChild,g=d.firstChild,m=g.nextSibling,k=m.nextSibling,C=d.nextSibling;return g.$$input=n=>r(n.target.value),m.$$input=n=>u(n.target.value),k.$$click=_,e(b,(()=>{var n=N(()=>h()!="");return()=>n()?(()=>{var o=ht(),y=o.firstChild,v=y.nextSibling;return v.firstChild,y.$$click=I,e(v,h,null),o})():[]})(),C),e(C,x(lt,{get each(){return f()},children:n=>(()=>{var o=ft();return e(o,n),p(()=>O(o,"href","http://"+t.IP+":"+n)),o})()})),a})()}q(["input","click"]);var gt=c('<div class="card border-primary"><div class=card-header>History</div><div class=card-body>');function mt(t){return(()=>{var l=gt(),i=l.firstChild,r=i.nextSibling;return e(r,(()=>{var $=N(()=>t.mac!=="");return()=>$()?x(dt,{get mac(){return t.mac}}):"Loading..."})()),l})()}var vt=c("<div class=row><div class=col-md></div><div class=col-md>"),St=c('<div class="row mt-4"><div class=col-md>');function yt(){const[t,l]=S(rt);return nt(async()=>{const i=at(),r=await st(i.id);l(r)}),[(()=>{var i=vt(),r=i.firstChild,$=r.nextSibling;return e(r,x(bt,{get host(){return t()}})),e($,x(_t,{get IP(){return t().IP}})),i})(),(()=>{var i=St(),r=i.firstChild;return e(r,x(mt,{get mac(){return t().Mac}})),i})()]}export{yt as default};
|
||||
4
internal/web/public/assets/MacHistory-CwNdmW4v.js
Normal file
4
internal/web/public/assets/MacHistory-CwNdmW4v.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import{c,o as l,e as f,t as m,b as u,s as v,v as w,F as y,w as b}from"./index.js";var d=m("<i>");function I(n){const[r,i]=c([]);return l(async()=>{let t=[];t=await b(n.mac),t!=null&&(t.sort((a,e)=>a.Date<e.Date?1:-1),n.show>0&&(t=t.slice(0,n.show)),i(t))}),f(y,{get each(){return r()},children:t=>(()=>{var a=d();return u(e=>{var o="Date:"+t.Date+`
|
||||
Iface:`+t.Iface+`
|
||||
IP:`+t.IP+`
|
||||
Known:`+t.Known,s=t.Now===0?"my-box-off":"my-box-on";return o!==e.e&&v(a,"title",e.e=o),s!==e.t&&w(a,e.t=s),e},{e:void 0,t:void 0}),a})()})}export{I as M};
|
||||
|
|
@ -1 +1 @@
|
|||
.my-btn{height:100%;background-color:#0000;color:var(--bs-primary);text-align:center}.my-btn:hover{background-color:#0000001a}
|
||||
:root{--transparent-light: #ffffff15}.my-btn{height:100%;background-color:#0000;color:var(--bs-primary);text-align:center;cursor:pointer;padding:1px;border-radius:15%}.my-btn:hover{background-color:var(--transparent-light)}.my-box-on:before,.my-box-off:before{content:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='18'></svg>");border-left:thin solid black}.my-box-on{background-color:var(--bs-success)}.my-box-off{background-color:var(--bs-gray-500)}.my-box-on:hover,.my-box-off:hover{background-color:#0000001a}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -48,6 +48,8 @@ func Gui(dirPath, nodePath string) {
|
|||
|
||||
router.GET("/", indexHandler) // index.go
|
||||
router.GET("/config", indexHandler) // index.go
|
||||
router.GET("/history", indexHandler) // index.go
|
||||
router.GET("/host/*any", indexHandler) // index.go
|
||||
router.GET("/metrics", prometheus.Handler(&appConfig))
|
||||
|
||||
router.GET("/api/all", apiAll) // api.go
|
||||
|
|
|
|||
Loading…
Reference in a new issue