milestone 23 s3: convert features/dashboard/UpstreamHealthTable.tsx to stylex
This commit is contained in:
@@ -1,64 +1,150 @@
|
|||||||
|
import * as stylex from "@stylexjs/stylex";
|
||||||
import type { UpstreamHealth } from "@/lib/types";
|
import type { UpstreamHealth } from "@/lib/types";
|
||||||
|
import { styles as shared } from "@/ui/styles";
|
||||||
|
import { colors } from "@/ui/tokens.stylex";
|
||||||
|
|
||||||
|
const styles = stylex.create({
|
||||||
|
card: {
|
||||||
|
borderRadius: "0.25rem",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderStyle: "solid",
|
||||||
|
borderColor: colors.border,
|
||||||
|
backgroundColor: colors.surfaceRaised,
|
||||||
|
},
|
||||||
|
heading: {
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "baseline",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
paddingInline: "1rem",
|
||||||
|
paddingTop: "0.75rem",
|
||||||
|
fontSize: "0.875rem",
|
||||||
|
lineHeight: "1.25rem",
|
||||||
|
fontWeight: 600,
|
||||||
|
},
|
||||||
|
count: {
|
||||||
|
fontSize: "0.75rem",
|
||||||
|
lineHeight: "1rem",
|
||||||
|
fontWeight: 400,
|
||||||
|
color: colors.textMuted,
|
||||||
|
},
|
||||||
|
empty: {
|
||||||
|
paddingInline: "1rem",
|
||||||
|
paddingBlock: "0.75rem",
|
||||||
|
fontSize: "0.875rem",
|
||||||
|
lineHeight: "1.25rem",
|
||||||
|
color: colors.textMuted,
|
||||||
|
},
|
||||||
|
tableWrap: {
|
||||||
|
overflowX: "auto",
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
marginTop: "0.5rem",
|
||||||
|
width: "100%",
|
||||||
|
fontSize: "0.875rem",
|
||||||
|
lineHeight: "1.25rem",
|
||||||
|
},
|
||||||
|
headRow: {
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomStyle: "solid",
|
||||||
|
borderBottomColor: colors.border,
|
||||||
|
textAlign: "left",
|
||||||
|
fontSize: "0.75rem",
|
||||||
|
lineHeight: "1rem",
|
||||||
|
color: colors.textMuted,
|
||||||
|
},
|
||||||
|
th: {
|
||||||
|
paddingInline: "1rem",
|
||||||
|
paddingBlock: "0.5rem",
|
||||||
|
fontWeight: 500,
|
||||||
|
},
|
||||||
|
thRight: {
|
||||||
|
textAlign: "right",
|
||||||
|
},
|
||||||
|
/** No hairline under the last row: the card border already closes the table. */
|
||||||
|
row: {
|
||||||
|
borderBottomWidth: { default: 1, ":last-child": 0 },
|
||||||
|
borderBottomStyle: "solid",
|
||||||
|
borderBottomColor: colors.border,
|
||||||
|
},
|
||||||
|
cell: {
|
||||||
|
paddingInline: "1rem",
|
||||||
|
paddingBlock: "0.5rem",
|
||||||
|
},
|
||||||
|
cellRight: {
|
||||||
|
textAlign: "right",
|
||||||
|
},
|
||||||
|
small: {
|
||||||
|
fontSize: "0.75rem",
|
||||||
|
lineHeight: "1rem",
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
color: colors.textMuted,
|
||||||
|
},
|
||||||
|
bad: {
|
||||||
|
color: colors.danger,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function YesNo({ value, badValue }: { value: boolean; badValue: boolean }) {
|
function YesNo({ value, badValue }: { value: boolean; badValue: boolean }) {
|
||||||
const bad = value === badValue;
|
const bad = value === badValue;
|
||||||
return <span className={bad ? "text-red-700 dark:text-red-400" : ""}>{value ? "yes" : "no"}</span>;
|
return <span {...stylex.props(bad && styles.bad)}>{value ? "yes" : "no"}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function UpstreamHealthTable({ health }: { health: UpstreamHealth }) {
|
export default function UpstreamHealthTable({ health }: { health: UpstreamHealth }) {
|
||||||
return (
|
return (
|
||||||
<section className="rounded border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
|
<section {...stylex.props(styles.card)}>
|
||||||
<h2 className="flex items-baseline justify-between px-4 pt-3 text-sm font-semibold">
|
<h2 {...stylex.props(styles.heading)}>
|
||||||
Upstreams
|
Upstreams
|
||||||
<span className="text-xs font-normal text-zinc-500 tabular-nums">
|
<span {...stylex.props(styles.count, shared.tabularNums)}>
|
||||||
{health.available}/{health.total} available
|
{health.available}/{health.total} available
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
{health.upstreams.length === 0 ? (
|
{health.upstreams.length === 0 ? (
|
||||||
<p className="px-4 py-3 text-sm text-zinc-500">No upstreams configured.</p>
|
<p {...stylex.props(styles.empty)}>No upstreams configured.</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="overflow-x-auto">
|
<div {...stylex.props(styles.tableWrap)}>
|
||||||
<table className="mt-2 w-full text-sm">
|
<table {...stylex.props(styles.table)}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="border-b border-zinc-200 text-left text-xs text-zinc-500 dark:border-zinc-800">
|
<tr {...stylex.props(styles.headRow)}>
|
||||||
<th scope="col" className="px-4 py-2 font-medium">
|
<th scope="col" {...stylex.props(styles.th)}>
|
||||||
URL
|
URL
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-4 py-2 font-medium">
|
<th scope="col" {...stylex.props(styles.th)}>
|
||||||
Enabled
|
Enabled
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-4 py-2 font-medium">
|
<th scope="col" {...stylex.props(styles.th)}>
|
||||||
Available
|
Available
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-4 py-2 text-right font-medium">
|
<th scope="col" {...stylex.props(styles.th, styles.thRight)}>
|
||||||
Failures
|
Failures
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-4 py-2 text-right font-medium">
|
<th scope="col" {...stylex.props(styles.th, styles.thRight)}>
|
||||||
Success rate
|
Success rate
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-4 py-2 font-medium">
|
<th scope="col" {...stylex.props(styles.th)}>
|
||||||
Last error
|
Last error
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{health.upstreams.map((upstream) => (
|
{health.upstreams.map((upstream) => (
|
||||||
<tr
|
<tr key={upstream.url} {...stylex.props(styles.row)}>
|
||||||
key={upstream.url}
|
<td {...stylex.props(styles.cell, styles.small, shared.mono)}>{upstream.url}</td>
|
||||||
className="border-b border-zinc-100 last:border-0 dark:border-zinc-800/50"
|
<td {...stylex.props(styles.cell)}>
|
||||||
>
|
|
||||||
<td className="px-4 py-2 font-mono text-xs">{upstream.url}</td>
|
|
||||||
<td className="px-4 py-2">
|
|
||||||
<YesNo value={upstream.enabled} badValue={false} />
|
<YesNo value={upstream.enabled} badValue={false} />
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-2">
|
<td {...stylex.props(styles.cell)}>
|
||||||
<YesNo value={upstream.available} badValue={false} />
|
<YesNo value={upstream.available} badValue={false} />
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-2 text-right tabular-nums">{upstream.total_failures}</td>
|
<td {...stylex.props(styles.cell, styles.cellRight, shared.tabularNums)}>
|
||||||
<td className="px-4 py-2 text-right tabular-nums">
|
{upstream.total_failures}
|
||||||
|
</td>
|
||||||
|
<td {...stylex.props(styles.cell, styles.cellRight, shared.tabularNums)}>
|
||||||
{(upstream.success_rate * 100).toFixed(1)}%
|
{(upstream.success_rate * 100).toFixed(1)}%
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-2 text-xs text-zinc-500">{upstream.last_error || "—"}</td>
|
<td {...stylex.props(styles.cell, styles.small, styles.muted)}>
|
||||||
|
{upstream.last_error || "—"}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user