Add niceid to ui and api for providers

This commit is contained in:
Owen
2026-08-14 09:43:03 -04:00
parent f0f5e9219b
commit 5d37f44241
18 changed files with 219 additions and 75 deletions
@@ -0,0 +1,12 @@
import { redirect } from "next/navigation";
type Props = {
params: Promise<{ orgId: string; niceId: string }>;
};
export default async function AiProviderConfigurationRedirect({
params
}: Props) {
const { orgId, niceId } = await params;
redirect(`/${orgId}/settings/ai-providers/${niceId}/network`);
}
@@ -55,6 +55,7 @@ export default function AiProviderGeneralPage() {
.string()
.trim()
.min(1, { message: t("nameRequired") }),
niceId: z.string().min(1).max(255).optional(),
enabled: z.boolean(),
capabilities: z.array(z.enum(AI_CAPABILITIES)).optional()
})
@@ -76,6 +77,7 @@ export default function AiProviderGeneralPage() {
resolver: zodResolver(generalSchema),
defaultValues: {
name: provider.name,
niceId: provider.niceId,
enabled: provider.enabled,
capabilities: provider.capabilities ?? []
}
@@ -86,10 +88,12 @@ export default function AiProviderGeneralPage() {
try {
const body: {
name: string;
niceId?: string;
enabled: boolean;
capabilities?: AiCapability[];
} = {
name: values.name.trim(),
niceId: values.niceId,
enabled: values.enabled,
capabilities: values.capabilities ?? []
};
@@ -101,6 +105,7 @@ export default function AiProviderGeneralPage() {
updateProvider(updated);
form.reset({
name: updated.name,
niceId: updated.niceId,
enabled: updated.enabled,
capabilities: updated.capabilities ?? []
});
@@ -108,6 +113,13 @@ export default function AiProviderGeneralPage() {
title: t("success"),
description: t("aiProviderUpdated")
});
if (values.niceId && values.niceId !== provider.niceId) {
router.replace(
`/${provider.orgId}/settings/ai-providers/${values.niceId}/general`
);
}
router.refresh();
} catch (e) {
toast({
@@ -190,6 +202,29 @@ export default function AiProviderGeneralPage() {
/>
</SettingsFormCell>
<SettingsFormCell span="half">
<FormField
control={form.control}
name="niceId"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("identifier")}
</FormLabel>
<FormControl>
<Input
{...field}
placeholder={t(
"enterIdentifier"
)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</SettingsFormCell>
<SettingsFormCell span="full">
<FormField
control={form.control}
@@ -20,17 +20,17 @@ export const dynamic = "force-dynamic";
type Props = {
children: React.ReactNode;
params: Promise<{ orgId: string; providerId: string }>;
params: Promise<{ orgId: string; niceId: string }>;
};
export default async function AiProviderLayout({ children, params }: Props) {
const { orgId, providerId } = await params;
const { orgId, niceId } = await params;
const t = await getTranslations();
let provider = null;
try {
const res = await internal.get<AxiosResponse<GetAiProviderResponse>>(
`/ai-provider/${providerId}`,
`/org/${orgId}/ai-provider/${niceId}`,
await authCookieHeader()
);
provider = res.data.data.provider;
@@ -63,23 +63,23 @@ export default async function AiProviderLayout({ children, params }: Props) {
const navItems = [
{
title: t("general"),
href: "/{orgId}/settings/ai-providers/{providerId}/general"
href: "/{orgId}/settings/ai-providers/{niceId}/general"
},
{
title: t("aiProviderNetworkSettings"),
href: "/{orgId}/settings/ai-providers/{providerId}/network"
href: "/{orgId}/settings/ai-providers/{niceId}/network"
},
{
title: t("aiProviderModels"),
href: "/{orgId}/settings/ai-providers/{providerId}/models"
href: "/{orgId}/settings/ai-providers/{niceId}/models"
},
{
title: t("aiProviderAuthSettings"),
href: "/{orgId}/settings/ai-providers/{providerId}/authentication"
href: "/{orgId}/settings/ai-providers/{niceId}/authentication"
},
{
title: t("aiProviderBudgetSettings"),
href: "/{orgId}/settings/ai-providers/{providerId}/budget"
href: "/{orgId}/settings/ai-providers/{niceId}/budget"
}
];
@@ -0,0 +1,10 @@
import { redirect } from "next/navigation";
type Props = {
params: Promise<{ orgId: string; niceId: string }>;
};
export default async function AiProviderPage({ params }: Props) {
const { orgId, niceId } = await params;
redirect(`/${orgId}/settings/ai-providers/${niceId}/general`);
}
@@ -1,12 +0,0 @@
import { redirect } from "next/navigation";
type Props = {
params: Promise<{ orgId: string; providerId: string }>;
};
export default async function AiProviderConfigurationRedirect({
params
}: Props) {
const { orgId, providerId } = await params;
redirect(`/${orgId}/settings/ai-providers/${providerId}/network`);
}
@@ -1,10 +0,0 @@
import { redirect } from "next/navigation";
type Props = {
params: Promise<{ orgId: string; providerId: string }>;
};
export default async function AiProviderPage({ params }: Props) {
const { orgId, providerId } = await params;
redirect(`/${orgId}/settings/ai-providers/${providerId}/general`);
}
@@ -222,6 +222,7 @@ export default function CreateAiProviderPage() {
>(`/org/${orgId}/ai-provider`, toAiProviderCreatePayload(values));
const providerId = res.data.data.provider.providerId;
const niceId = res.data.data.provider.niceId;
if (showTargets && targets.length > 0) {
try {
@@ -236,7 +237,7 @@ export default function CreateAiProviderPage() {
)
});
router.push(
`/${orgId}/settings/ai-providers/${providerId}/network`
`/${orgId}/settings/ai-providers/${niceId}/network`
);
return;
}
@@ -255,7 +256,7 @@ export default function CreateAiProviderPage() {
)
});
router.push(
`/${orgId}/settings/ai-providers/${providerId}/models`
`/${orgId}/settings/ai-providers/${niceId}/models`
);
return;
}
@@ -266,7 +267,7 @@ export default function CreateAiProviderPage() {
description: t("aiProviderCreated")
});
router.push(`/${orgId}/settings/ai-providers/${providerId}`);
router.push(`/${orgId}/settings/ai-providers/${niceId}`);
} catch (e) {
toast({
variant: "destructive",
@@ -53,6 +53,7 @@ export default async function AiProvidersPage({ params, searchParams }: Props) {
orgId={orgId}
providers={providers.map((provider) => ({
providerId: provider.providerId,
niceId: provider.niceId,
name: provider.name,
type: provider.type,
routingMode: provider.routingMode,
+4 -3
View File
@@ -27,6 +27,7 @@ import { useDebouncedCallback } from "use-debounce";
export type AiProviderRow = {
providerId: number;
niceId: string;
name: string;
type: string;
routingMode: string;
@@ -176,7 +177,7 @@ export default function AiProvidersTable({
header: () => <span className="p-3">{t("name")}</span>,
cell: ({ row }) => (
<Link
href={`/${orgId}/settings/ai-providers/${row.original.providerId}`}
href={`/${orgId}/settings/ai-providers/${row.original.niceId}`}
className="hover:underline"
>
{row.original.name}
@@ -238,7 +239,7 @@ export default function AiProvidersTable({
<DropdownMenuContent align="end">
<DropdownMenuItem asChild>
<Link
href={`/${orgId}/settings/ai-providers/${row.original.providerId}`}
href={`/${orgId}/settings/ai-providers/${row.original.niceId}`}
>
{t("edit")}
</Link>
@@ -256,7 +257,7 @@ export default function AiProvidersTable({
</DropdownMenuContent>
</DropdownMenu>
<Link
href={`/${orgId}/settings/ai-providers/${row.original.providerId}`}
href={`/${orgId}/settings/ai-providers/${row.original.niceId}`}
>
<Button variant="outline">
{t("edit")}