fix(channels): reveal advanced validation errors #5239
Merge pull request #5239 from QuantumNous/fix/channel-advanced-errors
This commit is contained in:
+23
-13
@@ -24,7 +24,7 @@ import {
|
||||
useCallback,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { type SubmitErrorHandler, useForm } from 'react-hook-form'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import {
|
||||
@@ -140,6 +140,7 @@ import {
|
||||
hasModelConfigChanged,
|
||||
findMissingModelsInMapping,
|
||||
validateModelMappingJson,
|
||||
hasAdvancedSettingsErrors,
|
||||
} from '../../lib'
|
||||
import {
|
||||
collectInvalidStatusCodeEntries,
|
||||
@@ -204,7 +205,6 @@ function readAdvancedSettingsPreference(): boolean {
|
||||
|
||||
function hasAdvancedSettingsValues(values: ChannelFormValues): boolean {
|
||||
return Boolean(
|
||||
values.model_mapping?.trim() ||
|
||||
values.param_override?.trim() ||
|
||||
values.header_override?.trim() ||
|
||||
values.status_code_mapping?.trim() ||
|
||||
@@ -1008,6 +1008,26 @@ export function ChannelMutateDrawer({
|
||||
]
|
||||
)
|
||||
|
||||
const handleAdvancedSettingsOpenChange = useCallback((nextOpen: boolean) => {
|
||||
setAdvancedSettingsOpen(nextOpen)
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem(
|
||||
ADVANCED_SETTINGS_EXPANDED_KEY,
|
||||
String(nextOpen)
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onInvalid: SubmitErrorHandler<ChannelFormValues> = useCallback(
|
||||
(errors) => {
|
||||
if (hasAdvancedSettingsErrors(errors)) {
|
||||
handleAdvancedSettingsOpenChange(true)
|
||||
}
|
||||
toast.error(t('Please fix the highlighted fields before saving'))
|
||||
},
|
||||
[handleAdvancedSettingsOpenChange, t]
|
||||
)
|
||||
|
||||
// Handle drawer close
|
||||
const handleOpenChange = useCallback(
|
||||
(v: boolean) => {
|
||||
@@ -1020,16 +1040,6 @@ export function ChannelMutateDrawer({
|
||||
[onOpenChange, form]
|
||||
)
|
||||
|
||||
const handleAdvancedSettingsOpenChange = useCallback((nextOpen: boolean) => {
|
||||
setAdvancedSettingsOpen(nextOpen)
|
||||
if (typeof window !== 'undefined') {
|
||||
window.localStorage.setItem(
|
||||
ADVANCED_SETTINGS_EXPANDED_KEY,
|
||||
String(nextOpen)
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Sheet open={open} onOpenChange={handleOpenChange}>
|
||||
@@ -1060,7 +1070,7 @@ export function ChannelMutateDrawer({
|
||||
<Form {...form}>
|
||||
<form
|
||||
id='channel-form'
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
onSubmit={form.handleSubmit(onSubmit, onInvalid)}
|
||||
className={sideDrawerFormClassName('gap-5')}
|
||||
>
|
||||
{isChannelDetailLoading ? (
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (C) 2023-2026 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import type { FieldPath } from 'react-hook-form'
|
||||
import type { ChannelFormValues } from './channel-form'
|
||||
|
||||
type ChannelFormErrorMap = Partial<
|
||||
Record<FieldPath<ChannelFormValues>, unknown>
|
||||
>
|
||||
|
||||
const ADVANCED_SETTINGS_FIELDS = new Set<FieldPath<ChannelFormValues>>([
|
||||
'priority',
|
||||
'weight',
|
||||
'test_model',
|
||||
'auto_ban',
|
||||
'tag',
|
||||
'remark',
|
||||
'param_override',
|
||||
'header_override',
|
||||
'status_code_mapping',
|
||||
'force_format',
|
||||
'thinking_to_content',
|
||||
'pass_through_body_enabled',
|
||||
'proxy',
|
||||
'system_prompt',
|
||||
'system_prompt_override',
|
||||
'allow_service_tier',
|
||||
'disable_store',
|
||||
'allow_safety_identifier',
|
||||
'allow_include_obfuscation',
|
||||
'allow_inference_geo',
|
||||
'allow_speed',
|
||||
'claude_beta_query',
|
||||
'upstream_model_update_check_enabled',
|
||||
'upstream_model_update_auto_sync_enabled',
|
||||
'upstream_model_update_ignored_models',
|
||||
])
|
||||
|
||||
export function isAdvancedSettingsField(
|
||||
fieldName: string
|
||||
): fieldName is FieldPath<ChannelFormValues> {
|
||||
return ADVANCED_SETTINGS_FIELDS.has(fieldName as FieldPath<ChannelFormValues>)
|
||||
}
|
||||
|
||||
export function hasAdvancedSettingsErrors(
|
||||
errors: ChannelFormErrorMap
|
||||
): boolean {
|
||||
return Object.keys(errors).some((fieldName) =>
|
||||
isAdvancedSettingsField(fieldName)
|
||||
)
|
||||
}
|
||||
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
// Re-export all library functions
|
||||
export * from './channel-actions'
|
||||
export * from './channel-form-errors'
|
||||
export * from './channel-form'
|
||||
export * from './channel-type-config'
|
||||
export * from './channel-utils'
|
||||
|
||||
Reference in New Issue
Block a user