mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-27 11:12:55 +00:00
Cleaning up some react
This commit is contained in:
@@ -6,9 +6,7 @@ import { Input } from "@/components/ui/input";
|
|||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
SelectGroup,
|
|
||||||
SelectItem,
|
SelectItem,
|
||||||
SelectLabel,
|
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue
|
SelectValue
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
@@ -36,7 +34,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCaption,
|
|
||||||
TableCell,
|
TableCell,
|
||||||
TableHead,
|
TableHead,
|
||||||
TableHeader,
|
TableHeader,
|
||||||
@@ -55,18 +52,11 @@ import {
|
|||||||
SettingsSectionTitle,
|
SettingsSectionTitle,
|
||||||
SettingsSectionDescription,
|
SettingsSectionDescription,
|
||||||
SettingsSectionBody,
|
SettingsSectionBody,
|
||||||
SettingsSectionFooter,
|
SettingsSectionFooter
|
||||||
SettingsSectionForm
|
|
||||||
} from "@app/components/Settings";
|
} from "@app/components/Settings";
|
||||||
import { ListResourceRulesResponse } from "@server/routers/resource/listResourceRules";
|
import { ListResourceRulesResponse } from "@server/routers/resource/listResourceRules";
|
||||||
import { SwitchInput } from "@app/components/SwitchInput";
|
import { SwitchInput } from "@app/components/SwitchInput";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
|
|
||||||
import { ArrowUpDown, Check, InfoIcon, X, ChevronsUpDown } from "lucide-react";
|
import { ArrowUpDown, Check, InfoIcon, X, ChevronsUpDown } from "lucide-react";
|
||||||
import {
|
|
||||||
InfoSection,
|
|
||||||
InfoSections,
|
|
||||||
InfoSectionTitle
|
|
||||||
} from "@app/components/InfoSection";
|
|
||||||
import { InfoPopup } from "@app/components/ui/info-popup";
|
import { InfoPopup } from "@app/components/ui/info-popup";
|
||||||
import {
|
import {
|
||||||
isValidCIDR,
|
isValidCIDR,
|
||||||
@@ -78,7 +68,11 @@ import { useRouter } from "next/navigation";
|
|||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { COUNTRIES } from "@server/db/countries";
|
import { COUNTRIES } from "@server/db/countries";
|
||||||
import { MAJOR_ASNS } from "@server/db/asns";
|
import { MAJOR_ASNS } from "@server/db/asns";
|
||||||
import { REGIONS, getRegionNameById, isValidRegionId } from "@server/db/regions";
|
import {
|
||||||
|
REGIONS,
|
||||||
|
getRegionNameById,
|
||||||
|
isValidRegionId
|
||||||
|
} from "@server/db/regions";
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
CommandEmpty,
|
CommandEmpty,
|
||||||
@@ -109,25 +103,23 @@ type LocalRule = ArrayElement<ListResourceRulesResponse["rules"]> & {
|
|||||||
export default function ResourceRules(props: {
|
export default function ResourceRules(props: {
|
||||||
params: Promise<{ resourceId: number }>;
|
params: Promise<{ resourceId: number }>;
|
||||||
}) {
|
}) {
|
||||||
const params = use(props.params);
|
|
||||||
const { resource, updateResource } = useResourceContext();
|
const { resource, updateResource } = useResourceContext();
|
||||||
const api = createApiClient(useEnvContext());
|
const api = createApiClient(useEnvContext());
|
||||||
const [rules, setRules] = useState<LocalRule[]>([]);
|
const [rules, setRules] = useState<LocalRule[]>([]);
|
||||||
const [rulesToRemove, setRulesToRemove] = useState<number[]>([]);
|
const [rulesToRemove, setRulesToRemove] = useState<number[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [pageLoading, setPageLoading] = useState(true);
|
const [pageLoading, setPageLoading] = useState(true);
|
||||||
const [rulesEnabled, setRulesEnabled] = useState(resource.applyRules ?? false);
|
const [rulesEnabled, setRulesEnabled] = useState(
|
||||||
|
resource.applyRules ?? false
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRulesEnabled(resource.applyRules);
|
setRulesEnabled(resource.applyRules);
|
||||||
}, [resource.applyRules]);
|
}, [resource.applyRules]);
|
||||||
|
|
||||||
const [openCountrySelect, setOpenCountrySelect] = useState(false);
|
|
||||||
const [countrySelectValue, setCountrySelectValue] = useState("");
|
|
||||||
const [openAddRuleCountrySelect, setOpenAddRuleCountrySelect] =
|
const [openAddRuleCountrySelect, setOpenAddRuleCountrySelect] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const [openAddRuleAsnSelect, setOpenAddRuleAsnSelect] =
|
const [openAddRuleAsnSelect, setOpenAddRuleAsnSelect] = useState(false);
|
||||||
useState(false);
|
|
||||||
const [openAddRuleRegionSelect, setOpenAddRuleRegionSelect] =
|
const [openAddRuleRegionSelect, setOpenAddRuleRegionSelect] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -157,7 +149,10 @@ export default function ResourceRules(props: {
|
|||||||
resolver: zodResolver(addRuleSchema),
|
resolver: zodResolver(addRuleSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
action: "ACCEPT",
|
action: "ACCEPT",
|
||||||
match: "PATH",
|
match:
|
||||||
|
resource.http && resource.browserAccessType == "http"
|
||||||
|
? "PATH"
|
||||||
|
: "IP",
|
||||||
value: ""
|
value: ""
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -270,16 +265,12 @@ export default function ResourceRules(props: {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
if (data.match === "REGION" && !isValidRegionId(data.value)) {
|
||||||
data.match === "REGION" &&
|
|
||||||
!isValidRegionId(data.value)
|
|
||||||
) {
|
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: t("rulesErrorInvalidRegion"),
|
title: t("rulesErrorInvalidRegion"),
|
||||||
description:
|
description:
|
||||||
t("rulesErrorInvalidRegionDescription") ||
|
t("rulesErrorInvalidRegionDescription") || "Invalid region."
|
||||||
"Invalid region."
|
|
||||||
});
|
});
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
@@ -564,12 +555,24 @@ export default function ResourceRules(props: {
|
|||||||
<Select
|
<Select
|
||||||
defaultValue={row.original.match}
|
defaultValue={row.original.match}
|
||||||
onValueChange={(
|
onValueChange={(
|
||||||
value: "CIDR" | "IP" | "PATH" | "COUNTRY" | "ASN" | "REGION"
|
value:
|
||||||
|
| "CIDR"
|
||||||
|
| "IP"
|
||||||
|
| "PATH"
|
||||||
|
| "COUNTRY"
|
||||||
|
| "ASN"
|
||||||
|
| "REGION"
|
||||||
) =>
|
) =>
|
||||||
updateRule(row.original.ruleId, {
|
updateRule(row.original.ruleId, {
|
||||||
match: value,
|
match: value,
|
||||||
value:
|
value:
|
||||||
value === "COUNTRY" ? "US" : value === "ASN" ? "AS15169" : value === "REGION" ? "021" : row.original.value
|
value === "COUNTRY"
|
||||||
|
? "US"
|
||||||
|
: value === "ASN"
|
||||||
|
? "AS15169"
|
||||||
|
: value === "REGION"
|
||||||
|
? "021"
|
||||||
|
: row.original.value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -577,7 +580,12 @@ export default function ResourceRules(props: {
|
|||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="PATH">{RuleMatch.PATH}</SelectItem>
|
{resource.http &&
|
||||||
|
resource.browserAccessType == "http" && (
|
||||||
|
<SelectItem value="PATH">
|
||||||
|
{RuleMatch.PATH}
|
||||||
|
</SelectItem>
|
||||||
|
)}
|
||||||
<SelectItem value="IP">{RuleMatch.IP}</SelectItem>
|
<SelectItem value="IP">{RuleMatch.IP}</SelectItem>
|
||||||
<SelectItem value="CIDR">{RuleMatch.CIDR}</SelectItem>
|
<SelectItem value="CIDR">{RuleMatch.CIDR}</SelectItem>
|
||||||
{isMaxmindAvailable && (
|
{isMaxmindAvailable && (
|
||||||
@@ -669,14 +677,14 @@ export default function ResourceRules(props: {
|
|||||||
>
|
>
|
||||||
{row.original.value
|
{row.original.value
|
||||||
? (() => {
|
? (() => {
|
||||||
const found = MAJOR_ASNS.find(
|
const found = MAJOR_ASNS.find(
|
||||||
(asn) =>
|
(asn) =>
|
||||||
asn.code ===
|
asn.code ===
|
||||||
row.original.value
|
row.original.value
|
||||||
);
|
);
|
||||||
return found
|
return found
|
||||||
? `${found.name} (${row.original.value})`
|
? `${found.name} (${row.original.value})`
|
||||||
: `Custom (${row.original.value})`;
|
: `Custom (${row.original.value})`;
|
||||||
})()
|
})()
|
||||||
: "Select ASN"}
|
: "Select ASN"}
|
||||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
@@ -755,7 +763,9 @@ export default function ResourceRules(props: {
|
|||||||
className="min-w-[200px] justify-between"
|
className="min-w-[200px] justify-between"
|
||||||
>
|
>
|
||||||
{(() => {
|
{(() => {
|
||||||
const regionName = getRegionNameById(row.original.value);
|
const regionName = getRegionNameById(
|
||||||
|
row.original.value
|
||||||
|
);
|
||||||
if (!regionName) {
|
if (!regionName) {
|
||||||
return t("selectRegion");
|
return t("selectRegion");
|
||||||
}
|
}
|
||||||
@@ -774,7 +784,10 @@ export default function ResourceRules(props: {
|
|||||||
{t("noRegionFound")}
|
{t("noRegionFound")}
|
||||||
</CommandEmpty>
|
</CommandEmpty>
|
||||||
{REGIONS.map((continent) => (
|
{REGIONS.map((continent) => (
|
||||||
<CommandGroup key={continent.id} heading={t(continent.name)}>
|
<CommandGroup
|
||||||
|
key={continent.id}
|
||||||
|
heading={t(continent.name)}
|
||||||
|
>
|
||||||
<CommandItem
|
<CommandItem
|
||||||
value={continent.id}
|
value={continent.id}
|
||||||
keywords={[
|
keywords={[
|
||||||
@@ -790,38 +803,48 @@ export default function ResourceRules(props: {
|
|||||||
>
|
>
|
||||||
<Check
|
<Check
|
||||||
className={`mr-2 h-4 w-4 ${
|
className={`mr-2 h-4 w-4 ${
|
||||||
row.original.value === continent.id
|
row.original.value ===
|
||||||
|
continent.id
|
||||||
? "opacity-100"
|
? "opacity-100"
|
||||||
: "opacity-0"
|
: "opacity-0"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{t(continent.name)} ({continent.id})
|
{t(continent.name)} (
|
||||||
|
{continent.id})
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
{continent.includes.map((subregion) => (
|
{continent.includes.map(
|
||||||
<CommandItem
|
(subregion) => (
|
||||||
key={subregion.id}
|
<CommandItem
|
||||||
value={subregion.id}
|
key={subregion.id}
|
||||||
keywords={[
|
value={subregion.id}
|
||||||
t(subregion.name),
|
keywords={[
|
||||||
subregion.id
|
t(subregion.name),
|
||||||
]}
|
subregion.id
|
||||||
onSelect={() => {
|
]}
|
||||||
updateRule(
|
onSelect={() => {
|
||||||
row.original.ruleId,
|
updateRule(
|
||||||
{ value: subregion.id }
|
row.original
|
||||||
);
|
.ruleId,
|
||||||
}}
|
{
|
||||||
>
|
value: subregion.id
|
||||||
<Check
|
}
|
||||||
className={`mr-2 h-4 w-4 ${
|
);
|
||||||
row.original.value === subregion.id
|
}}
|
||||||
? "opacity-100"
|
>
|
||||||
: "opacity-0"
|
<Check
|
||||||
}`}
|
className={`mr-2 h-4 w-4 ${
|
||||||
/>
|
row.original
|
||||||
{t(subregion.name)} ({subregion.id})
|
.value ===
|
||||||
</CommandItem>
|
subregion.id
|
||||||
))}
|
? "opacity-100"
|
||||||
|
: "opacity-0"
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
{t(subregion.name)} (
|
||||||
|
{subregion.id})
|
||||||
|
</CommandItem>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
))}
|
))}
|
||||||
</CommandList>
|
</CommandList>
|
||||||
@@ -1018,13 +1041,15 @@ export default function ResourceRules(props: {
|
|||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{resource.http && (
|
{resource.http &&
|
||||||
<SelectItem value="PATH">
|
resource.browserAccessType ==
|
||||||
{
|
"http" && (
|
||||||
RuleMatch.PATH
|
<SelectItem value="PATH">
|
||||||
}
|
{
|
||||||
</SelectItem>
|
RuleMatch.PATH
|
||||||
)}
|
}
|
||||||
|
</SelectItem>
|
||||||
|
)}
|
||||||
<SelectItem value="IP">
|
<SelectItem value="IP">
|
||||||
{RuleMatch.IP}
|
{RuleMatch.IP}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
@@ -1311,8 +1336,8 @@ export default function ResourceRules(props: {
|
|||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
) : addRuleForm.watch(
|
) : addRuleForm.watch(
|
||||||
"match"
|
"match"
|
||||||
) === "REGION" ? (
|
) === "REGION" ? (
|
||||||
<Popover
|
<Popover
|
||||||
open={
|
open={
|
||||||
openAddRuleRegionSelect
|
openAddRuleRegionSelect
|
||||||
@@ -1334,8 +1359,16 @@ export default function ResourceRules(props: {
|
|||||||
>
|
>
|
||||||
{field.value
|
{field.value
|
||||||
? (() => {
|
? (() => {
|
||||||
const regionName = getRegionNameById(field.value);
|
const regionName =
|
||||||
const translatedName = regionName ? t(regionName) : field.value;
|
getRegionNameById(
|
||||||
|
field.value
|
||||||
|
);
|
||||||
|
const translatedName =
|
||||||
|
regionName
|
||||||
|
? t(
|
||||||
|
regionName
|
||||||
|
)
|
||||||
|
: field.value;
|
||||||
return `${translatedName} (${field.value})`;
|
return `${translatedName} (${field.value})`;
|
||||||
})()
|
})()
|
||||||
: t(
|
: t(
|
||||||
@@ -1357,43 +1390,31 @@ export default function ResourceRules(props: {
|
|||||||
"noRegionFound"
|
"noRegionFound"
|
||||||
)}
|
)}
|
||||||
</CommandEmpty>
|
</CommandEmpty>
|
||||||
{REGIONS.map((continent) => (
|
{REGIONS.map(
|
||||||
<CommandGroup key={continent.id} heading={t(continent.name)}>
|
(
|
||||||
<CommandItem
|
continent
|
||||||
value={continent.id}
|
) => (
|
||||||
keywords={[
|
<CommandGroup
|
||||||
t(continent.name),
|
key={
|
||||||
continent.id
|
continent.id
|
||||||
]}
|
}
|
||||||
onSelect={() => {
|
heading={t(
|
||||||
field.onChange(
|
continent.name
|
||||||
continent.id
|
)}
|
||||||
);
|
|
||||||
setOpenAddRuleRegionSelect(
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Check
|
|
||||||
className={`mr-2 h-4 w-4 ${
|
|
||||||
field.value === continent.id
|
|
||||||
? "opacity-100"
|
|
||||||
: "opacity-0"
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
{t(continent.name)} ({continent.id})
|
|
||||||
</CommandItem>
|
|
||||||
{continent.includes.map((subregion) => (
|
|
||||||
<CommandItem
|
<CommandItem
|
||||||
key={subregion.id}
|
value={
|
||||||
value={subregion.id}
|
continent.id
|
||||||
|
}
|
||||||
keywords={[
|
keywords={[
|
||||||
t(subregion.name),
|
t(
|
||||||
subregion.id
|
continent.name
|
||||||
|
),
|
||||||
|
continent.id
|
||||||
]}
|
]}
|
||||||
onSelect={() => {
|
onSelect={() => {
|
||||||
field.onChange(
|
field.onChange(
|
||||||
subregion.id
|
continent.id
|
||||||
);
|
);
|
||||||
setOpenAddRuleRegionSelect(
|
setOpenAddRuleRegionSelect(
|
||||||
false
|
false
|
||||||
@@ -1402,16 +1423,71 @@ export default function ResourceRules(props: {
|
|||||||
>
|
>
|
||||||
<Check
|
<Check
|
||||||
className={`mr-2 h-4 w-4 ${
|
className={`mr-2 h-4 w-4 ${
|
||||||
field.value === subregion.id
|
field.value ===
|
||||||
|
continent.id
|
||||||
? "opacity-100"
|
? "opacity-100"
|
||||||
: "opacity-0"
|
: "opacity-0"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
{t(subregion.name)} ({subregion.id})
|
{t(
|
||||||
|
continent.name
|
||||||
|
)}{" "}
|
||||||
|
(
|
||||||
|
{
|
||||||
|
continent.id
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
))}
|
{continent.includes.map(
|
||||||
</CommandGroup>
|
(
|
||||||
))}
|
subregion
|
||||||
|
) => (
|
||||||
|
<CommandItem
|
||||||
|
key={
|
||||||
|
subregion.id
|
||||||
|
}
|
||||||
|
value={
|
||||||
|
subregion.id
|
||||||
|
}
|
||||||
|
keywords={[
|
||||||
|
t(
|
||||||
|
subregion.name
|
||||||
|
),
|
||||||
|
subregion.id
|
||||||
|
]}
|
||||||
|
onSelect={() => {
|
||||||
|
field.onChange(
|
||||||
|
subregion.id
|
||||||
|
);
|
||||||
|
setOpenAddRuleRegionSelect(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check
|
||||||
|
className={`mr-2 h-4 w-4 ${
|
||||||
|
field.value ===
|
||||||
|
subregion.id
|
||||||
|
? "opacity-100"
|
||||||
|
: "opacity-0"
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
{t(
|
||||||
|
subregion.name
|
||||||
|
)}{" "}
|
||||||
|
(
|
||||||
|
{
|
||||||
|
subregion.id
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
</CommandItem>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</CommandGroup>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</CommandList>
|
</CommandList>
|
||||||
</Command>
|
</Command>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import { Laptop, LogOut, Moon, Sun, Smartphone, Trash2 } from "lucide-react";
|
|||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { build } from "@server/build";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useUserContext } from "@app/hooks/useUserContext";
|
import { useUserContext } from "@app/hooks/useUserContext";
|
||||||
import Disable2FaForm from "./Disable2FaForm";
|
import Disable2FaForm from "./Disable2FaForm";
|
||||||
|
|||||||
Reference in New Issue
Block a user