Merge branch 'dev' into feat/login-page-customization

This commit is contained in:
miloschwartz
2025-12-17 11:41:17 -05:00
660 changed files with 19695 additions and 12803 deletions

View File

@@ -58,17 +58,17 @@ export default function GeneralPage() {
const t = useTranslations();
const GeneralFormSchema = z.object({
name: z.string().min(2, { message: t('nameMin', {len: 2}) }),
clientId: z.string().min(1, { message: t('idpClientIdRequired') }),
clientSecret: z.string().min(1, { message: t('idpClientSecretRequired') }),
authUrl: z.url({ message: t('idpErrorAuthUrlInvalid') }),
tokenUrl: z.url({ message: t('idpErrorTokenUrlInvalid') }),
identifierPath: z
name: z.string().min(2, { message: t("nameMin", { len: 2 }) }),
clientId: z.string().min(1, { message: t("idpClientIdRequired") }),
clientSecret: z
.string()
.min(1, { message: t('idpPathRequired') }),
.min(1, { message: t("idpClientSecretRequired") }),
authUrl: z.url({ message: t("idpErrorAuthUrlInvalid") }),
tokenUrl: z.url({ message: t("idpErrorTokenUrlInvalid") }),
identifierPath: z.string().min(1, { message: t("idpPathRequired") }),
emailPath: z.string().optional(),
namePath: z.string().optional(),
scopes: z.string().min(1, { message: t('idpScopeRequired') }),
scopes: z.string().min(1, { message: t("idpScopeRequired") }),
autoProvision: z.boolean().default(false)
});
@@ -111,7 +111,7 @@ export default function GeneralPage() {
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -145,14 +145,14 @@ export default function GeneralPage() {
if (res.status === 200) {
toast({
title: t('success'),
description: t('idpUpdatedDescription')
title: t("success"),
description: t("idpUpdatedDescription")
});
router.refresh();
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -171,17 +171,17 @@ export default function GeneralPage() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpTitle')}
{t("idpTitle")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpSettingsDescription')}
{t("idpSettingsDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
<InfoSections cols={3}>
<InfoSection>
<InfoSectionTitle>
{t('redirectUrl')}
{t("redirectUrl")}
</InfoSectionTitle>
<InfoSectionContent>
<CopyToClipboard text={redirectUrl} />
@@ -192,10 +192,10 @@ export default function GeneralPage() {
<Alert variant="neutral" className="">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">
{t('redirectUrlAbout')}
{t("redirectUrlAbout")}
</AlertTitle>
<AlertDescription>
{t('redirectUrlAboutDescription')}
{t("redirectUrlAboutDescription")}
</AlertDescription>
</Alert>
<SettingsSectionForm>
@@ -210,12 +210,14 @@ export default function GeneralPage() {
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t('name')}</FormLabel>
<FormLabel>
{t("name")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpDisplayName')}
{t("idpDisplayName")}
</FormDescription>
<FormMessage />
</FormItem>
@@ -225,7 +227,7 @@ export default function GeneralPage() {
<div className="flex items-start mb-0">
<SwitchInput
id="auto-provision-toggle"
label={t('idpAutoProvisionUsers')}
label={t("idpAutoProvisionUsers")}
defaultChecked={form.getValues(
"autoProvision"
)}
@@ -238,7 +240,7 @@ export default function GeneralPage() {
/>
</div>
<span className="text-sm text-muted-foreground">
{t('idpAutoProvisionUsersDescription')}
{t("idpAutoProvisionUsersDescription")}
</span>
</form>
</Form>
@@ -250,10 +252,10 @@ export default function GeneralPage() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpOidcConfigure')}
{t("idpOidcConfigure")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpOidcConfigureDescription')}
{t("idpOidcConfigureDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -270,13 +272,15 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpClientId')}
{t("idpClientId")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpClientIdDescription')}
{t(
"idpClientIdDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -289,7 +293,7 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpClientSecret')}
{t("idpClientSecret")}
</FormLabel>
<FormControl>
<Input
@@ -298,7 +302,9 @@ export default function GeneralPage() {
/>
</FormControl>
<FormDescription>
{t('idpClientSecretDescription')}
{t(
"idpClientSecretDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -311,13 +317,15 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpAuthUrl')}
{t("idpAuthUrl")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpAuthUrlDescription')}
{t(
"idpAuthUrlDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -330,13 +338,15 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpTokenUrl')}
{t("idpTokenUrl")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpTokenUrlDescription')}
{t(
"idpTokenUrlDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -351,10 +361,10 @@ export default function GeneralPage() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpToken')}
{t("idpToken")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpTokenDescription')}
{t("idpTokenDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -368,17 +378,21 @@ export default function GeneralPage() {
<Alert variant="neutral">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">
{t('idpJmespathAbout')}
{t("idpJmespathAbout")}
</AlertTitle>
<AlertDescription>
{t('idpJmespathAboutDescription')}
{t(
"idpJmespathAboutDescription"
)}
<a
href="https://jmespath.org"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline inline-flex items-center"
>
{t('idpJmespathAboutDescriptionLink')}{" "}
{t(
"idpJmespathAboutDescriptionLink"
)}{" "}
<ExternalLink className="ml-1 h-4 w-4" />
</a>
</AlertDescription>
@@ -390,13 +404,15 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpJmespathLabel')}
{t("idpJmespathLabel")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpJmespathLabelDescription')}
{t(
"idpJmespathLabelDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -409,13 +425,17 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpJmespathEmailPathOptional')}
{t(
"idpJmespathEmailPathOptional"
)}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpJmespathEmailPathOptionalDescription')}
{t(
"idpJmespathEmailPathOptionalDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -428,13 +448,17 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpJmespathNamePathOptional')}
{t(
"idpJmespathNamePathOptional"
)}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpJmespathNamePathOptionalDescription')}
{t(
"idpJmespathNamePathOptionalDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -447,13 +471,17 @@ export default function GeneralPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpOidcConfigureScopes')}
{t(
"idpOidcConfigureScopes"
)}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpOidcConfigureScopesDescription')}
{t(
"idpOidcConfigureScopesDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -474,7 +502,7 @@ export default function GeneralPage() {
loading={loading}
disabled={loading}
>
{t('saveGeneralSettings')}
{t("saveGeneralSettings")}
</Button>
</div>
</>

View File

@@ -89,7 +89,7 @@ export default function PoliciesPage() {
const [editingPolicy, setEditingPolicy] = useState<PolicyRow | null>(null);
const policyFormSchema = z.object({
orgId: z.string().min(1, { message: t('orgRequired') }),
orgId: z.string().min(1, { message: t("orgRequired") }),
roleMapping: z.string().optional(),
orgMapping: z.string().optional()
});
@@ -133,7 +133,7 @@ export default function PoliciesPage() {
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -148,7 +148,7 @@ export default function PoliciesPage() {
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -167,7 +167,7 @@ export default function PoliciesPage() {
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -202,15 +202,15 @@ export default function PoliciesPage() {
};
setPolicies([...policies, newPolicy]);
toast({
title: t('success'),
description: t('orgPolicyAddedDescription')
title: t("success"),
description: t("orgPolicyAddedDescription")
});
setShowAddDialog(false);
form.reset();
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -244,8 +244,8 @@ export default function PoliciesPage() {
)
);
toast({
title: t('success'),
description: t('orgPolicyUpdatedDescription')
title: t("success"),
description: t("orgPolicyUpdatedDescription")
});
setShowAddDialog(false);
setEditingPolicy(null);
@@ -253,7 +253,7 @@ export default function PoliciesPage() {
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -271,13 +271,13 @@ export default function PoliciesPage() {
policies.filter((policy) => policy.orgId !== orgId)
);
toast({
title: t('success'),
description: t('orgPolicyDeletedDescription')
title: t("success"),
description: t("orgPolicyDeletedDescription")
});
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -295,13 +295,13 @@ export default function PoliciesPage() {
});
if (res.status === 200) {
toast({
title: t('success'),
description: t('defaultMappingsUpdatedDescription')
title: t("success"),
description: t("defaultMappingsUpdatedDescription")
});
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -320,18 +320,18 @@ export default function PoliciesPage() {
<Alert variant="neutral" className="mb-6">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">
{t('orgPoliciesAbout')}
{t("orgPoliciesAbout")}
</AlertTitle>
<AlertDescription>
{/*TODO(vlalx): Validate replacing */}
{t('orgPoliciesAboutDescription')}{" "}
{t("orgPoliciesAboutDescription")}{" "}
<Link
href="https://docs.pangolin.net/manage/identity-providers/auto-provisioning"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{t('orgPoliciesAboutDescriptionLink')}
{t("orgPoliciesAboutDescriptionLink")}
<ExternalLink className="ml-1 h-4 w-4 inline" />
</Link>
</AlertDescription>
@@ -340,10 +340,10 @@ export default function PoliciesPage() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('defaultMappingsOptional')}
{t("defaultMappingsOptional")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('defaultMappingsOptionalDescription')}
{t("defaultMappingsOptionalDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -362,13 +362,15 @@ export default function PoliciesPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('defaultMappingsRole')}
{t("defaultMappingsRole")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('defaultMappingsRoleDescription')}
{t(
"defaultMappingsRoleDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -381,13 +383,15 @@ export default function PoliciesPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('defaultMappingsOrg')}
{t("defaultMappingsOrg")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('defaultMappingsOrgDescription')}
{t(
"defaultMappingsOrgDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -402,7 +406,7 @@ export default function PoliciesPage() {
form="policy-default-mappings-form"
loading={updateDefaultMappingsLoading}
>
{t('defaultMappingsSubmit')}
{t("defaultMappingsSubmit")}
</Button>
</SettingsSectionFooter>
</SettingsSectionBody>
@@ -445,11 +449,11 @@ export default function PoliciesPage() {
<CredenzaHeader>
<CredenzaTitle>
{editingPolicy
? t('orgPoliciesEdit')
: t('orgPoliciesAdd')}
? t("orgPoliciesEdit")
: t("orgPoliciesAdd")}
</CredenzaTitle>
<CredenzaDescription>
{t('orgPolicyConfig')}
{t("orgPolicyConfig")}
</CredenzaDescription>
</CredenzaHeader>
<CredenzaBody>
@@ -466,7 +470,7 @@ export default function PoliciesPage() {
name="orgId"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>{t('org')}</FormLabel>
<FormLabel>{t("org")}</FormLabel>
{editingPolicy ? (
<Input {...field} disabled />
) : (
@@ -490,17 +494,25 @@ export default function PoliciesPage() {
org.orgId ===
field.value
)?.name
: t('orgSelect')}
: t(
"orgSelect"
)}
<CaretSortIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="p-0">
<Command>
<CommandInput placeholder={t('orgSearch')} />
<CommandInput
placeholder={t(
"orgSearch"
)}
/>
<CommandList>
<CommandEmpty>
{t('orgNotFound')}
{t(
"orgNotFound"
)}
</CommandEmpty>
<CommandGroup>
{organizations.map(
@@ -551,13 +563,15 @@ export default function PoliciesPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('roleMappingPathOptional')}
{t("roleMappingPathOptional")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('defaultMappingsRoleDescription')}
{t(
"defaultMappingsRoleDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -570,13 +584,15 @@ export default function PoliciesPage() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('orgMappingPathOptional')}
{t("orgMappingPathOptional")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('defaultMappingsOrgDescription')}
{t(
"defaultMappingsOrgDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -603,7 +619,9 @@ export default function PoliciesPage() {
: addPolicyLoading
}
>
{editingPolicy ? t('orgPolicyUpdate') : t('orgPolicyAdd')}
{editingPolicy
? t("orgPolicyUpdate")
: t("orgPolicyAdd")}
</Button>
</CredenzaFooter>
</CredenzaContent>

View File

@@ -48,18 +48,18 @@ export default function Page() {
const t = useTranslations();
const createIdpFormSchema = z.object({
name: z.string().min(2, { message: t('nameMin', {len: 2}) }),
name: z.string().min(2, { message: t("nameMin", { len: 2 }) }),
type: z.enum(["oidc"]),
clientId: z.string().min(1, { message: t('idpClientIdRequired') }),
clientSecret: z.string().min(1, { message: t('idpClientSecretRequired') }),
authUrl: z.url({ message: t('idpErrorAuthUrlInvalid') }),
tokenUrl: z.url({ message: t('idpErrorTokenUrlInvalid') }),
identifierPath: z
clientId: z.string().min(1, { message: t("idpClientIdRequired") }),
clientSecret: z
.string()
.min(1, { message: t('idpPathRequired') }),
.min(1, { message: t("idpClientSecretRequired") }),
authUrl: z.url({ message: t("idpErrorAuthUrlInvalid") }),
tokenUrl: z.url({ message: t("idpErrorTokenUrlInvalid") }),
identifierPath: z.string().min(1, { message: t("idpPathRequired") }),
emailPath: z.string().optional(),
namePath: z.string().optional(),
scopes: z.string().min(1, { message: t('idpScopeRequired') }),
scopes: z.string().min(1, { message: t("idpScopeRequired") }),
autoProvision: z.boolean().default(false)
});
@@ -75,7 +75,7 @@ export default function Page() {
{
id: "oidc",
title: "OAuth2/OIDC",
description: t('idpOidcDescription')
description: t("idpOidcDescription")
}
];
@@ -117,14 +117,14 @@ export default function Page() {
if (res.status === 201) {
toast({
title: t('success'),
description: t('idpCreatedDescription')
title: t("success"),
description: t("idpCreatedDescription")
});
router.push(`/admin/idp/${res.data.data.idpId}`);
}
} catch (e) {
toast({
title: t('error'),
title: t("error"),
description: formatAxiosError(e),
variant: "destructive"
});
@@ -137,8 +137,8 @@ export default function Page() {
<>
<div className="flex justify-between">
<HeaderTitle
title={t('idpCreate')}
description={t('idpCreateDescription')}
title={t("idpCreate")}
description={t("idpCreateDescription")}
/>
<Button
variant="outline"
@@ -146,7 +146,7 @@ export default function Page() {
router.push("/admin/idp");
}}
>
{t('idpSeeAll')}
{t("idpSeeAll")}
</Button>
</div>
@@ -154,10 +154,10 @@ export default function Page() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpTitle')}
{t("idpTitle")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpCreateSettingsDescription')}
{t("idpCreateSettingsDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -173,12 +173,14 @@ export default function Page() {
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>{t('name')}</FormLabel>
<FormLabel>
{t("name")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpDisplayName')}
{t("idpDisplayName")}
</FormDescription>
<FormMessage />
</FormItem>
@@ -188,7 +190,7 @@ export default function Page() {
<div className="flex items-start mb-0">
<SwitchInput
id="auto-provision-toggle"
label={t('idpAutoProvisionUsers')}
label={t("idpAutoProvisionUsers")}
defaultChecked={form.getValues(
"autoProvision"
)}
@@ -201,7 +203,7 @@ export default function Page() {
/>
</div>
<span className="text-sm text-muted-foreground">
{t('idpAutoProvisionUsersDescription')}
{t("idpAutoProvisionUsersDescription")}
</span>
</form>
</Form>
@@ -212,10 +214,10 @@ export default function Page() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpType')}
{t("idpType")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpTypeDescription')}
{t("idpTypeDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -235,10 +237,10 @@ export default function Page() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpOidcConfigure')}
{t("idpOidcConfigure")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpOidcConfigureDescription')}
{t("idpOidcConfigureDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -254,13 +256,15 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpClientId')}
{t("idpClientId")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpClientIdDescription')}
{t(
"idpClientIdDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -273,7 +277,7 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpClientSecret')}
{t("idpClientSecret")}
</FormLabel>
<FormControl>
<Input
@@ -282,7 +286,9 @@ export default function Page() {
/>
</FormControl>
<FormDescription>
{t('idpClientSecretDescription')}
{t(
"idpClientSecretDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -295,7 +301,7 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpAuthUrl')}
{t("idpAuthUrl")}
</FormLabel>
<FormControl>
<Input
@@ -304,7 +310,9 @@ export default function Page() {
/>
</FormControl>
<FormDescription>
{t('idpAuthUrlDescription')}
{t(
"idpAuthUrlDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -317,7 +325,7 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpTokenUrl')}
{t("idpTokenUrl")}
</FormLabel>
<FormControl>
<Input
@@ -326,7 +334,9 @@ export default function Page() {
/>
</FormControl>
<FormDescription>
{t('idpTokenUrlDescription')}
{t(
"idpTokenUrlDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -338,10 +348,10 @@ export default function Page() {
<Alert variant="neutral">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">
{t('idpOidcConfigureAlert')}
{t("idpOidcConfigureAlert")}
</AlertTitle>
<AlertDescription>
{t('idpOidcConfigureAlertDescription')}
{t("idpOidcConfigureAlertDescription")}
</AlertDescription>
</Alert>
</SettingsSectionBody>
@@ -350,10 +360,10 @@ export default function Page() {
<SettingsSection>
<SettingsSectionHeader>
<SettingsSectionTitle>
{t('idpToken')}
{t("idpToken")}
</SettingsSectionTitle>
<SettingsSectionDescription>
{t('idpTokenDescription')}
{t("idpTokenDescription")}
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
@@ -366,17 +376,21 @@ export default function Page() {
<Alert variant="neutral">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">
{t('idpJmespathAbout')}
{t("idpJmespathAbout")}
</AlertTitle>
<AlertDescription>
{t('idpJmespathAboutDescription')}{" "}
{t(
"idpJmespathAboutDescription"
)}{" "}
<a
href="https://jmespath.org"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline inline-flex items-center"
>
{t('idpJmespathAboutDescriptionLink')}{" "}
{t(
"idpJmespathAboutDescriptionLink"
)}{" "}
<ExternalLink className="ml-1 h-4 w-4" />
</a>
</AlertDescription>
@@ -388,13 +402,15 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpJmespathLabel')}
{t("idpJmespathLabel")}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpJmespathLabelDescription')}
{t(
"idpJmespathLabelDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -407,13 +423,17 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpJmespathEmailPathOptional')}
{t(
"idpJmespathEmailPathOptional"
)}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpJmespathEmailPathOptionalDescription')}
{t(
"idpJmespathEmailPathOptionalDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -426,13 +446,17 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpJmespathNamePathOptional')}
{t(
"idpJmespathNamePathOptional"
)}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpJmespathNamePathOptionalDescription')}
{t(
"idpJmespathNamePathOptionalDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -445,13 +469,17 @@ export default function Page() {
render={({ field }) => (
<FormItem>
<FormLabel>
{t('idpOidcConfigureScopes')}
{t(
"idpOidcConfigureScopes"
)}
</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
{t('idpOidcConfigureScopesDescription')}
{t(
"idpOidcConfigureScopesDescription"
)}
</FormDescription>
<FormMessage />
</FormItem>
@@ -473,7 +501,7 @@ export default function Page() {
router.push("/admin/idp");
}}
>
{t('cancel')}
{t("cancel")}
</Button>
<Button
type="submit"
@@ -481,7 +509,7 @@ export default function Page() {
loading={createLoading}
onClick={form.handleSubmit(onSubmit)}
>
{t('idpSubmit')}
{t("idpSubmit")}
</Button>
</div>
</>

View File

@@ -22,8 +22,8 @@ export default async function IdpPage() {
return (
<>
<SettingsSectionTitle
title={t('idpManage')}
description={t('idpManageDescription')}
title={t("idpManage")}
description={t("idpManageDescription")}
/>
<IdpTable idps={idps} />
</>