mirror of
https://github.com/fosrl/pangolin.git
synced 2026-10-21 12:09:04 +02:00
♻️ Show popup for invalid redirect resource domain
This commit is contained in:
+2
-1
@@ -2580,7 +2580,8 @@
|
||||
"billingModifyLicenses": "Modify License Subscription",
|
||||
"domainNotFound": "Domain Not Found",
|
||||
"domainNotFoundDescription": "This resource is disabled because the domain no longer exists our system. Please set a new domain for this resource.",
|
||||
"rdirectDomainNotFoundDescription": "This redirect is disabled because the domain no longer exists our system. Please set a new domain for this redirect or its attached resource domain.",
|
||||
"redirectDomainNotFoundDescription": "This redirect is disabled because the domain no longer exists our system. Please set a new domain for this redirect or its attached resource domain.",
|
||||
"redirectDomainSelectedDomainNotFound": "This redirect is disabled because its domain no longer exists. Select a different domain, or attach the redirect to a resource that has a valid domain.",
|
||||
"failed": "Failed",
|
||||
"createNewOrgDescription": "Create a new organization",
|
||||
"organization": "Organization",
|
||||
|
||||
@@ -29,6 +29,7 @@ export type GetRedirectResponse = {
|
||||
resourceId: number | null;
|
||||
resourceName: string | null;
|
||||
resourceNiceId: string | null;
|
||||
resourceDomainId: string | null;
|
||||
resourceFullDomain: string | null;
|
||||
resourceSsl: boolean | null;
|
||||
resourceWildcard: boolean | null;
|
||||
@@ -59,7 +60,8 @@ const redirectColumns = {
|
||||
resourceSsl: resources.ssl,
|
||||
resourceWildcard: resources.wildcard,
|
||||
domainId: redirects.domainId,
|
||||
baseDomain: domains.baseDomain
|
||||
baseDomain: domains.baseDomain,
|
||||
resourceDomainId: resources.domainId
|
||||
};
|
||||
|
||||
const paramsSchema = z.strictObject({
|
||||
|
||||
@@ -40,6 +40,7 @@ export default async function EditRedirectPage(props: EditRedirectPageProps) {
|
||||
const initialResource =
|
||||
redirect.resourceId && redirect.resourceNiceId
|
||||
? {
|
||||
domainId: redirect.resourceDomainId,
|
||||
resourceId: redirect.resourceId,
|
||||
niceId: redirect.resourceNiceId,
|
||||
name: redirect.resourceName ?? redirect.resourceNiceId,
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
|
||||
import DomainPicker from "@app/components/DomainPicker";
|
||||
import {
|
||||
PathMatchDisplay,
|
||||
PathMatchModal,
|
||||
PathRewriteDisplay,
|
||||
PathRewriteModal
|
||||
} from "@app/components/PathMatchRenameModal";
|
||||
import {
|
||||
SettingsContainer,
|
||||
SettingsFormCell,
|
||||
@@ -40,34 +47,34 @@ import {
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { toast } from "@app/hooks/useToast";
|
||||
import { createApiClient, formatAxiosError } from "@app/lib/api";
|
||||
import {
|
||||
isValidDestinationHost,
|
||||
isValidRegex
|
||||
} from "@server/routers/redirect/validation";
|
||||
import { build } from "@server/build";
|
||||
import { cn } from "@app/lib/cn";
|
||||
import { CaretSortIcon } from "@radix-ui/react-icons";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { CaretSortIcon } from "@radix-ui/react-icons";
|
||||
import { build } from "@server/build";
|
||||
import type {
|
||||
CreateRedirectResponse,
|
||||
GetRedirectResponse
|
||||
} from "@server/routers/redirect";
|
||||
import {
|
||||
isValidDestinationHost,
|
||||
isValidRegex
|
||||
} from "@server/routers/redirect/validation";
|
||||
import type { AxiosResponse } from "axios";
|
||||
import { InfoIcon, Plus } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useActionState, useEffect, useMemo, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { ResourceSelector, type SelectedResource } from "./resource-selector";
|
||||
import {
|
||||
PathMatchDisplay,
|
||||
PathMatchModal,
|
||||
PathRewriteDisplay,
|
||||
PathRewriteModal
|
||||
} from "@app/components/PathMatchRenameModal";
|
||||
import { Plus } from "lucide-react";
|
||||
import DomainPicker from "@app/components/DomainPicker";
|
||||
import Link from "next/link";
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger
|
||||
} from "./ui/tooltip";
|
||||
import { Alert, AlertDescription } from "./ui/alert";
|
||||
|
||||
const DEFAULT_PATH_MATCH_TYPE = "regex" as const;
|
||||
const DEFAULT_PRIORITY = 100;
|
||||
@@ -213,6 +220,11 @@ export default function RedirectForm({
|
||||
const attachTo = form.watch("attachTo");
|
||||
const ssl = form.watch("ssl");
|
||||
|
||||
const resourceMissingDomain =
|
||||
attachTo === "resource" &&
|
||||
Boolean(selectedResource) &&
|
||||
!selectedResource?.domainId;
|
||||
|
||||
const sourceFullDomain =
|
||||
attachTo === "domain"
|
||||
? domainFullDomain
|
||||
@@ -364,7 +376,20 @@ export default function RedirectForm({
|
||||
<Form {...form}>
|
||||
<form action={formAction} id="redirect-form">
|
||||
<SettingsFormGrid>
|
||||
<SettingsFormCell span="full">
|
||||
<SettingsFormCell
|
||||
span="full"
|
||||
className="flex flex-col items-start gap-4"
|
||||
>
|
||||
{resourceMissingDomain && (
|
||||
<Alert variant="neutral">
|
||||
<InfoIcon className="h-4 w-4" />
|
||||
<AlertDescription>
|
||||
{t(
|
||||
"redirectDomainSelectedDomainNotFound"
|
||||
)}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="enabled"
|
||||
@@ -380,8 +405,12 @@ export default function RedirectForm({
|
||||
"redirectEnabledDescription"
|
||||
)}
|
||||
checked={
|
||||
!resourceMissingDomain &&
|
||||
field.value
|
||||
}
|
||||
disabled={
|
||||
resourceMissingDomain
|
||||
}
|
||||
onCheckedChange={
|
||||
field.onChange
|
||||
}
|
||||
|
||||
@@ -269,7 +269,9 @@ export default function RedirectsTable({
|
||||
return (
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<InfoPopup
|
||||
info={t("rdirectDomainNotFoundDescription")}
|
||||
info={t(
|
||||
"redirectDomainNotFoundDescription"
|
||||
)}
|
||||
text={t("domainNotFound")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,13 @@ import { useDebounce } from "use-debounce";
|
||||
|
||||
export type SelectedResource = Pick<
|
||||
ListResourcesResponse["resources"][number],
|
||||
"name" | "resourceId" | "fullDomain" | "niceId" | "ssl" | "wildcard"
|
||||
| "name"
|
||||
| "resourceId"
|
||||
| "fullDomain"
|
||||
| "niceId"
|
||||
| "ssl"
|
||||
| "wildcard"
|
||||
| "domainId"
|
||||
>;
|
||||
|
||||
export type ResourceSelectorProps = {
|
||||
|
||||
Reference in New Issue
Block a user