소스 검색

Use status components for true/false things

Jamie Curnow 1 개월 전
부모
커밋
0f718570d6

+ 6 - 9
frontend/src/components/Table/Formatter/CertificateInUseFormatter.tsx

@@ -1,6 +1,7 @@
 import OverlayTrigger from "react-bootstrap/OverlayTrigger";
 import Popover from "react-bootstrap/Popover";
 import type { DeadHost, ProxyHost, RedirectionHost, Stream } from "src/api/backend";
+import { TrueFalseFormatter } from "src/components";
 import { T } from "src/locale";
 
 const getSection = (title: string, items: ProxyHost[] | RedirectionHost[] | DeadHost[]) => {
@@ -52,11 +53,7 @@ interface Props {
 export function CertificateInUseFormatter({ proxyHosts, redirectionHosts, deadHosts, streams }: Props) {
 	const totalCount = proxyHosts?.length + redirectionHosts?.length + deadHosts?.length + streams?.length;
 	if (totalCount === 0) {
-		return (
-			<span className="badge bg-red-lt">
-				<T id="certificate.not-in-use" />
-			</span>
-		);
+		return <TrueFalseFormatter value={false} falseLabel="certificate.not-in-use" />;
 	}
 
 	proxyHosts.sort();
@@ -76,10 +73,10 @@ export function CertificateInUseFormatter({ proxyHosts, redirectionHosts, deadHo
 	);
 
 	return (
-		<OverlayTrigger trigger="hover" placement="bottom" overlay={popover}>
-			<span className="badge bg-lime-lt">
-				<T id="certificate.in-use" />
-			</span>
+		<OverlayTrigger trigger={["hover", "click", "focus"]} placement="bottom" overlay={popover}>
+			<div>
+				<TrueFalseFormatter value trueLabel="certificate.in-use" />
+			</div>
 		</OverlayTrigger>
 	);
 }

+ 6 - 5
frontend/src/components/Table/Formatter/DomainsFormatter.tsx

@@ -1,3 +1,4 @@
+import cn from "classnames";
 import type { ReactNode } from "react";
 import { DateTimeFormat, T } from "src/locale";
 
@@ -6,9 +7,10 @@ interface Props {
 	createdOn?: string;
 	niceName?: string;
 	provider?: string;
+	color?: string;
 }
 
-const DomainLink = ({ domain }: { domain: string }) => {
+const DomainLink = ({ domain, color }: { domain: string; color?: string }) => {
 	// when domain contains a wildcard, make the link go nowhere.
 	let onClick: ((e: React.MouseEvent) => void) | undefined;
 	if (domain.includes("*")) {
@@ -20,15 +22,14 @@ const DomainLink = ({ domain }: { domain: string }) => {
 			href={`http://${domain}`}
 			target="_blank"
 			onClick={onClick}
-			className="badge bg-yellow-lt domain-name me-2"
+			className={cn("badge", color ? `bg-${color}-lt` : null, "domain-name", "me-2")}
 		>
 			{domain}
 		</a>
 	);
 };
 
-export function DomainsFormatter({ domains, createdOn, niceName, provider }: Props) {
-	console.log("PROVIDER:", provider);
+export function DomainsFormatter({ domains, createdOn, niceName, provider, color }: Props) {
 	const elms: ReactNode[] = [];
 	if (domains.length === 0 && !niceName) {
 		elms.push(
@@ -45,7 +46,7 @@ export function DomainsFormatter({ domains, createdOn, niceName, provider }: Pro
 		);
 	}
 
-	domains.map((domain: string) => elms.push(<DomainLink key={domain} domain={domain} />));
+	domains.map((domain: string) => elms.push(<DomainLink key={domain} domain={domain} color={color} />));
 
 	return (
 		<div className="flex-fill">

+ 0 - 13
frontend/src/components/Table/Formatter/EnabledFormatter.tsx

@@ -1,13 +0,0 @@
-import cn from "classnames";
-import { T } from "src/locale";
-
-interface Props {
-	enabled: boolean;
-}
-export function EnabledFormatter({ enabled }: Props) {
-	return (
-		<span className={cn("badge", enabled ? "bg-lime-lt" : "bg-red-lt")}>
-			<T id={enabled ? "enabled" : "disabled"} />
-		</span>
-	);
-}

+ 0 - 13
frontend/src/components/Table/Formatter/StatusFormatter.tsx

@@ -1,13 +0,0 @@
-import cn from "classnames";
-import { T } from "src/locale";
-
-interface Props {
-	enabled: boolean;
-}
-export function StatusFormatter({ enabled }: Props) {
-	return (
-		<span className={cn("badge", enabled ? "bg-lime-lt" : "bg-red-lt")}>
-			<T id={enabled ? "online" : "offline"} />
-		</span>
-	);
-}

+ 24 - 0
frontend/src/components/Table/Formatter/TrueFalseFormatter.tsx

@@ -0,0 +1,24 @@
+import cn from "classnames";
+import { T } from "src/locale";
+
+interface Props {
+	value: boolean;
+	trueLabel?: string;
+	trueColor?: string;
+	falseLabel?: string;
+	falseColor?: string;
+}
+export function TrueFalseFormatter({
+	value,
+	trueLabel = "enabled",
+	trueColor = "lime",
+	falseLabel = "disabled",
+	falseColor = "red",
+}: Props) {
+	return (
+		<span className={cn("status", `status-${value ? trueColor : falseColor}`)}>
+			<span className="status-dot status-dot-animated" />
+			<T id={value ? trueLabel : falseLabel} />
+		</span>
+	);
+}

+ 1 - 2
frontend/src/components/Table/Formatter/index.ts

@@ -4,9 +4,8 @@ export * from "./CertificateInUseFormatter";
 export * from "./DateFormatter";
 export * from "./DomainsFormatter";
 export * from "./EmailFormatter";
-export * from "./EnabledFormatter";
 export * from "./EventFormatter";
 export * from "./GravatarFormatter";
 export * from "./RolesFormatter";
-export * from "./StatusFormatter";
+export * from "./TrueFalseFormatter";
 export * from "./ValueWithDateFormatter";

+ 1 - 1
frontend/src/pages/Dashboard/index.tsx

@@ -116,6 +116,7 @@ const Dashboard = () => {
 				<code>{`Todo:
 
 - check mobile
+- use statuses for table formatters where applicable: https://docs.tabler.io/ui/components/statuses
 - add help docs for host types
 - REDO SCREENSHOTS in docs folder
 - search codebase for "TODO"
@@ -125,7 +126,6 @@ const Dashboard = () => {
 
 More for api, then implement here:
 - Add error message_18n for all backend errors
-- minor: certificates expand with hosts needs to omit 'is_deleted'
 - properly wrap all logger.debug called in isDebug check
 - add new api endpoint changes to swagger docs
 

+ 8 - 2
frontend/src/pages/Nginx/DeadHosts/Table.tsx

@@ -2,7 +2,13 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-
 import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
 import { useMemo } from "react";
 import type { DeadHost } from "src/api/backend";
-import { CertificateFormatter, DomainsFormatter, EmptyData, GravatarFormatter, StatusFormatter } from "src/components";
+import {
+	CertificateFormatter,
+	DomainsFormatter,
+	EmptyData,
+	GravatarFormatter,
+	TrueFalseFormatter,
+} from "src/components";
 import { TableLayout } from "src/components/Table/TableLayout";
 import { intl, T } from "src/locale";
 
@@ -48,7 +54,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
 				id: "enabled",
 				header: intl.formatMessage({ id: "column.status" }),
 				cell: (info: any) => {
-					return <StatusFormatter enabled={info.getValue()} />;
+					return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
 				},
 			}),
 			columnHelper.display({

+ 2 - 2
frontend/src/pages/Nginx/ProxyHosts/Table.tsx

@@ -8,7 +8,7 @@ import {
 	DomainsFormatter,
 	EmptyData,
 	GravatarFormatter,
-	StatusFormatter,
+	TrueFalseFormatter,
 } from "src/components";
 import { TableLayout } from "src/components/Table/TableLayout";
 import { intl, T } from "src/locale";
@@ -70,7 +70,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
 				id: "enabled",
 				header: intl.formatMessage({ id: "column.status" }),
 				cell: (info: any) => {
-					return <StatusFormatter enabled={info.getValue()} />;
+					return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
 				},
 			}),
 			columnHelper.display({

+ 8 - 2
frontend/src/pages/Nginx/RedirectionHosts/Table.tsx

@@ -2,7 +2,13 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-
 import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
 import { useMemo } from "react";
 import type { RedirectionHost } from "src/api/backend";
-import { CertificateFormatter, DomainsFormatter, EmptyData, GravatarFormatter, StatusFormatter } from "src/components";
+import {
+	CertificateFormatter,
+	DomainsFormatter,
+	EmptyData,
+	GravatarFormatter,
+	TrueFalseFormatter,
+} from "src/components";
 import { TableLayout } from "src/components/Table/TableLayout";
 import { intl, T } from "src/locale";
 
@@ -69,7 +75,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
 				id: "enabled",
 				header: intl.formatMessage({ id: "column.status" }),
 				cell: (info: any) => {
-					return <StatusFormatter enabled={info.getValue()} />;
+					return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
 				},
 			}),
 			columnHelper.display({

+ 2 - 2
frontend/src/pages/Nginx/Streams/Table.tsx

@@ -6,7 +6,7 @@ import {
 	CertificateFormatter,
 	EmptyData,
 	GravatarFormatter,
-	StatusFormatter,
+	TrueFalseFormatter,
 	ValueWithDateFormatter,
 } from "src/components";
 import { TableLayout } from "src/components/Table/TableLayout";
@@ -83,7 +83,7 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete,
 				id: "enabled",
 				header: intl.formatMessage({ id: "column.status" }),
 				cell: (info: any) => {
-					return <StatusFormatter enabled={info.getValue()} />;
+					return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
 				},
 			}),
 			columnHelper.display({

+ 2 - 2
frontend/src/pages/Users/Table.tsx

@@ -5,9 +5,9 @@ import type { User } from "src/api/backend";
 import {
 	EmailFormatter,
 	EmptyData,
-	EnabledFormatter,
 	GravatarFormatter,
 	RolesFormatter,
+	TrueFalseFormatter,
 	ValueWithDateFormatter,
 } from "src/components";
 import { TableLayout } from "src/components/Table/TableLayout";
@@ -83,7 +83,7 @@ export default function Table({
 				id: "isDisabled",
 				header: intl.formatMessage({ id: "column.status" }),
 				cell: (info: any) => {
-					return <EnabledFormatter enabled={!info.getValue()} />;
+					return <TrueFalseFormatter value={!info.getValue()} />;
 				},
 			}),
 			columnHelper.display({