mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-15 09:26:40 +00:00
first fixes
This commit is contained in:
@@ -39,10 +39,8 @@ type CreateRoleFormProps = {
|
||||
afterCreate?: (res: CreateRoleResponse) => Promise<void>;
|
||||
};
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const formSchema = z.object({
|
||||
name: z.string({ message: t('accessRoleNameRequired') }).max(32),
|
||||
name: z.string({ message: "Name is required" }).max(32),
|
||||
description: z.string().max(255).optional()
|
||||
});
|
||||
|
||||
@@ -52,6 +50,7 @@ export default function CreateRoleForm({
|
||||
afterCreate
|
||||
}: CreateRoleFormProps) {
|
||||
const { org } = useOrgContext();
|
||||
const t = useTranslations();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
|
||||
@@ -47,10 +47,8 @@ type CreateRoleFormProps = {
|
||||
afterDelete?: () => void;
|
||||
};
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const formSchema = z.object({
|
||||
newRoleId: z.string({ message: t('accessRoleErrorNewRequired') })
|
||||
newRoleId: z.string({ message: "New role is required" })
|
||||
});
|
||||
|
||||
export default function DeleteRoleForm({
|
||||
@@ -60,6 +58,7 @@ export default function DeleteRoleForm({
|
||||
afterDelete
|
||||
}: CreateRoleFormProps) {
|
||||
const { org } = useOrgContext();
|
||||
const t = useTranslations();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [roles, setRoles] = useState<ListRolesResponse["roles"]>([]);
|
||||
|
||||
@@ -60,30 +60,28 @@ interface IdpOption {
|
||||
type: string;
|
||||
}
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const internalFormSchema = z.object({
|
||||
email: z.string().email({ message: t('emailInvalid') }),
|
||||
validForHours: z.string().min(1, { message: t('inviteValidityDuration') }),
|
||||
roleId: z.string().min(1, { message: t('accessRoleSelectPlease') })
|
||||
email: z.string().email({ message: "Invalid email address" }),
|
||||
validForHours: z.string().min(1, { message: "Please select a duration" }),
|
||||
roleId: z.string().min(1, { message: "Please select a role" })
|
||||
});
|
||||
|
||||
const externalFormSchema = z.object({
|
||||
username: z.string().min(1, { message: t('usernameRequired') }),
|
||||
username: z.string().min(1, { message: "Username is required" }),
|
||||
email: z
|
||||
.string()
|
||||
.email({ message: t('emailInvalid') })
|
||||
.email({ message: "Invalid email address" })
|
||||
.optional()
|
||||
.or(z.literal("")),
|
||||
name: z.string().optional(),
|
||||
roleId: z.string().min(1, { message: t('accessRoleSelectPlease') }),
|
||||
idpId: z.string().min(1, { message: t('idpSelectPlease') })
|
||||
roleId: z.string().min(1, { message: "Please select a role" }),
|
||||
idpId: z.string().min(1, { message: "Please select an identity provider" })
|
||||
});
|
||||
|
||||
const formatIdpType = (type: string) => {
|
||||
switch (type.toLowerCase()) {
|
||||
case "oidc":
|
||||
return t('idpGenericOidc');
|
||||
return "Generic OAuth2/OIDC provider.";
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
@@ -94,6 +92,7 @@ export default function Page() {
|
||||
const router = useRouter();
|
||||
const { env } = useEnvContext();
|
||||
const api = createApiClient({ env });
|
||||
const t = useTranslations();
|
||||
|
||||
const [userType, setUserType] = useState<UserType | null>("internal");
|
||||
const [inviteLink, setInviteLink] = useState<string | null>(null);
|
||||
@@ -351,7 +350,7 @@ export default function Page() {
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>
|
||||
{t('userInfo')}
|
||||
{t('userSettings')}
|
||||
</SettingsSectionTitle>
|
||||
<SettingsSectionDescription>
|
||||
{t('userSettingsDescription')}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { verifySession } from "@app/lib/auth/verifySession";
|
||||
import AccessPageHeaderAndNav from "../AccessPageHeaderAndNav";
|
||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type UsersPageProps = {
|
||||
params: Promise<{ orgId: string }>;
|
||||
@@ -24,8 +23,7 @@ export default async function UsersPage(props: UsersPageProps) {
|
||||
|
||||
const getUser = cache(verifySession);
|
||||
const user = await getUser();
|
||||
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
let users: ListUsersResponse["users"] = [];
|
||||
let hasInvitations = false;
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
import { GetApiKeyResponse } from "@server/routers/apiKeys";
|
||||
import ApiKeyProvider from "@app/providers/ApiKeyProvider";
|
||||
import { HorizontalTabs } from "@app/components/HorizontalTabs";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
interface SettingsLayoutProps {
|
||||
children: React.ReactNode;
|
||||
@@ -24,8 +24,7 @@ interface SettingsLayoutProps {
|
||||
|
||||
export default async function SettingsLayout(props: SettingsLayoutProps) {
|
||||
const params = await props.params;
|
||||
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
const { children } = props;
|
||||
|
||||
|
||||
@@ -45,10 +45,10 @@ export default function Page() {
|
||||
.catch((e) => {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error loading API key actions",
|
||||
title: t('apiKeysPermissionsErrorLoadingActions'),
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"Error loading API key actions"
|
||||
t('apiKeysPermissionsErrorLoadingActions')
|
||||
)
|
||||
});
|
||||
});
|
||||
@@ -79,18 +79,18 @@ export default function Page() {
|
||||
)
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Error setting permissions", e);
|
||||
console.error(t('apiKeysErrorSetPermission'), e);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error setting permissions",
|
||||
title: t('apiKeysErrorSetPermission'),
|
||||
description: formatAxiosError(e)
|
||||
});
|
||||
});
|
||||
|
||||
if (actionsRes && actionsRes.status === 200) {
|
||||
toast({
|
||||
title: "Permissions updated",
|
||||
description: "The permissions have been updated."
|
||||
title: t('apiKeysPermissionsUpdated'),
|
||||
description: t('apiKeysPermissionsUpdatedDescription')
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AxiosResponse } from "axios";
|
||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||
import OrgApiKeysTable, { OrgApiKeyRow } from "./OrgApiKeysTable";
|
||||
import { ListOrgApiKeysResponse } from "@server/routers/apiKeys";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
type ApiKeyPageProps = {
|
||||
params: Promise<{ orgId: string }>;
|
||||
@@ -14,7 +14,8 @@ export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function ApiKeysPage(props: ApiKeyPageProps) {
|
||||
const params = await props.params;
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
let apiKeys: ListOrgApiKeysResponse["apiKeys"] = [];
|
||||
try {
|
||||
const res = await internal.get<AxiosResponse<ListOrgApiKeysResponse>>(
|
||||
|
||||
@@ -19,7 +19,7 @@ import UserProvider from "@app/providers/UserProvider";
|
||||
import { Layout } from "@app/components/Layout";
|
||||
import { SidebarNavItem, SidebarNavProps } from "@app/components/SidebarNav";
|
||||
import { orgNavItems } from "@app/app/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -47,7 +47,7 @@ export default async function SettingsLayout(props: SettingsLayoutProps) {
|
||||
|
||||
const cookie = await authCookieHeader();
|
||||
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
try {
|
||||
const getOrgUser = cache(() =>
|
||||
|
||||
@@ -89,11 +89,8 @@ export default function SitesTable({ resources, orgId }: ResourcesTableProps) {
|
||||
.catch((e) => {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to toggle resource",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred while updating the resource"
|
||||
)
|
||||
title: t('resourcesErrorUpdate'),
|
||||
description: formatAxiosError(e, t('resourcesErrorUpdateDescription'))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,8 +67,6 @@ import {
|
||||
import { SwitchInput } from "@app/components/SwitchInput";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const GeneralFormSchema = z
|
||||
.object({
|
||||
subdomain: z.string().optional(),
|
||||
@@ -91,7 +89,7 @@ const GeneralFormSchema = z
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: t('proxyErrorInvalidPort'),
|
||||
message: "Invalid port number",
|
||||
path: ["proxyPort"]
|
||||
}
|
||||
)
|
||||
@@ -103,7 +101,7 @@ const GeneralFormSchema = z
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: t('subdomainErrorInvalid'),
|
||||
message: "Invalid subdomain",
|
||||
path: ["subdomain"]
|
||||
}
|
||||
);
|
||||
@@ -121,6 +119,7 @@ export default function GeneralForm() {
|
||||
const { resource, updateResource } = useResourceContext();
|
||||
const { org } = useOrgContext();
|
||||
const router = useRouter();
|
||||
const t = useTranslations();
|
||||
|
||||
const { env } = useEnvContext();
|
||||
|
||||
@@ -178,10 +177,7 @@ export default function GeneralForm() {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: t('domainErrorFetch'),
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
t('domainErrorFetchDescription')
|
||||
)
|
||||
description: formatAxiosError(e, t('domainErrorFetchDescription'))
|
||||
});
|
||||
});
|
||||
|
||||
@@ -220,10 +216,7 @@ export default function GeneralForm() {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: t('resourceErrorUpdate'),
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
t('resourceErrorUpdateDescription')
|
||||
)
|
||||
description: formatAxiosError(e, t('resourceErrorUpdateDescription'))
|
||||
});
|
||||
});
|
||||
|
||||
@@ -259,9 +252,7 @@ export default function GeneralForm() {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: t('resourceErrorTransfer'),
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
t('resourceErrorTransferDescription')
|
||||
description: formatAxiosError(e, t('resourceErrorTransferDescription')
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
@@ -93,8 +93,6 @@ type LocalTarget = Omit<
|
||||
"protocol"
|
||||
>;
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const proxySettingsSchema = z.object({
|
||||
setHostHeader: z
|
||||
.string()
|
||||
@@ -107,7 +105,7 @@ const proxySettingsSchema = z.object({
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: t('proxyErrorInvalidHeader')
|
||||
message: "Invalid custom Host Header value. Use domain name format, or save empty to unset custom Host Header."
|
||||
}
|
||||
)
|
||||
});
|
||||
@@ -125,7 +123,7 @@ const tlsSettingsSchema = z.object({
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: t('proxyErrorTls')
|
||||
message: "Invalid TLS Server Name. Use domain name format, or save empty to remove the TLS Server Name."
|
||||
}
|
||||
)
|
||||
});
|
||||
@@ -138,6 +136,7 @@ export default function ReverseProxyTargets(props: {
|
||||
params: Promise<{ resourceId: number }>;
|
||||
}) {
|
||||
const params = use(props.params);
|
||||
const t = useTranslations();
|
||||
|
||||
const { resource, updateResource } = useResourceContext();
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import { GetOrgResponse } from "@server/routers/org";
|
||||
import OrgProvider from "@app/providers/OrgProvider";
|
||||
import ResourcesSplashCard from "./ResourcesSplashCard";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type ResourcesPageProps = {
|
||||
params: Promise<{ orgId: string }>;
|
||||
@@ -20,6 +19,8 @@ export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function ResourcesPage(props: ResourcesPageProps) {
|
||||
const params = await props.params;
|
||||
const t = await getTranslations();
|
||||
|
||||
let resources: ListResourcesResponse["resources"] = [];
|
||||
try {
|
||||
const res = await internal.get<AxiosResponse<ListResourcesResponse>>(
|
||||
@@ -47,8 +48,6 @@ export default async function ResourcesPage(props: ResourcesPageProps) {
|
||||
redirect(`/${params.orgId}/settings/resources`);
|
||||
}
|
||||
|
||||
const t = useTranslations();
|
||||
|
||||
const resourceRows: ResourceRow[] = resources.map((resource) => {
|
||||
return {
|
||||
id: resource.resourceId,
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
import { GetApiKeyResponse } from "@server/routers/apiKeys";
|
||||
import ApiKeyProvider from "@app/providers/ApiKeyProvider";
|
||||
import { HorizontalTabs } from "@app/components/HorizontalTabs";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
interface SettingsLayoutProps {
|
||||
children: React.ReactNode;
|
||||
@@ -25,7 +25,7 @@ interface SettingsLayoutProps {
|
||||
export default async function SettingsLayout(props: SettingsLayoutProps) {
|
||||
const params = await props.params;
|
||||
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
const { children } = props;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator
|
||||
} from "@app/components/ui/breadcrumb";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
interface SettingsLayoutProps {
|
||||
children: React.ReactNode;
|
||||
@@ -37,7 +37,7 @@ export default async function SettingsLayout(props: SettingsLayoutProps) {
|
||||
redirect("/admin/idp");
|
||||
}
|
||||
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
const navItems: HorizontalTabs = [
|
||||
{
|
||||
|
||||
@@ -371,7 +371,7 @@ export default function Page() {
|
||||
</AlertTitle>
|
||||
<AlertDescription>
|
||||
{/*TODO(vlalx): Validate replacing */}
|
||||
{t('idpJmespathAboutDescription')}
|
||||
{t('idpJmespathAboutDescription')}{" "}
|
||||
<a
|
||||
href="https://jmespath.org"
|
||||
target="_blank"
|
||||
@@ -447,8 +447,7 @@ export default function Page() {
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
"idpOidcConfigureScopes": "Scopes"
|
||||
{t('')}
|
||||
{t('idpOidcConfigureScopes')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
|
||||
@@ -3,7 +3,7 @@ import { authCookieHeader } from "@app/lib/api/cookies";
|
||||
import { AxiosResponse } from "axios";
|
||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||
import IdpTable, { IdpRow } from "./AdminIdpTable";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
export default async function IdpPage() {
|
||||
let idps: IdpRow[] = [];
|
||||
@@ -16,7 +16,8 @@ export default async function IdpPage() {
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
const t = useTranslations();
|
||||
|
||||
const t = await getTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -7,7 +7,6 @@ import UsersTable, { GlobalUserRow } from "./AdminUsersTable";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
|
||||
import { InfoIcon } from "lucide-react";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
type PageProps = {
|
||||
params: Promise<{ orgId: string }>;
|
||||
@@ -26,7 +25,8 @@ export default async function UsersPage(props: PageProps) {
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
const t = useTranslations();
|
||||
|
||||
const t = await getTranslations();
|
||||
|
||||
const userRows: GlobalUserRow[] = rows.map((row) => {
|
||||
return {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AxiosResponse } from "axios";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
import { Metadata } from "next";
|
||||
import { cache } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Auth - Pangolin`,
|
||||
@@ -22,7 +22,7 @@ type AuthLayoutProps = {
|
||||
export default async function AuthLayout({ children }: AuthLayoutProps) {
|
||||
const getUser = cache(verifySession);
|
||||
const user = await getUser();
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
const licenseStatusRes = await cache(
|
||||
async () =>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { cleanRedirect } from "@app/lib/cleanRedirect";
|
||||
import db from "@server/db";
|
||||
import { idp } from "@server/db/schemas";
|
||||
import { LoginFormIDP } from "@app/components/LoginForm";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -41,7 +41,7 @@ export default async function Page(props: {
|
||||
name: idp.name
|
||||
})) as LoginFormIDP[];
|
||||
|
||||
const t = useTranslations();
|
||||
const t = await getTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import Link from "next/link";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
export default async function NotFound() {
|
||||
const t = useTranslations();
|
||||
|
||||
const t = await getTranslations();
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-md mx-auto p-3 md:mt-32 text-center">
|
||||
<h1 className="text-6xl font-bold mb-4">404</h1>
|
||||
|
||||
Reference in New Issue
Block a user