mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 07:43:33 +00:00 
			
		
		
		
	Use status components for true/false things
This commit is contained in:
		| @@ -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> | ||||
| 	); | ||||
| } | ||||
|   | ||||
| @@ -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"> | ||||
|   | ||||
| @@ -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> | ||||
| 	); | ||||
| } | ||||
| @@ -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> | ||||
| 	); | ||||
| } | ||||
| @@ -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> | ||||
| 	); | ||||
| } | ||||
| @@ -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"; | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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({ | ||||
|   | ||||
| @@ -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({ | ||||
|   | ||||
| @@ -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({ | ||||
|   | ||||
| @@ -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({ | ||||
|   | ||||
| @@ -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({ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user