mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-04 01:36:39 +00:00
♻️ refactor
This commit is contained in:
@@ -34,6 +34,7 @@ import {
|
|||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue
|
SelectValue
|
||||||
} from "@app/components/ui/select";
|
} from "@app/components/ui/select";
|
||||||
|
import type { ResourceContextType } from "@app/contexts/resourceContext";
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||||
import { useResourceContext } from "@app/hooks/useResourceContext";
|
import { useResourceContext } from "@app/hooks/useResourceContext";
|
||||||
@@ -58,7 +59,14 @@ import type { text } from "express";
|
|||||||
import { Binary, Bot, InfoIcon, Key } from "lucide-react";
|
import { Binary, Bot, InfoIcon, Key } from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useEffect, useMemo, useRef, useState, useTransition } from "react";
|
import {
|
||||||
|
useActionState,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
useTransition
|
||||||
|
} from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -200,10 +208,6 @@ export default function ResourceAuthenticationPage() {
|
|||||||
resource.skipToIdpId || null
|
resource.skipToIdpId || null
|
||||||
);
|
);
|
||||||
|
|
||||||
const [loadingSaveUsersRoles, setLoadingSaveUsersRoles] = useState(false);
|
|
||||||
const [loadingSaveWhitelist, startSaveWhitelistTransition] =
|
|
||||||
useTransition();
|
|
||||||
|
|
||||||
const [loadingRemoveResourcePassword, setLoadingRemoveResourcePassword] =
|
const [loadingRemoveResourcePassword, setLoadingRemoveResourcePassword] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const [loadingRemoveResourcePincode, setLoadingRemoveResourcePincode] =
|
const [loadingRemoveResourcePincode, setLoadingRemoveResourcePincode] =
|
||||||
@@ -309,12 +313,18 @@ export default function ResourceAuthenticationPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onSubmitUsersRoles(
|
const [, submitUserRolesForm, loadingSaveUsersRoles] = useActionState(
|
||||||
data: z.infer<typeof UsersRolesFormSchema>
|
onSubmitUsersRoles,
|
||||||
) {
|
null
|
||||||
try {
|
);
|
||||||
setLoadingSaveUsersRoles(true);
|
|
||||||
|
|
||||||
|
async function onSubmitUsersRoles() {
|
||||||
|
const isValid = usersRolesForm.trigger();
|
||||||
|
if (!isValid) return;
|
||||||
|
|
||||||
|
const data = usersRolesForm.getValues();
|
||||||
|
|
||||||
|
try {
|
||||||
// Validate that an IDP is selected if auto login is enabled
|
// Validate that an IDP is selected if auto login is enabled
|
||||||
if (autoLoginEnabled && !selectedIdpId) {
|
if (autoLoginEnabled && !selectedIdpId) {
|
||||||
toast({
|
toast({
|
||||||
@@ -364,8 +374,6 @@ export default function ResourceAuthenticationPage() {
|
|||||||
t("resourceErrorUsersRolesSaveDescription")
|
t("resourceErrorUsersRolesSaveDescription")
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
} finally {
|
|
||||||
setLoadingSaveUsersRoles(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,9 +537,7 @@ export default function ResourceAuthenticationPage() {
|
|||||||
|
|
||||||
<Form {...usersRolesForm}>
|
<Form {...usersRolesForm}>
|
||||||
<form
|
<form
|
||||||
onSubmit={usersRolesForm.handleSubmit(
|
action={submitUserRolesForm}
|
||||||
onSubmitUsersRoles
|
|
||||||
)}
|
|
||||||
id="users-roles-form"
|
id="users-roles-form"
|
||||||
className="space-y-4"
|
className="space-y-4"
|
||||||
>
|
>
|
||||||
@@ -859,6 +865,83 @@ export default function ResourceAuthenticationPage() {
|
|||||||
</SettingsSectionBody>
|
</SettingsSectionBody>
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
|
|
||||||
|
<OneTimePasswordFormSection
|
||||||
|
resource={resource}
|
||||||
|
updateResource={updateResource}
|
||||||
|
/>
|
||||||
|
</SettingsContainer>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneTimePasswordFormSectionProps = Pick<
|
||||||
|
ResourceContextType,
|
||||||
|
"resource" | "updateResource"
|
||||||
|
>;
|
||||||
|
|
||||||
|
function OneTimePasswordFormSection({
|
||||||
|
resource,
|
||||||
|
updateResource
|
||||||
|
}: OneTimePasswordFormSectionProps) {
|
||||||
|
const { env } = useEnvContext();
|
||||||
|
const [whitelistEnabled, setWhitelistEnabled] = useState(
|
||||||
|
resource.emailWhitelistEnabled
|
||||||
|
);
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const [loadingSaveWhitelist, startTransition] = useTransition();
|
||||||
|
const whitelistForm = useForm({
|
||||||
|
resolver: zodResolver(whitelistSchema),
|
||||||
|
defaultValues: { emails: [] }
|
||||||
|
});
|
||||||
|
const api = createApiClient({ env });
|
||||||
|
const router = useRouter();
|
||||||
|
const t = useTranslations();
|
||||||
|
|
||||||
|
const [activeEmailTagIndex, setActiveEmailTagIndex] = useState<
|
||||||
|
number | null
|
||||||
|
>(null);
|
||||||
|
|
||||||
|
async function saveWhitelist() {
|
||||||
|
try {
|
||||||
|
await api.post(`/resource/${resource.resourceId}`, {
|
||||||
|
emailWhitelistEnabled: whitelistEnabled
|
||||||
|
});
|
||||||
|
|
||||||
|
if (whitelistEnabled) {
|
||||||
|
await api.post(`/resource/${resource.resourceId}/whitelist`, {
|
||||||
|
emails: whitelistForm.getValues().emails.map((i) => i.text)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateResource({
|
||||||
|
emailWhitelistEnabled: whitelistEnabled
|
||||||
|
});
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: t("resourceWhitelistSave"),
|
||||||
|
description: t("resourceWhitelistSaveDescription")
|
||||||
|
});
|
||||||
|
router.refresh();
|
||||||
|
await queryClient.invalidateQueries(
|
||||||
|
resourceQueries.resourceWhitelist({
|
||||||
|
resourceId: resource.resourceId
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: t("resourceErrorWhitelistSave"),
|
||||||
|
description: formatAxiosError(
|
||||||
|
e,
|
||||||
|
t("resourceErrorWhitelistSaveDescription")
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<SettingsSection>
|
<SettingsSection>
|
||||||
<SettingsSectionHeader>
|
<SettingsSectionHeader>
|
||||||
<SettingsSectionTitle>
|
<SettingsSectionTitle>
|
||||||
@@ -915,9 +998,7 @@ export default function ResourceAuthenticationPage() {
|
|||||||
activeEmailTagIndex
|
activeEmailTagIndex
|
||||||
}
|
}
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
validateTag={(
|
validateTag={(tag) => {
|
||||||
tag
|
|
||||||
) => {
|
|
||||||
return z
|
return z
|
||||||
.email()
|
.email()
|
||||||
.or(
|
.or(
|
||||||
@@ -933,9 +1014,8 @@ export default function ResourceAuthenticationPage() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.safeParse(
|
.safeParse(tag)
|
||||||
tag
|
.success;
|
||||||
).success;
|
|
||||||
}}
|
}}
|
||||||
setActiveTagIndex={
|
setActiveTagIndex={
|
||||||
setActiveEmailTagIndex
|
setActiveEmailTagIndex
|
||||||
@@ -947,9 +1027,7 @@ export default function ResourceAuthenticationPage() {
|
|||||||
whitelistForm.getValues()
|
whitelistForm.getValues()
|
||||||
.emails
|
.emails
|
||||||
}
|
}
|
||||||
setTags={(
|
setTags={(newRoles) => {
|
||||||
newRoles
|
|
||||||
) => {
|
|
||||||
whitelistForm.setValue(
|
whitelistForm.setValue(
|
||||||
"emails",
|
"emails",
|
||||||
newRoles as [
|
newRoles as [
|
||||||
@@ -958,16 +1036,12 @@ export default function ResourceAuthenticationPage() {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
allowDuplicates={
|
allowDuplicates={false}
|
||||||
false
|
|
||||||
}
|
|
||||||
sortTags={true}
|
sortTags={true}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
{t(
|
{t("otpEmailEnterDescription")}
|
||||||
"otpEmailEnterDescription"
|
|
||||||
)}
|
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
@@ -979,9 +1053,7 @@ export default function ResourceAuthenticationPage() {
|
|||||||
</SettingsSectionBody>
|
</SettingsSectionBody>
|
||||||
<SettingsSectionFooter>
|
<SettingsSectionFooter>
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() => startTransition(saveWhitelist)}
|
||||||
startSaveWhitelistTransition(saveWhitelist)
|
|
||||||
}
|
|
||||||
form="whitelist-form"
|
form="whitelist-form"
|
||||||
loading={loadingSaveWhitelist}
|
loading={loadingSaveWhitelist}
|
||||||
disabled={loadingSaveWhitelist}
|
disabled={loadingSaveWhitelist}
|
||||||
@@ -990,7 +1062,5 @@ export default function ResourceAuthenticationPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</SettingsSectionFooter>
|
</SettingsSectionFooter>
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
</SettingsContainer>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user