fix: misc frontend fixes for agent log, login, search settings (#16137)

### What problem does this PR solve?

fix: misc frontend fixes for agent log, login, search settings
- agent-log: restore server-side pagination on export and search;
replace hardcoded labels with i18n keys; switch container to
text-text-primary
- login: validate register nickname against NICKNAME_PATTERN with
reusable setting i18n
- next-search: align llm_setting schema with chat (LlmSettingFieldSchema
+ LLMIdFormField nested, LlmSettingEnabledSchema at form
root) so the slider Switch reads the correct path; strip *Enabled flags
before submit to avoid backend "Unrecognized field name"
  errors
  - locales: add common.reset (zh/en)
  - skills/go-naming: fix relative link to rules/named.md

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
chanx
2026-06-17 16:20:26 +08:00
committed by GitHub
parent 3247e353c7
commit 9302233b95
8 changed files with 71 additions and 35 deletions

View File

@@ -3,4 +3,4 @@ name: go-naming
description: Go naming conventions and best practices. Use this skill when working with Go code and need to name packages, files, directories, structs, interfaces, functions, variables, or constants. Provides comprehensive naming guidelines following Go community standards.
---
Strictly follow the naming conventions in [rules/named.md](rules/named.md)
Strictly follow the naming conventions in [rules/named.md](../../rules/named.md)

View File

@@ -1043,11 +1043,9 @@ export const useExportAgentLog = () => {
mutationFn: async (searchParams: IAgentLogsRequest) => {
const { data } = await fetchAgentLogsByCanvasId(id as string, {
...searchParams,
page: 1,
page_size: 100000,
});
return data?.data?.sessions ?? [];
return data?.data ?? [];
},
});

View File

