You've already forked nginx-proxy-manager
mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-10-30 18:05:34 +03:00
Use status components for true/false things
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
|
import OverlayTrigger from "react-bootstrap/OverlayTrigger";
|
||||||
import Popover from "react-bootstrap/Popover";
|
import Popover from "react-bootstrap/Popover";
|
||||||
import type { DeadHost, ProxyHost, RedirectionHost, Stream } from "src/api/backend";
|
import type { DeadHost, ProxyHost, RedirectionHost, Stream } from "src/api/backend";
|
||||||
|
import { TrueFalseFormatter } from "src/components";
|
||||||
import { T } from "src/locale";
|
import { T } from "src/locale";
|
||||||
|
|
||||||
const getSection = (title: string, items: ProxyHost[] | RedirectionHost[] | DeadHost[]) => {
|
const getSection = (title: string, items: ProxyHost[] | RedirectionHost[] | DeadHost[]) => {
|
||||||
@@ -52,11 +53,7 @@ interface Props {
|
|||||||
export function CertificateInUseFormatter({ proxyHosts, redirectionHosts, deadHosts, streams }: Props) {
|
export function CertificateInUseFormatter({ proxyHosts, redirectionHosts, deadHosts, streams }: Props) {
|
||||||
const totalCount = proxyHosts?.length + redirectionHosts?.length + deadHosts?.length + streams?.length;
|
const totalCount = proxyHosts?.length + redirectionHosts?.length + deadHosts?.length + streams?.length;
|
||||||
if (totalCount === 0) {
|
if (totalCount === 0) {
|
||||||
return (
|
return <TrueFalseFormatter value={false} falseLabel="certificate.not-in-use" />;
|
||||||
<span className="badge bg-red-lt">
|
|
||||||
<T id="certificate.not-in-use" />
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyHosts.sort();
|
proxyHosts.sort();
|
||||||
@@ -76,10 +73,10 @@ export function CertificateInUseFormatter({ proxyHosts, redirectionHosts, deadHo
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OverlayTrigger trigger="hover" placement="bottom" overlay={popover}>
|
<OverlayTrigger trigger={["hover", "click", "focus"]} placement="bottom" overlay={popover}>
|
||||||
<span className="badge bg-lime-lt">
|
<div>
|
||||||
<T id="certificate.in-use" />
|
<TrueFalseFormatter value trueLabel="certificate.in-use" />
|
||||||
</span>
|
</div>
|
||||||
</OverlayTrigger>
|
</OverlayTrigger>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import cn from "classnames";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { DateTimeFormat, T } from "src/locale";
|
import { DateTimeFormat, T } from "src/locale";
|
||||||
|
|
||||||
@@ -6,9 +7,10 @@ interface Props {
|
|||||||
createdOn?: string;
|
createdOn?: string;
|
||||||
niceName?: string;
|
niceName?: string;
|
||||||
provider?: 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.
|
// when domain contains a wildcard, make the link go nowhere.
|
||||||
let onClick: ((e: React.MouseEvent) => void) | undefined;
|
let onClick: ((e: React.MouseEvent) => void) | undefined;
|
||||||
if (domain.includes("*")) {
|
if (domain.includes("*")) {
|
||||||
@@ -20,15 +22,14 @@ const DomainLink = ({ domain }: { domain: string }) => {
|
|||||||
href={`http://${domain}`}
|
href={`http://${domain}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className="badge bg-yellow-lt domain-name me-2"
|
className={cn("badge", color ? `bg-${color}-lt` : null, "domain-name", "me-2")}
|
||||||
>
|
>
|
||||||
{domain}
|
{domain}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DomainsFormatter({ domains, createdOn, niceName, provider }: Props) {
|
export function DomainsFormatter({ domains, createdOn, niceName, provider, color }: Props) {
|
||||||
console.log("PROVIDER:", provider);
|
|
||||||
const elms: ReactNode[] = [];
|
const elms: ReactNode[] = [];
|
||||||
if (domains.length === 0 && !niceName) {
|
if (domains.length === 0 && !niceName) {
|
||||||
elms.push(
|
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 (
|
return (
|
||||||
<div className="flex-fill">
|
<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 "./DateFormatter";
|
||||||
export * from "./DomainsFormatter";
|
export * from "./DomainsFormatter";
|
||||||
export * from "./EmailFormatter";
|
export * from "./EmailFormatter";
|
||||||
export * from "./EnabledFormatter";
|
|
||||||
export * from "./EventFormatter";
|
export * from "./EventFormatter";
|
||||||
export * from "./GravatarFormatter";
|
export * from "./GravatarFormatter";
|
||||||
export * from "./RolesFormatter";
|
export * from "./RolesFormatter";
|
||||||
export * from "./StatusFormatter";
|
export * from "./TrueFalseFormatter";
|
||||||
export * from "./ValueWithDateFormatter";
|
export * from "./ValueWithDateFormatter";
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ const Dashboard = () => {
|
|||||||
<code>{`Todo:
|
<code>{`Todo:
|
||||||
|
|
||||||
- check mobile
|
- check mobile
|
||||||
|
- use statuses for table formatters where applicable: https://docs.tabler.io/ui/components/statuses
|
||||||
- add help docs for host types
|
- add help docs for host types
|
||||||
- REDO SCREENSHOTS in docs folder
|
- REDO SCREENSHOTS in docs folder
|
||||||
- search codebase for "TODO"
|
- search codebase for "TODO"
|
||||||
@@ -125,7 +126,6 @@ const Dashboard = () => {
|
|||||||
|
|
||||||
More for api, then implement here:
|
More for api, then implement here:
|
||||||
- Add error message_18n for all backend errors
|
- 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
|
- properly wrap all logger.debug called in isDebug check
|
||||||
- add new api endpoint changes to swagger docs
|
- 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 { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import type { DeadHost } from "src/api/backend";
|
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 { TableLayout } from "src/components/Table/TableLayout";
|
||||||
import { intl, T } from "src/locale";
|
import { intl, T } from "src/locale";
|
||||||
|
|
||||||
@@ -48,7 +54,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
|||||||
id: "enabled",
|
id: "enabled",
|
||||||
header: intl.formatMessage({ id: "column.status" }),
|
header: intl.formatMessage({ id: "column.status" }),
|
||||||
cell: (info: any) => {
|
cell: (info: any) => {
|
||||||
return <StatusFormatter enabled={info.getValue()} />;
|
return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
DomainsFormatter,
|
DomainsFormatter,
|
||||||
EmptyData,
|
EmptyData,
|
||||||
GravatarFormatter,
|
GravatarFormatter,
|
||||||
StatusFormatter,
|
TrueFalseFormatter,
|
||||||
} from "src/components";
|
} from "src/components";
|
||||||
import { TableLayout } from "src/components/Table/TableLayout";
|
import { TableLayout } from "src/components/Table/TableLayout";
|
||||||
import { intl, T } from "src/locale";
|
import { intl, T } from "src/locale";
|
||||||
@@ -70,7 +70,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
|||||||
id: "enabled",
|
id: "enabled",
|
||||||
header: intl.formatMessage({ id: "column.status" }),
|
header: intl.formatMessage({ id: "column.status" }),
|
||||||
cell: (info: any) => {
|
cell: (info: any) => {
|
||||||
return <StatusFormatter enabled={info.getValue()} />;
|
return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-
|
|||||||
import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import type { RedirectionHost } from "src/api/backend";
|
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 { TableLayout } from "src/components/Table/TableLayout";
|
||||||
import { intl, T } from "src/locale";
|
import { intl, T } from "src/locale";
|
||||||
|
|
||||||
@@ -69,7 +75,7 @@ export default function Table({ data, isFetching, onEdit, onDelete, onDisableTog
|
|||||||
id: "enabled",
|
id: "enabled",
|
||||||
header: intl.formatMessage({ id: "column.status" }),
|
header: intl.formatMessage({ id: "column.status" }),
|
||||||
cell: (info: any) => {
|
cell: (info: any) => {
|
||||||
return <StatusFormatter enabled={info.getValue()} />;
|
return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
CertificateFormatter,
|
CertificateFormatter,
|
||||||
EmptyData,
|
EmptyData,
|
||||||
GravatarFormatter,
|
GravatarFormatter,
|
||||||
StatusFormatter,
|
TrueFalseFormatter,
|
||||||
ValueWithDateFormatter,
|
ValueWithDateFormatter,
|
||||||
} from "src/components";
|
} from "src/components";
|
||||||
import { TableLayout } from "src/components/Table/TableLayout";
|
import { TableLayout } from "src/components/Table/TableLayout";
|
||||||
@@ -83,7 +83,7 @@ export default function Table({ data, isFetching, isFiltered, onEdit, onDelete,
|
|||||||
id: "enabled",
|
id: "enabled",
|
||||||
header: intl.formatMessage({ id: "column.status" }),
|
header: intl.formatMessage({ id: "column.status" }),
|
||||||
cell: (info: any) => {
|
cell: (info: any) => {
|
||||||
return <StatusFormatter enabled={info.getValue()} />;
|
return <TrueFalseFormatter value={info.getValue()} trueLabel="online" falseLabel="offline" />;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import type { User } from "src/api/backend";
|
|||||||
import {
|
import {
|
||||||
EmailFormatter,
|
EmailFormatter,
|
||||||
EmptyData,
|
EmptyData,
|
||||||
EnabledFormatter,
|
|
||||||
GravatarFormatter,
|
GravatarFormatter,
|
||||||
RolesFormatter,
|
RolesFormatter,
|
||||||
|
TrueFalseFormatter,
|
||||||
ValueWithDateFormatter,
|
ValueWithDateFormatter,
|
||||||
} from "src/components";
|
} from "src/components";
|
||||||
import { TableLayout } from "src/components/Table/TableLayout";
|
import { TableLayout } from "src/components/Table/TableLayout";
|
||||||
@@ -83,7 +83,7 @@ export default function Table({
|
|||||||
id: "isDisabled",
|
id: "isDisabled",
|
||||||
header: intl.formatMessage({ id: "column.status" }),
|
header: intl.formatMessage({ id: "column.status" }),
|
||||||
cell: (info: any) => {
|
cell: (info: any) => {
|
||||||
return <EnabledFormatter enabled={!info.getValue()} />;
|
return <TrueFalseFormatter value={!info.getValue()} />;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.display({
|
columnHelper.display({
|
||||||
|
|||||||
Reference in New Issue
Block a user