Commit 77d31575 by QuentinHsu

fix(model-pricing): commit visual pricing drafts on save

- Commit the open visual editor draft before saving model pricing settings
- Show unsaved draft differences against persisted model pricing values
- Move model pricing actions into the editor toolbar and refine the visual editor layout
parent 39e05118
......@@ -37,7 +37,6 @@ import {
SettingsSwitchContent,
SettingsSwitchItem,
} from '../components/settings-form-layout'
import { SettingsPageActionsPortal } from '../components/settings-page-context'
import {
ModelRatioVisualEditor,
type ModelRatioVisualEditorHandle,
......@@ -59,6 +58,7 @@ type ModelFormValues = {
type ModelRatioFormProps = {
form: UseFormReturn<ModelFormValues>
savedValues: ModelFormValues
onSave: (values: ModelFormValues) => Promise<void>
onReset: () => void
isSaving: boolean
......@@ -67,6 +67,7 @@ type ModelRatioFormProps = {
export const ModelRatioForm = memo(function ModelRatioForm({
form,
savedValues,
onSave,
onReset,
isSaving,
......@@ -101,7 +102,24 @@ export const ModelRatioForm = memo(function ModelRatioForm({
return (
<div className='space-y-6'>
<div className='flex justify-end'>
<div className='flex flex-wrap justify-end gap-2'>
<Button
type='button'
variant='destructive'
size='sm'
onClick={onReset}
disabled={isResetting}
>
{t('Reset prices')}
</Button>
<Button
type='button'
size='sm'
onClick={handleSave}
disabled={isSaving}
>
{isSaving ? t('Saving...') : t('Save model prices')}
</Button>
<Button variant='outline' size='sm' onClick={toggleEditMode}>
{editMode === 'visual' ? (
<>
......@@ -118,29 +136,20 @@ export const ModelRatioForm = memo(function ModelRatioForm({
</div>
<Form {...form}>
<SettingsPageActionsPortal>
<Button
type='button'
variant='destructive'
size='sm'
onClick={onReset}
disabled={isResetting}
>
{t('Reset prices')}
</Button>
<Button
type='button'
size='sm'
onClick={handleSave}
disabled={isSaving}
>
{isSaving ? t('Saving...') : t('Save model prices')}
</Button>
</SettingsPageActionsPortal>
{editMode === 'visual' ? (
<div className='space-y-6'>
<ModelRatioVisualEditor
ref={visualEditorRef}
savedModelPrice={savedValues.ModelPrice}
savedModelRatio={savedValues.ModelRatio}
savedCacheRatio={savedValues.CacheRatio}
savedCreateCacheRatio={savedValues.CreateCacheRatio}
savedCompletionRatio={savedValues.CompletionRatio}
savedImageRatio={savedValues.ImageRatio}
savedAudioRatio={savedValues.AudioRatio}
savedAudioCompletionRatio={savedValues.AudioCompletionRatio}
savedBillingMode={savedValues.BillingMode}
savedBillingExpr={savedValues.BillingExpr}
modelPrice={form.watch('ModelPrice')}
modelRatio={form.watch('ModelRatio')}
cacheRatio={form.watch('CacheRatio')}
......
......@@ -250,6 +250,9 @@ export function RatioSettingsCard({
BillingMode: normalizeJsonString(modelDefaults.BillingMode),
BillingExpr: normalizeJsonString(modelDefaults.BillingExpr),
})
const [savedModelValues, setSavedModelValues] = useState(
modelNormalizedDefaults.current
)
const groupNormalizedDefaults = useRef({
GroupRatio: normalizeJsonString(groupDefaults.GroupRatio),
......@@ -315,6 +318,7 @@ export function RatioSettingsCard({
BillingMode: normalizeJsonString(modelDefaults.BillingMode),
BillingExpr: normalizeJsonString(modelDefaults.BillingExpr),
}
setSavedModelValues(modelNormalizedDefaults.current)
modelForm.reset({
...modelDefaults,
......@@ -395,6 +399,9 @@ export function RatioSettingsCard({
const apiKey = apiKeyMap[key as string] || (key as string)
await updateOption.mutateAsync({ key: apiKey, value: normalized[key] })
}
modelNormalizedDefaults.current = normalized
setSavedModelValues(normalized)
},
[t, updateOption]
)
......@@ -462,6 +469,7 @@ export function RatioSettingsCard({
return (
<ModelRatioForm
form={modelForm}
savedValues={savedModelValues}
onSave={saveModelRatios}
onReset={handleResetRatios}
isSaving={updateOption.isPending}
......
......@@ -1253,6 +1253,7 @@
"DoubaoVideo": "DoubaoVideo",
"Double check the configuration below. Your system will be locked until initialization is complete.": "Double check the configuration below. Your system will be locked until initialization is complete.",
"Download": "Download",
"Draft": "Draft",
"Draw": "Draw",
"Drawing": "Drawing",
"Drawing logs": "Drawing logs",
......@@ -4414,6 +4415,7 @@
"We could not load the setup status.": "We could not load the setup status.",
"We will prompt your device to confirm using biometrics or your hardware key.": "We will prompt your device to confirm using biometrics or your hardware key.",
"We'll be back online shortly.": "We'll be back online shortly.",
"Will be removed": "Will be removed",
"Web search": "Web search",
"Web Search": "Web Search",
"Webhook Configuration:": "Webhook Configuration:",
......
......@@ -1253,6 +1253,7 @@
"DoubaoVideo": "DoubaoVideo",
"Double check the configuration below. Your system will be locked until initialization is complete.": "Vérifiez la configuration ci-dessous. Votre système sera verrouillé jusqu'à ce que l'initialisation soit terminée.",
"Download": "Télécharger",
"Draft": "Brouillon",
"Draw": "Dessin",
"Drawing": "Dessin",
"Drawing logs": "Journaux de dessin",
......@@ -4414,6 +4415,7 @@
"We could not load the setup status.": "Nous n'avons pas pu charger l'état de la configuration.",
"We will prompt your device to confirm using biometrics or your hardware key.": "Nous allons demander à votre appareil de confirmer en utilisant la biométrie ou votre clé matérielle.",
"We'll be back online shortly.": "Nous serons de retour en ligne sous peu.",
"Will be removed": "Sera supprimé",
"Web search": "Recherche web",
"Web Search": "Recherche web",
"Webhook Configuration:": "Configuration du Webhook :",
......
......@@ -1253,6 +1253,7 @@
"DoubaoVideo": "DoubaoVideo",
"Double check the configuration below. Your system will be locked until initialization is complete.": "下記の設定を再確認してください。初期化が完了するまでシステムはロックされます。",
"Download": "ダウンロード",
"Draft": "下書き",
"Draw": "描画",
"Drawing": "画像生成",
"Drawing logs": "描画ログ",
......@@ -4414,6 +4415,7 @@
"We could not load the setup status.": "セットアップステータスを読み込めませんでした。",
"We will prompt your device to confirm using biometrics or your hardware key.": "生体認証またはハードウェアキーを使用して確認するよう、デバイスにプロンプトが表示されます。",
"We'll be back online shortly.": "まもなくオンラインに戻ります。",
"Will be removed": "削除予定",
"Web search": "ウェブ検索",
"Web Search": "Web 検索",
"Webhook Configuration:": "Webhook設定:",
......
......@@ -1253,6 +1253,7 @@
"DoubaoVideo": "DoubaoVideo",
"Double check the configuration below. Your system will be locked until initialization is complete.": "Дважды проверьте конфигурацию ниже. Ваша система будет заблокирована до завершения инициализации.",
"Download": "Скачать",
"Draft": "Черновик",
"Draw": "Рисование",
"Drawing": "Рисование",
"Drawing logs": "Журналы рисования",
......@@ -4414,6 +4415,7 @@
"We could not load the setup status.": "Не удалось загрузить статус настройки.",
"We will prompt your device to confirm using biometrics or your hardware key.": "Мы предложим вашему устройству подтвердить действие с помощью биометрии или аппаратного ключа.",
"We'll be back online shortly.": "Мы скоро вернемся в сеть.",
"Will be removed": "Будет удалено",
"Web search": "Веб-поиск",
"Web Search": "Веб-поиск",
"Webhook Configuration:": "Конфигурация веб-хука:",
......
......@@ -1253,6 +1253,7 @@
"DoubaoVideo": "DoubaoVideo",
"Double check the configuration below. Your system will be locked until initialization is complete.": "Kiểm tra kỹ lại cấu hình bên dưới. Hệ thống của bạn sẽ bị khóa cho đến khi quá trình khởi tạo hoàn tất.",
"Download": "Tải xuống",
"Draft": "Bản nháp",
"Draw": "Vẽ",
"Drawing": "Vẽ",
"Drawing logs": "Nhật ký vẽ",
......@@ -4414,6 +4415,7 @@
"We could not load the setup status.": "Chúng tôi không thể tải trạng thái thiết lập.",
"We will prompt your device to confirm using biometrics or your hardware key.": "Chúng tôi sẽ yêu cầu thiết bị của bạn xác nhận bằng cách sử dụng sinh trắc học hoặc khóa bảo mật phần cứng của bạn.",
"We'll be back online shortly.": "Chúng tôi sẽ sớm trực tuyến trở lại.",
"Will be removed": "Sẽ bị xóa",
"Web search": "Tìm kiếm web",
"Web Search": "Tìm kiếm web",
"Webhook Configuration:": "Cấu hình Webhook:",
......
......@@ -1253,6 +1253,7 @@
"DoubaoVideo": "DoubaoVideo",
"Double check the configuration below. Your system will be locked until initialization is complete.": "仔细检查以下配置。您的系统将在初始化完成前保持锁定状态。",
"Download": "下载",
"Draft": "草稿",
"Draw": "绘图",
"Drawing": "绘图",
"Drawing logs": "绘制日志",
......@@ -4414,6 +4415,7 @@
"We could not load the setup status.": "我们无法加载设置状态。",
"We will prompt your device to confirm using biometrics or your hardware key.": "我们将提示您的设备使用生物识别或硬件密钥进行确认。",
"We'll be back online shortly.": "我们将很快恢复在线。",
"Will be removed": "将被移除",
"Web search": "网络搜索",
"Web Search": "网页搜索",
"Webhook Configuration:": "Webhook 配置:",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment