Show when a domain is config managed

This commit is contained in:
Owen
2026-05-12 20:13:45 -07:00
parent b6caeda0a5
commit f91d914ec6
5 changed files with 146 additions and 24 deletions

View File

@@ -13,6 +13,8 @@ import DomainCertForm from "@app/components/DomainCertForm";
import { build } from "@server/build";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useTranslations } from "next-intl";
import { Lock } from "lucide-react";
import { Badge } from "@app/components/ui/badge";
interface DomainPageClientProps {
initialDomain: GetDomainResponse;
@@ -49,7 +51,22 @@ export default function DomainPageClient({
<>
<div className="flex justify-between">
<SettingsSectionTitle
title={domain.baseDomain}
title={
<span className="flex items-center gap-2">
{domain.baseDomain}
{domain.configManaged && (
<Badge
variant="secondary"
className="flex items-center gap-1 text-sm font-normal"
>
<Lock className="h-3 w-3" />
{t("configManaged", {
fallback: "Config Managed"
})}
</Badge>
)}
</span>
}
description={t("domainSettingDescription")}
/>
{env.flags.usePangolinDns && domain.failed ? (
@@ -90,4 +107,4 @@ export default function DomainPageClient({
</div>
</>
);
}
}

View File

@@ -16,6 +16,7 @@ import { formatAxiosError } from "@app/lib/api";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { Badge } from "@app/components/ui/badge";
import { Lock } from "lucide-react";
import { useTranslations } from "next-intl";
import CreateDomainForm from "@app/components/CreateDomainForm";
import { useToast } from "@app/hooks/useToast";
@@ -72,7 +73,11 @@ export default function DomainsTable({ domains, orgId }: Props) {
const { org } = useOrgContext();
const queryClient = useQueryClient();
const { data: rawDomains, isRefetching, refetch } = useQuery({
const {
data: rawDomains,
isRefetching,
refetch
} = useQuery({
...orgQueries.domains({ orgId }),
initialData: domains as any,
refetchInterval: durationToMs(10, "seconds")
@@ -80,12 +85,15 @@ export default function DomainsTable({ domains, orgId }: Props) {
const tableData = useMemo(
() =>
(rawDomains ?? []).map((d) => ({
...d,
baseDomain: toUnicode(d.baseDomain),
type: d.type ?? "",
errorMessage: d.errorMessage ?? null
} as DomainRow)),
(rawDomains ?? []).map(
(d) =>
({
...d,
baseDomain: toUnicode(d.baseDomain),
type: d.type ?? "",
errorMessage: d.errorMessage ?? null
}) as DomainRow
),
[rawDomains]
);
@@ -198,12 +206,17 @@ export default function DomainsTable({ domains, orgId }: Props) {
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="red" className="cursor-help">
<Badge
variant="red"
className="cursor-help"
>
{t("failed", { fallback: "Failed" })}
</Badge>
</TooltipTrigger>
<TooltipContent className="max-w-xs">
<p className="break-words">{errorMessage}</p>
<p className="break-words">
{errorMessage}
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
@@ -220,12 +233,17 @@ export default function DomainsTable({ domains, orgId }: Props) {
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="yellow" className="cursor-help">
<Badge
variant="yellow"
className="cursor-help"
>
{t("pending")}
</Badge>
</TooltipTrigger>
<TooltipContent className="max-w-xs">
<p className="break-words">{errorMessage}</p>
<p className="break-words">
{errorMessage}
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
@@ -253,6 +271,25 @@ export default function DomainsTable({ domains, orgId }: Props) {
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
);
},
cell: ({ row }) => {
const domain = row.original;
return (
<span className="flex items-center gap-2">
{domain.baseDomain}
{domain.configManaged && (
<Badge
variant="secondary"
className="flex items-center gap-1 text-xs font-normal"
>
<Lock className="h-3 w-3" />
{t("configManaged", {
fallback: "Config Managed"
})}
</Badge>
)}
</span>
);
}
},
...(env.env.flags.usePangolinDns ? [typeColumn] : []),
@@ -283,16 +320,18 @@ export default function DomainsTable({ domains, orgId }: Props) {
{t("viewSettings")}
</DropdownMenuItem>
</Link>
<DropdownMenuItem
onClick={() => {
setSelectedDomain(domain);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">
{t("delete")}
</span>
</DropdownMenuItem>
{!domain.configManaged && (
<DropdownMenuItem
onClick={() => {
setSelectedDomain(domain);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">
{t("delete")}
</span>
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
{domain.failed && (
@@ -315,7 +354,9 @@ export default function DomainsTable({ domains, orgId }: Props) {
href={`/${orgId}/settings/domains/${domain.domainId}`}
>
<Button variant={"outline"}>
{t("edit")}
{domain.configManaged
? t("view", { fallback: "View" })
: t("edit")}
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</Link>