feat(common-config): show first-run notice dialog when editing providers

Display a one-time informational dialog explaining the Common Config
Snippet feature when users first open the add/edit provider form.
Uses a derived isOpen state from settings to avoid race conditions.
Adds commonConfigConfirmed flag to both TS and Rust settings types.
This commit is contained in:
Jason
2026-04-09 16:48:21 +08:00
parent ecb1fed5db
commit fa4297f4d3
6 changed files with 56 additions and 5 deletions
@@ -1,14 +1,14 @@
import { useEffect, useMemo, useState, useCallback } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useQuery } from "@tanstack/react-query";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Form, FormField, FormItem, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { providerSchema, type ProviderFormData } from "@/lib/schemas/provider";
import { providersApi, type AppId } from "@/lib/api";
import { providersApi, settingsApi, type AppId } from "@/lib/api";
import type {
ProviderCategory,
ProviderMeta,
@@ -84,6 +84,8 @@ import {
useCopilotAuth,
useCodexOauth,
} from "./hooks";
import { ConfirmDialog } from "@/components/ConfirmDialog";
import { useSettingsQuery } from "@/lib/query";
import {
CLAUDE_DEFAULT_CONFIG,
CODEX_DEFAULT_CONFIG,
@@ -141,6 +143,22 @@ export function ProviderForm({
}: ProviderFormProps) {
const { t } = useTranslation();
const isEditMode = Boolean(initialData);
const queryClient = useQueryClient();
const { data: settingsData } = useSettingsQuery();
const showCommonConfigNotice =
settingsData != null && settingsData.commonConfigConfirmed !== true;
const handleCommonConfigConfirm = async () => {
try {
if (settingsData) {
const { webdavSync: _, ...rest } = settingsData;
await settingsApi.save({ ...rest, commonConfigConfirmed: true });
await queryClient.invalidateQueries({ queryKey: ["settings"] });
}
} catch (error) {
console.error("Failed to save commonConfigConfirmed:", error);
}
};
const [selectedPresetId, setSelectedPresetId] = useState<string | null>(
initialData ? null : "custom",
@@ -1342,7 +1360,8 @@ export function ProviderForm({
);
return (
<Form {...form}>
<>
<Form {...form}>
<form
id="provider-form"
onSubmit={form.handleSubmit(handleSubmit)}
@@ -1836,8 +1855,19 @@ export function ProviderForm({
</Button>
</div>
)}
</form>
</Form>
</form>
</Form>
<ConfirmDialog
isOpen={showCommonConfigNotice}
variant="info"
title={t("confirm.commonConfig.title")}
message={t("confirm.commonConfig.message")}
confirmText={t("confirm.commonConfig.confirm")}
onConfirm={() => void handleCommonConfigConfirm()}
onCancel={() => void handleCommonConfigConfirm()}
/>
</>
);
}