@@ -67,6 +67,7 @@ export default {
add: 'Add',
remove: 'Remove',
search: 'Search',
reset: 'Reset',
noDataFound: 'No data found.',
noData: 'No data available',
promptPlaceholder: `Please input or use / to quickly insert variables.`,

View File

@@ -57,6 +57,7 @@ export default {
add: '添加',
remove: '移除',
search: '搜索',
reset: '重置',
noDataFound: '没有找到数据。',
noData: '暂无数据',
bedrockCredentialsHint:

View File

@@ -20,7 +20,6 @@ import {
} from '@/interfaces/database/agent';
import { IReferenceObject } from '@/interfaces/database/chat';
import { formatDate } from '@/utils/date';
import { useQueryClient } from '@tanstack/react-query';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router';
@@ -53,7 +52,6 @@ const AgentLogPage: React.FC = () => {
const { navigateToAgents, navigateToAgent } = useNavigatePage();
const { flowDetail: agentDetail } = useFetchDataOnMount();
const { id: canvasId } = useParams();
const queryClient = useQueryClient();
const init = {
keywords: '',
from_date: getStartOfToday(),
@@ -176,7 +174,7 @@ const AgentLogPage: React.FC = () => {
});
};
const handleSearch = () => {
const handleSearch = (overrides: Partial<typeof searchParams> = {}) => {
setSearchParams((pre) => {
return {
...pre,
@@ -187,16 +185,14 @@ const AgentLogPage: React.FC = () => {
orderby: sortConfig?.orderby || '',
desc: sortConfig?.desc as boolean,
keywords: keywords,
...overrides,
};
});
};
const handleClickSearch = () => {
setPagination({ ...pagination, current: 1 });
handleSearch();
queryClient.invalidateQueries({
queryKey: ['fetchAgentLog'],
});
setPagination((pre) => ({ ...pre, current: 1 }));
handleSearch({ page: 1, keywords });
};
useEffect(() => {
handleSearch();
@@ -232,16 +228,20 @@ const AgentLogPage: React.FC = () => {
to_date: searchParams.to_date,
orderby: searchParams.orderby,
desc: searchParams.desc,
page: pagination.current,
page_size: pagination.pageSize,
});
};
return (
<div className=" text-white">
<div className=" text-text-primary">
<PageHeader>
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink onClick={navigateToAgents}>Agent</BreadcrumbLink>
<BreadcrumbLink onClick={navigateToAgents}>
{t('flow.agent')}
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
@@ -251,21 +251,21 @@ const AgentLogPage: React.FC = () => {
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Log</BreadcrumbPage>
<BreadcrumbPage>{t('flow.log')}</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</PageHeader>
<div className="p-4">
<div className="flex justify-between items-center">
<h1 className="text-2xl font-bold mb-4">Log</h1>
<h1 className="text-2xl font-bold mb-4">{t('flow.log')}</h1>
<div className="flex justify-end space-x-2 mb-4 text-foreground">
<div className="flex items-center space-x-2">
<Button onClick={onExportClick} loading={exportLoading}>
{t('flow.export')}
</Button>
<span>ID/Title</span>
<span>{`${t('flow.id')}/${t('flow.logTitle')}`}</span>
<SearchInput
value={keywords}
onChange={(e) => {
@@ -275,7 +275,7 @@ const AgentLogPage: React.FC = () => {
></SearchInput>
</div>
<div className="flex items-center space-x-2">
<span className="whitespace-nowrap">Latest Date</span>
<span className="whitespace-nowrap">{t('flow.latestDate')}</span>
<DatePickerWithRange
required
selected={currentDate}
@@ -292,14 +292,14 @@ const AgentLogPage: React.FC = () => {
handleClickSearch();
}}
>
Search
{t('common.search')}
</button>
<button
type="button"
className="bg-transparent text-foreground px-4 py-1 rounded border"
onClick={() => handleReset()}
>
Reset
{t('common.reset')}
</button>
</div>
</div>
@@ -374,7 +374,7 @@ const AgentLogPage: React.FC = () => {
colSpan={columns.length}
className="h-24 text-center"
>
No data
{t('common.noData')}
</TableCell>
</TableRow>
)}

View File

@@ -11,6 +11,8 @@ interface ISearchParams {
to_date?: Date;
orderby?: string;
desc?: boolean;
page?: number;
page_size?: number;
}
export const useExportAgentLogToCSV = () => {
@@ -58,9 +60,12 @@ export const useExportAgentLogToCSV = () => {
to_date: searchParams.to_date,
orderby: searchParams.orderby,
desc: searchParams.desc,
page: searchParams.page,
page_size: searchParams.page_size,
});
if (allData.length === 0) {
console.log('No data to export', allData);
message.warning(t('flow.noDataToExport'));
return;
}

View File

@@ -28,6 +28,7 @@ import { cn } from '@/lib/utils';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm, UseFormReturn } from 'react-hook-form';
import { z } from 'zod';
import { NICKNAME_PATTERN } from '../user-setting/profile/constants';
import { BgSvg } from './bg';
import FlipCard3D, { FlipFaceContext } from './card';
import './index.less';
@@ -253,6 +254,9 @@ const Login = () => {
const { login: loginWithChannel, loading: loginWithChannelLoading } =
useLoginWithChannel();
const { t } = useTranslation('translation', { keyPrefix: 'login' });
const { t: tSetting } = useTranslation('translation', {
keyPrefix: 'setting',
});
const [isLoginPage, setIsLoginPage] = useState(true);
const loading =
@@ -287,7 +291,7 @@ const Login = () => {
const FormSchema = z
.object({
nickname: z.string(),
nickname: z.string().optional(),
email: z
.string()
.email()
@@ -296,12 +300,21 @@ const Login = () => {
remember: z.boolean().optional(),
})
.superRefine((data, ctx) => {
if (title === 'register' && !data.nickname) {
if (title !== 'register') return;
if (!data.nickname) {
ctx.addIssue({
path: ['nickname'],
message: 'nicknamePlaceholder',
code: z.ZodIssueCode.custom,
});
return;
}
if (!NICKNAME_PATTERN.test(data.nickname)) {
ctx.addIssue({
path: ['nickname'],
message: tSetting('usernameInvalidCharacters'),
code: z.ZodIssueCode.custom,
});
}
});
type FormValues = z.infer<typeof FormSchema>;

View File

@@ -3,8 +3,10 @@
import AvatarNameDescription from '@/components/avatar-name-description';
import { KnowledgeBaseFormField } from '@/components/knowledge-base-item';
import {
LLMIdFormField,
LlmSettingEnabledSchema,
LlmSettingFieldItems,
LlmSettingSchema,
LlmSettingFieldSchema,
} from '@/components/llm-setting-items/next';
import {
MetadataFilter,
@@ -65,10 +67,7 @@ const SearchSettingFormSchema = z
use_rerank: z.boolean(),
top_k: z.number(),
summary: z.boolean(),
llm_setting: z.object({
...LlmSettingSchema,
parameter: z.string().optional(),
}),
llm_setting: z.object({ ...LlmSettingFieldSchema, ...LLMIdFormField }),
related_search: z.boolean(),
query_mindmap: z.boolean(),
doc_ids: z.array(z.string()),
@@ -84,6 +83,7 @@ const SearchSettingFormSchema = z
.optional(),
...MetadataFilterSchema,
}),
...LlmSettingEnabledSchema,
})
.superRefine((data, ctx) => {
if (data.search_config.use_rerank && !data.search_config.rerank_id) {
@@ -144,12 +144,6 @@ const SearchSetting: React.FC<SearchSettingProps> = ({
top_p: llm_setting?.top_p || 0,
frequency_penalty: llm_setting?.frequency_penalty || 0,
presence_penalty: llm_setting?.presence_penalty || 0,
temperatureEnabled: llm_setting?.temperature ? true : false,
topPEnabled: llm_setting?.top_p ? true : false,
presencePenaltyEnabled: llm_setting?.presence_penalty ? true : false,
frequencyPenaltyEnabled: llm_setting?.frequency_penalty
? true
: false,
},
chat_settingcross_languages: [],
highlight: false,
@@ -166,6 +160,10 @@ const SearchSetting: React.FC<SearchSettingProps> = ({
: undefined,
},
},
temperatureEnabled: llm_setting?.temperature !== undefined,
topPEnabled: llm_setting?.top_p !== undefined,
presencePenaltyEnabled: llm_setting?.presence_penalty !== undefined,
frequencyPenaltyEnabled: llm_setting?.frequency_penalty !== undefined,
});
}, [data, search_config, llm_setting, formMethods, descriptionDefaultValue]);
@@ -259,7 +257,27 @@ const SearchSetting: React.FC<SearchSettingProps> = ({
) => {
try {
setFormSubmitLoading(true);
const { search_config, ...other_formdata } = formData;
const {
search_config,
temperatureEnabled: _temperatureEnabled,
topPEnabled: _topPEnabled,
presencePenaltyEnabled: _presencePenaltyEnabled,
frequencyPenaltyEnabled: _frequencyPenaltyEnabled,
maxTokensEnabled: _maxTokensEnabled,
...other_formdata
} = formData as IUpdateSearchProps & {
tenant_id: string;
temperatureEnabled?: boolean;
topPEnabled?: boolean;
presencePenaltyEnabled?: boolean;
frequencyPenaltyEnabled?: boolean;
maxTokensEnabled?: boolean;
};
void _temperatureEnabled;
void _topPEnabled;
void _presencePenaltyEnabled;
void _frequencyPenaltyEnabled;
void _maxTokensEnabled;
const {
llm_setting,
vector_similarity_weight,