mirror of
https://github.com/fosrl/pangolin.git
synced 2026-01-31 15:19:09 +00:00
Adjust styling to make it more clear
This commit is contained in:
@@ -513,6 +513,7 @@
|
||||
"ipAddressErrorInvalidFormat": "Invalid IP address format",
|
||||
"ipAddressErrorInvalidOctet": "Invalid IP address octet",
|
||||
"path": "Path",
|
||||
"matchPath": "Match Path",
|
||||
"ipAddressRange": "IP Range",
|
||||
"rulesErrorFetch": "Failed to fetch rules",
|
||||
"rulesErrorFetchDescription": "An error occurred while fetching rules",
|
||||
|
||||
@@ -71,7 +71,9 @@ import {
|
||||
Heart,
|
||||
Check,
|
||||
CircleCheck,
|
||||
CircleX
|
||||
CircleX,
|
||||
ArrowRight,
|
||||
MoveRight
|
||||
} from "lucide-react";
|
||||
import { ContainersSelector } from "@app/components/ContainersSelector";
|
||||
import { useTranslations } from "next-intl";
|
||||
@@ -565,6 +567,89 @@ export default function ReverseProxyTargets(props: {
|
||||
}
|
||||
|
||||
const columns: ColumnDef<LocalTarget>[] = [
|
||||
{
|
||||
accessorKey: "path",
|
||||
header: t("matchPath"),
|
||||
cell: ({ row }) => {
|
||||
const [showPathInput, setShowPathInput] = useState(
|
||||
!!(row.original.path || row.original.pathMatchType)
|
||||
);
|
||||
|
||||
if (!showPathInput) {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowPathInput(true)}
|
||||
>
|
||||
+ {t("matchPath")}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 min-w-[200px] items-center">
|
||||
<Select
|
||||
defaultValue={row.original.pathMatchType || "exact"}
|
||||
onValueChange={(value) =>
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
pathMatchType: value as "exact" | "prefix" | "regex"
|
||||
})
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-25">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="exact">Exact</SelectItem>
|
||||
<SelectItem value="prefix">Prefix</SelectItem>
|
||||
<SelectItem value="regex">Regex</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
placeholder={
|
||||
row.original.pathMatchType === "regex"
|
||||
? "^/api/.*"
|
||||
: "/path"
|
||||
}
|
||||
defaultValue={row.original.path || ""}
|
||||
className="flex-1 min-w-[150px]"
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value.trim();
|
||||
if (!value) {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
} else {
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: value
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
}}
|
||||
>
|
||||
×
|
||||
</Button>
|
||||
|
||||
<MoveRight className="ml-4 h-4 w-4" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "siteId",
|
||||
header: t("site"),
|
||||
@@ -762,87 +847,6 @@ export default function ReverseProxyTargets(props: {
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
accessorKey: "path",
|
||||
header: t("path"),
|
||||
cell: ({ row }) => {
|
||||
const [showPathInput, setShowPathInput] = useState(
|
||||
!!(row.original.path || row.original.pathMatchType)
|
||||
);
|
||||
|
||||
if (!showPathInput) {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowPathInput(true)}
|
||||
>
|
||||
+ Path
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 min-w-[200px]">
|
||||
<Select
|
||||
defaultValue={row.original.pathMatchType || "exact"}
|
||||
onValueChange={(value) =>
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
pathMatchType: value as "exact" | "prefix" | "regex"
|
||||
})
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-25">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="exact">Exact</SelectItem>
|
||||
<SelectItem value="prefix">Prefix</SelectItem>
|
||||
<SelectItem value="regex">Regex</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
placeholder={
|
||||
row.original.pathMatchType === "regex"
|
||||
? "^/api/.*"
|
||||
: "/path"
|
||||
}
|
||||
defaultValue={row.original.path || ""}
|
||||
className="flex-1 min-w-[150px]"
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value.trim();
|
||||
if (!value) {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
} else {
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: value
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
}}
|
||||
>
|
||||
×
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
// {
|
||||
// accessorKey: "protocol",
|
||||
// header: t('targetProtocol'),
|
||||
|
||||
@@ -58,7 +58,7 @@ import {
|
||||
} from "@app/components/ui/popover";
|
||||
import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons";
|
||||
import { cn } from "@app/lib/cn";
|
||||
import { SquareArrowOutUpRight } from "lucide-react";
|
||||
import { ArrowRight, MoveRight, SquareArrowOutUpRight } from "lucide-react";
|
||||
import CopyTextBox from "@app/components/CopyTextBox";
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
@@ -355,8 +355,6 @@ export default function Page() {
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
setShowSnippets(true);
|
||||
router.refresh();
|
||||
setCreateLoading(true);
|
||||
|
||||
const baseData = baseForm.getValues();
|
||||
@@ -537,6 +535,89 @@ export default function Page() {
|
||||
}, []);
|
||||
|
||||
const columns: ColumnDef<LocalTarget>[] = [
|
||||
{
|
||||
accessorKey: "path",
|
||||
header: t("matchPath"),
|
||||
cell: ({ row }) => {
|
||||
const [showPathInput, setShowPathInput] = useState(
|
||||
!!(row.original.path || row.original.pathMatchType)
|
||||
);
|
||||
|
||||
if (!showPathInput) {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowPathInput(true)}
|
||||
>
|
||||
+ {t("matchPath")}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 min-w-[200px] items-center">
|
||||
<Select
|
||||
defaultValue={row.original.pathMatchType || "exact"}
|
||||
onValueChange={(value) =>
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
pathMatchType: value as "exact" | "prefix" | "regex"
|
||||
})
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-25">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="exact">Exact</SelectItem>
|
||||
<SelectItem value="prefix">Prefix</SelectItem>
|
||||
<SelectItem value="regex">Regex</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
placeholder={
|
||||
row.original.pathMatchType === "regex"
|
||||
? "^/api/.*"
|
||||
: "/path"
|
||||
}
|
||||
defaultValue={row.original.path || ""}
|
||||
className="flex-1 min-w-[150px]"
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value.trim();
|
||||
if (!value) {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
} else {
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: value
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
}}
|
||||
>
|
||||
×
|
||||
</Button>
|
||||
|
||||
<MoveRight className="ml-4 h-4 w-4" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "siteId",
|
||||
header: t("site"),
|
||||
@@ -710,87 +791,6 @@ export default function Page() {
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
accessorKey: "path",
|
||||
header: t("path"),
|
||||
cell: ({ row }) => {
|
||||
const [showPathInput, setShowPathInput] = useState(
|
||||
!!(row.original.path || row.original.pathMatchType)
|
||||
);
|
||||
|
||||
if (!showPathInput) {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => setShowPathInput(true)}
|
||||
>
|
||||
+ Path
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 min-w-[200px]">
|
||||
<Select
|
||||
defaultValue={row.original.pathMatchType || "exact"}
|
||||
onValueChange={(value) =>
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
pathMatchType: value as "exact" | "prefix" | "regex"
|
||||
})
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-25">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="exact">Exact</SelectItem>
|
||||
<SelectItem value="prefix">Prefix</SelectItem>
|
||||
<SelectItem value="regex">Regex</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Input
|
||||
placeholder={
|
||||
row.original.pathMatchType === "regex"
|
||||
? "^/api/.*"
|
||||
: "/path"
|
||||
}
|
||||
defaultValue={row.original.path || ""}
|
||||
className="flex-1 min-w-[150px]"
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value.trim();
|
||||
if (!value) {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
} else {
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: value
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setShowPathInput(false);
|
||||
updateTarget(row.original.targetId, {
|
||||
...row.original,
|
||||
path: null,
|
||||
pathMatchType: null
|
||||
});
|
||||
}}
|
||||
>
|
||||
×
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "enabled",
|
||||
header: t("enabled"),
|
||||
|
||||
Reference in New Issue
Block a user