Content-Length: 658750 | pFad | http://github.com/nfx/slrp/pull/129/files/d7fc8246ddbcef49edb5ec0b30eec28a32750d7e

1E Refactor type names, move components out of util by SriramKeerthi · Pull Request #129 · nfx/slrp · GitHub
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor type names, move components out of util #129

Merged
merged 2 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap-icons/font/bootstrap-icons.css";
import "bootstrap/dist/css/bootstrap.min.css";
import { NavLink, Outlet, Route, Routes } from "react-router-dom";
import "./App.css";
import React from "react";
import { Routes, Route, NavLink, Outlet } from "react-router-dom";
import { ErrorBoundary } from "./util";
import Dashboard from "./Sources";
import Proxies from "./Proxies";
import History from "./History";
import Blacklist from "./Blacklist";
import Dashboard from "./Dashboard";
import History from "./History";
import Proxies from "./Proxies";
import Reverify from "./Reverify";
import { ErrorBoundary } from "./components/ErrorBoundary";

function Header() {
return (
Expand Down
13 changes: 8 additions & 5 deletions ui/src/Blacklist.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { useState } from "react";
import { IconHeader } from "./components/IconHeader";
import { LiveFilter } from "./components/LiveFilter";
import { Facet, QueryFacets } from "./components/facets/QueryFacet";
import { Countries } from "./countries";
import { Facet, IconHeader, LiveFilter, QueryFacets, http, useTitle } from "./util";
import { http, useTitle } from "./util";

type BlacklistItem = {
type BlacklistEntry = {
Proxy: string;
Failure: string;
Sources: string[];
Expand All @@ -11,7 +14,7 @@ type BlacklistItem = {
Country: string;
};

function Item({ Proxy, Failure, Sources, Provider, ASN, Country }: BlacklistItem) {
function BlacklistItem({ Proxy, Failure, Sources, Provider, ASN, Country }: BlacklistEntry) {
const removeProxy = () => {
http.delete(`/blacklist/${Proxy.replace("//", "")}`);
return false;
Expand Down Expand Up @@ -45,7 +48,7 @@ function Item({ Proxy, Failure, Sources, Provider, ASN, Country }: BlacklistItem

export default function Blacklist() {
useTitle("Blacklist");
const [result, setResult] = useState<{ Facets?: Facet[]; Records?: BlacklistItem[] }>();
const [result, setResult] = useState<{ Facets?: Facet[]; Records?: BlacklistEntry[] }>();
return (
<div className="card blacklist table-responsive">
<LiveFilter endpoint="/blacklist" onUpdate={setResult} minDelay={10000} />
Expand All @@ -62,7 +65,7 @@ export default function Blacklist() {
<IconHeader icon="emoji-dizzy failure" title="Failure" />
</tr>
</thead>
<tbody>{result.Records && result.Records.map(r => <Item key={r.Proxy} {...r} />)}</tbody>
<tbody>{result.Records && result.Records.map(r => <BlacklistItem key={r.Proxy} {...r} />)}</tbody>
</table>
</div>
)}
Expand Down
75 changes: 33 additions & 42 deletions ui/src/Sources.tsx → ui/src/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
import { ReactNode, useState } from "react";
import { Card, IconHeader, TimeDiff, http, useInterval, useTitle } from "./util";
import { Card as CardEntry } from "./components/Card";
import { IconHeader } from "./components/IconHeader";
import { TimeDiff } from "./components/TimeDiff";
import { http, tinyNum, useInterval, useTitle } from "./util";

const overall = ["Exclusive", "Dirty", "Contribution"] as const;
const pipeline = ["Scheduled", "New", "Probing"] as const;
const stats = ["Found", "Timeouts", "Blacklisted", "Ignored"] as const;
const cols = [...pipeline, ...stats];
type Summary = Partial<ProbeProps>;

type ProbeEntry = {
Name: string;
State: string;
Progress: number;
Failure: string;
EstFinish: number;
NextRefresh: number;
UrlPrefix: string;
Homepage: string;
Scheduled: number;
New: number;
Probing: number;
Found: number;
Timeouts: number;
Blacklisted: number;
Ignored: number;
Exclusive: number;
Dirty: number;
Contribution: number;
};

type Summary = Partial<ProbeEntry>;

function successRate(v: Summary) {
if (!v["Found"]) {
Expand All @@ -20,12 +45,12 @@ function successRate(v: Summary) {
);
}

function SourceOverview({ sources }: { sources: ProbeProps[] }) {
function SourceOverview({ sources }: { sources: ProbeEntry[] }) {
const summary: Summary = {};
sources.forEach(probe =>
cols.forEach(col => {
const oldVal = summary[col];
const val = probe[col as keyof ProbeProps] as number;
const val = probe[col as keyof ProbeEntry] as number;
summary[col] = val + (oldVal ? oldVal : 0);
})
);
Expand Down Expand Up @@ -90,41 +115,7 @@ function Cols(props: Summary) {
);
}

function tinyNum(n?: number) {
if (!n) {
return 0;
}
if (n < 1000) {
return n;
} else if (n < 1000000) {
return (n / 1000).toFixed() + "k";
}
return (n / 1000000).toFixed(1) + "m";
}

type ProbeProps = {
Name: string;
State: string;
Progress: number;
Failure: string;
EstFinish: number;
NextRefresh: number;
UrlPrefix: string;
Homepage: string;
Scheduled: number;
New: number;
Probing: number;
Found: number;
Timeouts: number;
Blacklisted: number;
Ignored: number;
Exclusive: number;
Dirty: number;
Contribution: number;
};
// type ProbeProps = { [key: string]: number | string };

function Probe(props: ProbeProps) {
function Probe(props: ProbeEntry) {
const { Name, State, Progress, Failure, EstFinish, NextRefresh, UrlPrefix, Homepage } = props;
const style: Record<string, string | number> = {};
let rowClass = "";
Expand Down Expand Up @@ -157,15 +148,15 @@ function Probe(props: ProbeProps) {
);
}

type Card = {
type CardEntry = {
SriramKeerthi marked this conversation as resolved.
Show resolved Hide resolved
Name: string;
Value: string;
Increment?: number;
};

export default function Dashboard() {
useTitle("Overview");
const [dashboard, setDashboard] = useState<{ Cards: Card[]; Refresh: ProbeProps[] }>();
const [dashboard, setDashboard] = useState<{ Cards: CardEntry[]; Refresh: ProbeEntry[] }>();
const [delay, setDelay] = useState<number | undefined>(1000);
useInterval(() => {
http
Expand All @@ -182,7 +173,7 @@ export default function Dashboard() {
<div>
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3">
{dashboard.Cards.map(card => (
<Card key={card.Name} label={card.Name} value={card.Value} increment={card.Increment} />
<CardEntry key={card.Name} label={card.Name} value={card.Value} increment={card.Increment} />
))}
</div>
<SourceOverview sources={dashboard.Refresh} />
Expand Down
41 changes: 22 additions & 19 deletions ui/src/History.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useState } from "react";
import "./History.css";
import { Facet, IconHeader, LiveFilter, QueryFacets, useTitle } from "./util";
import { IconHeader } from "./components/IconHeader";
import { LiveFilter } from "./components/LiveFilter";
import { Facet, QueryFacets } from "./components/facets/QueryFacet";
import { useTitle } from "./util";

function convertSize(bytes: number) {
if (bytes < 1024) {
Expand All @@ -11,7 +14,7 @@ function convertSize(bytes: number) {
return `${(bytes / 1024 / 1024).toFixed()}mb`;
}

type RequestProps = {
type HistoryEntry = {
ID: string;
Serial: number;
Attempt: number;
Expand All @@ -26,53 +29,53 @@ type RequestProps = {
Took: number;
};

function Request(props: RequestProps) {
const pos = props.URL.indexOf("/", 9);
const path = props.URL.substring(pos);
function Request(history: HistoryEntry) {
const pos = history.URL.indexOf("/", 9);
const path = history.URL.substring(pos);

let color = "text-muted";
if (props.StatusCode < 300) {
if (history.StatusCode < 300) {
color = "text-success";
} else if (props.StatusCode < 500) {
} else if (history.StatusCode < 500) {
color = "text-warning";
}
// TODO: add links in backend
return (
<tr className="list-group-item-action">
<td className="text-muted">
<small>{new Date(props.Ts).toLocaleTimeString()}</small>
<small>{new Date(history.Ts).toLocaleTimeString()}</small>
</td>
<td>
<span className="request">
{props.Method}{" "}
<a className="app-link" href={`http://localhost:8089/api/history/${props.ID}?format=text`} rel="noreferrer" target="_blank">
<abbr title={props.URL}>{path}</abbr>
{history.Method}{" "}
<a className="app-link" href={`http://localhost:8089/api/history/${history.ID}?format=text`} rel="noreferrer" target="_blank">
<abbr title={history.URL}>{path}</abbr>
</a>
<sup>
<a className="text-muted" href={`/history?filter=Serial:${props.Serial}`}>
{props.Serial}
<a className="text-muted" href={`/history?filter=Serial:${history.Serial}`}>
{history.Serial}
</a>
</sup>
</span>
</td>
<td className={color}>
{props.StatusCode === 200 ? 200 : <abbr title={props.Status}>{props.StatusCode}</abbr>} <sup>{props.Attempt}</sup>
{history.StatusCode === 200 ? 200 : <abbr title={history.Status}>{history.StatusCode}</abbr>} <sup>{history.Attempt}</sup>
</td>
<td className="text-muted proxy">
<a className="link-primary app-link" href={`/history?filter=Proxy:"${Proxy}"`}>
{props.Proxy}
{history.Proxy}
</a>{" "}
<sup>{props.Appeared}</sup>
<sup>{history.Appeared}</sup>
</td>
<td className="size">{convertSize(props.Size)}</td>
<td className="took">{props.Took}s</td>
<td className="size">{convertSize(history.Size)}</td>
<td className="took">{history.Took}s</td>
</tr>
);
}

export default function History() {
useTitle("History");
const [result, setResult] = useState<{ facets: Facet[]; Records?: RequestProps[] }>();
const [result, setResult] = useState<{ facets: Facet[]; Records?: HistoryEntry[] }>();
return (
<div id="history-table" className="card history table-responsive">
<LiveFilter endpoint="/history" onUpdate={setResult} minDelay={2000} />
Expand Down
9 changes: 6 additions & 3 deletions ui/src/Proxies.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { LiveFilter, QueryFacets, TimeDiff, http, IconHeader, useTitle, Facet } from "./util";
import { Countries } from "./countries";
import { useState } from "react";
import React from "react";
import { IconHeader } from "./components/IconHeader";
import { LiveFilter } from "./components/LiveFilter";
import { TimeDiff } from "./components/TimeDiff";
import { Facet, QueryFacets } from "./components/facets/QueryFacet";
import { Countries } from "./countries";
import { http, useTitle } from "./util";

export default function Proxies() {
useTitle("Proxies");
Expand Down
15 changes: 9 additions & 6 deletions ui/src/Reverify.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { useState } from "react";
import { IconHeader } from "./components/IconHeader";
import { LiveFilter } from "./components/LiveFilter";
import { Facet, QueryFacets } from "./components/facets/QueryFacet";
import { Countries } from "./countries";
import { Facet, IconHeader, LiveFilter, QueryFacets, http, useTitle } from "./util";
import { http, useTitle } from "./util";

type ReverifyItem = {
type ReverifyEntry = {
Proxy: string;
Sources: string[];
Provider: string;
Expand All @@ -11,7 +14,7 @@ type ReverifyItem = {
Attempt: number;
};

function Item({ Proxy, Sources, Provider, ASN, Country, Attempt }: ReverifyItem) {
function ReverifyItem({ Proxy, Sources, Provider, ASN, Country, Attempt }: ReverifyEntry) {
const removeProxy = () => {
http.delete(`/blacklist/${Proxy.replace("//", "")}`);
return false;
Expand Down Expand Up @@ -45,11 +48,11 @@ function Item({ Proxy, Sources, Provider, ASN, Country, Attempt }: ReverifyItem)

export default function Reverify() {
useTitle("Reverify");
const [result, setResult] = useState<{ Facets: Facet[]; Records?: ReverifyItem[] }>();
const [result, setResult] = useState<{ Facets: Facet[]; Records?: ReverifyEntry[] }>();
return (
<div className="card blacklist table-responsive">
<LiveFilter endpoint="/reverify" onUpdate={setResult} minDelay={10000} />
{result != null && (
{result && (
<div>
<QueryFacets endpoint="/reverify" {...result} />
<table className="table text-start table-sm">
Expand All @@ -62,7 +65,7 @@ export default function Reverify() {
<IconHeader icon="hdd-network attempt" title="Attempt" />
</tr>
</thead>
<tbody>{result.Records && result.Records.map(r => <Item key={r.Proxy} {...r} />)}</tbody>
<tbody>{result.Records && result.Records.map(r => <ReverifyItem key={r.Proxy} {...r} />)}</tbody>
</table>
</div>
)}
Expand Down
23 changes: 23 additions & 0 deletions ui/src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export type CardProps = {
label: string;
value: string;
increment?: number;
};

export function Card({ label, value, increment = 0 }: CardProps) {
return (
<div className="col">
<div className="card mb-3">
<div className="card-body">
<div className="row align-items-center gx-0">
<div className="col">
<h6 className="text-uppercase text-muted mb-2">{label}</h6>
<span className="h2 mb-0 ">{value}</span>
{increment > 0 && <span className="badge bg-success ms-2">+{increment}</span>}
</div>
</div>
</div>
</div>
</div>
);
}
26 changes: 26 additions & 0 deletions ui/src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from "react";
import { Component } from "react";

export class ErrorBoundary extends Component<{ children: React.ReactNode }> {
state = { error: false, errorMessage: "" };

static getDerivedStateFromError(error: any) {
return { error: true, errorMessage: error.toString() };
}

componentDidCatch(error: any) {
console.error(error);
}

render() {
if (this.state.error) {
return (
<div className="alert alert-danger" role="alert">
<h4 className="alert-heading">Failed</h4>
{this.state.errorMessage}
</div>
);
}
return this.props.children;
}
}
8 changes: 8 additions & 0 deletions ui/src/components/IconHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function IconHeader({ icon, col, title }: { icon: string; col?: string; title: string }) {
const cl = `bi bi-${icon}`;
return (
<th className={`col-${col}`}>
<i className={cl} title={title} />
</th>
);
}
Loading








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/nfx/slrp/pull/129/files/d7fc8246ddbcef49edb5ec0b30eec28a32750d7e

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy