Small ui adjustments

This commit is contained in:
Owen
2025-10-08 16:42:30 -07:00
committed by Pallavi Kumari
parent c0cc81ed96
commit 2f5e6248cd
2 changed files with 161 additions and 117 deletions

View File

@@ -109,7 +109,12 @@ import {
PathRewriteModal PathRewriteModal
} from "@app/components/PathMatchRenameModal"; } from "@app/components/PathMatchRenameModal";
import { Badge } from "@app/components/ui/badge"; import { Badge } from "@app/components/ui/badge";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@app/components/ui/tooltip"; import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from "@app/components/ui/tooltip";
const addTargetSchema = z const addTargetSchema = z
.object({ .object({
@@ -517,7 +522,7 @@ export default function ReverseProxyTargets(props: {
pathMatchType: null, pathMatchType: null,
rewritePath: null, rewritePath: null,
rewritePathType: null, rewritePathType: null,
priority: 100, priority: 100
}); });
} }
@@ -695,7 +700,12 @@ export default function ReverseProxyTargets(props: {
<Info className="h-4 w-4 text-muted-foreground" /> <Info className="h-4 w-4 text-muted-foreground" />
</TooltipTrigger> </TooltipTrigger>
<TooltipContent className="max-w-xs"> <TooltipContent className="max-w-xs">
<p>Higher priority routes are evaluated first. Priority = 100 means automatic ordering (system decides). Use another number to enforce manual priority.</p> <p>
Higher priority routes are evaluated first.
Priority = 100 means automatic ordering
(system decides). Use another number to
enforce manual priority.
</p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
@@ -770,8 +780,13 @@ export default function ReverseProxyTargets(props: {
return ( return (
<> <>
{row.original.siteType === "newt" ? ( {row.original.siteType === "newt" ? (
<Button variant="outline" <Button
className="flex items-center gap-2 p-2 max-w-md w-full text-left cursor-pointer"> variant="outline"
className="flex items-center gap-2 p-2 max-w-md w-full text-left cursor-pointer"
onClick={() =>
openHealthCheckDialog(row.original)
}
>
<div className="flex items-center space-x-1"> <div className="flex items-center space-x-1">
<Badge variant={getStatusColor(status)}> <Badge variant={getStatusColor(status)}>
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
@@ -779,22 +794,21 @@ export default function ReverseProxyTargets(props: {
{getStatusText(status)} {getStatusText(status)}
</div> </div>
</Badge> </Badge>
<Button
variant="text"
size="sm"
onClick={() =>
openHealthCheckDialog(row.original)
}
className="h-6 w-6 p-0"
>
<Settings className="h-4 w-4" /> <Settings className="h-4 w-4" />
</Button>
</div> </div>
</Button> </Button>
) : ( ) : (
<Button
variant="outline"
disabled={true}
className="flex items-center gap-2 p-2 max-w-md w-full text-left cursor-pointer"
>
<div className="flex items-center space-x-1">
<Badge variant="secondary"> <Badge variant="secondary">
{t("healthCheckNotAvailable")} {t("healthCheckNotAvailable")}
</Badge> </Badge>
</div>
</Button>
)} )}
</> </>
); );
@@ -865,7 +879,10 @@ export default function ReverseProxyTargets(props: {
(site) => site.siteId === row.original.siteId (site) => site.siteId === row.original.siteId
); );
const handleContainerSelectForTarget = (hostname: string, port?: number) => { const handleContainerSelectForTarget = (
hostname: string,
port?: number
) => {
updateTarget(row.original.targetId, { updateTarget(row.original.targetId, {
...row.original, ...row.original,
ip: hostname ip: hostname
@@ -880,7 +897,10 @@ export default function ReverseProxyTargets(props: {
return ( return (
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<Button variant={"outline"} className="w-full justify-start py-0 space-x-2 px-0 hover:bg-card cursor-default"> <Button
variant={"outline"}
className="w-full justify-start py-0 space-x-2 px-0 hover:bg-card cursor-default"
>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button
@@ -888,31 +908,46 @@ export default function ReverseProxyTargets(props: {
role="combobox" role="combobox"
className={cn( className={cn(
"min-w-[90px] justify-between text-sm font-medium border-r pr-4 rounded-none h-8 hover:bg-transparent", "min-w-[90px] justify-between text-sm font-medium border-r pr-4 rounded-none h-8 hover:bg-transparent",
!row.original.siteId && "text-muted-foreground" !row.original.siteId &&
"text-muted-foreground"
)} )}
> >
{row.original.siteId ? selectedSite?.name : t("siteSelect")} {row.original.siteId
? selectedSite?.name
: t("siteSelect")}
<CaretSortIcon className="ml-2h-4 w-4 shrink-0 opacity-50" /> <CaretSortIcon className="ml-2h-4 w-4 shrink-0 opacity-50" />
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="p-0 w-[180px]"> <PopoverContent className="p-0 w-[180px]">
<Command> <Command>
<CommandInput placeholder={t("siteSearch")} /> <CommandInput
placeholder={t("siteSearch")}
/>
<CommandList> <CommandList>
<CommandEmpty>{t("siteNotFound")}</CommandEmpty> <CommandEmpty>
{t("siteNotFound")}
</CommandEmpty>
<CommandGroup> <CommandGroup>
{sites.map((site) => ( {sites.map((site) => (
<CommandItem <CommandItem
key={site.siteId} key={site.siteId}
value={`${site.siteId}:${site.name}`} value={`${site.siteId}:${site.name}`}
onSelect={() => onSelect={() =>
updateTarget(row.original.targetId, { siteId: site.siteId }) updateTarget(
row.original
.targetId,
{
siteId: site.siteId
}
)
} }
> >
<CheckIcon <CheckIcon
className={cn( className={cn(
"mr-2 h-4 w-4", "mr-2 h-4 w-4",
site.siteId === row.original.siteId site.siteId ===
row.original
.siteId
? "opacity-100" ? "opacity-100"
: "opacity-0" : "opacity-0"
)} )}
@@ -935,7 +970,9 @@ export default function ReverseProxyTargets(props: {
<ContainersSelector <ContainersSelector
site={selectedSite} site={selectedSite}
containers={dockerState.containers} containers={dockerState.containers}
isAvailable={dockerState.isAvailable} isAvailable={
dockerState.isAvailable
}
onContainerSelect={ onContainerSelect={
handleContainerSelectForTarget handleContainerSelectForTarget
} }
@@ -953,7 +990,7 @@ export default function ReverseProxyTargets(props: {
onValueChange={(value) => onValueChange={(value) =>
updateTarget(row.original.targetId, { updateTarget(row.original.targetId, {
...row.original, ...row.original,
method: value, method: value
}) })
} }
> >
@@ -977,13 +1014,16 @@ export default function ReverseProxyTargets(props: {
className="min-w-[130px] border-none placeholder-gray-400" className="min-w-[130px] border-none placeholder-gray-400"
onBlur={(e) => { onBlur={(e) => {
const input = e.target.value.trim(); const input = e.target.value.trim();
const hasProtocol = /^(https?|h2c):\/\//.test(input); const hasProtocol =
/^(https?|h2c):\/\//.test(input);
const hasPort = /:\d+(?:\/|$)/.test(input); const hasPort = /:\d+(?:\/|$)/.test(input);
if (hasProtocol || hasPort) { if (hasProtocol || hasPort) {
const parsed = parseHostTarget(input); const parsed = parseHostTarget(input);
if (parsed) { if (parsed) {
updateTarget(row.original.targetId, { updateTarget(
row.original.targetId,
{
...row.original, ...row.original,
method: hasProtocol method: hasProtocol
? parsed.protocol ? parsed.protocol
@@ -992,12 +1032,16 @@ export default function ReverseProxyTargets(props: {
port: hasPort port: hasPort
? parsed.port ? parsed.port
: row.original.port : row.original.port
}); }
);
} else { } else {
updateTarget(row.original.targetId, { updateTarget(
row.original.targetId,
{
...row.original, ...row.original,
ip: input ip: input
}); }
);
} }
} else { } else {
updateTarget(row.original.targetId, { updateTarget(row.original.targetId, {
@@ -1013,7 +1057,7 @@ export default function ReverseProxyTargets(props: {
<Input <Input
placeholder="Port" placeholder="Port"
defaultValue={row.original.port} defaultValue={row.original.port}
className="min-w-[60px] pl-0 border-none placeholder-gray-400" className="w-[120px] pl-0 border-none placeholder-gray-400"
onBlur={(e) => onBlur={(e) =>
updateTarget(row.original.targetId, { updateTarget(row.original.targetId, {
...row.original, ...row.original,

View File

@@ -250,7 +250,7 @@ export function PathMatchDisplay({
return ( return (
<div className="flex items-center gap-2 w-full text-left"> <div className="flex items-center gap-2 w-full text-left">
<Badge variant="secondary" className="font-mono text-xs shrink-0"> <Badge variant="secondary" className="text-xs shrink-0">
{getTypeLabel(value.pathMatchType)} {getTypeLabel(value.pathMatchType)}
</Badge> </Badge>
<code className="text-sm flex-1 truncate" title={value.path}> <code className="text-sm flex-1 truncate" title={value.path}>
@@ -281,7 +281,7 @@ export function PathRewriteDisplay({
return ( return (
<div className="flex items-center gap-2 w-full text-left"> <div className="flex items-center gap-2 w-full text-left">
<Badge variant="secondary" className="font-mono text-xs shrink-0"> <Badge variant="secondary" className="text-xs shrink-0">
{getTypeLabel(value.rewritePathType)} {getTypeLabel(value.rewritePathType)}
</Badge> </Badge>
<code className="text-sm flex-1 truncate" title={value.rewritePath || ""}> <code className="text-sm flex-1 truncate" title={value.rewritePath || ""}>