Fix: The wiki's claim card does not display the title. (#17626)

This commit is contained in:
balibabu
2026-07-31 16:28:55 +08:00
committed by GitHub
parent 4a43a1d620
commit ec7a9797cb
15 changed files with 210 additions and 140 deletions

View File

@@ -9,7 +9,7 @@ import { startCase } from 'lodash';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { FieldLabelKeyMap } from '@/pages/user-setting/compilation-templates/create-next/utils';
import { FieldLabelKeyMap } from '@/pages/user-setting/compilation-templates/create-next/constant';
import { useAddFieldForm } from '../hooks/use-add-field-form';

View File

@@ -1,22 +1,38 @@
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Pencil, Trash2 } from 'lucide-react';
import { useCallback } from 'react';
type FieldCardProps = {
index: number;
title?: string;
field: Record<string, string>;
onEdit: () => void;
onDelete: () => void;
description?: string;
onEdit: (index: number) => void;
onDelete: (index: number) => void;
};
export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
export function FieldCard({
index,
title,
description,
onEdit,
onDelete,
}: FieldCardProps) {
const handleEdit = useCallback(() => {
onEdit(index);
}, [onEdit, index]);
const handleDelete = useCallback(() => {
onDelete(index);
}, [onDelete, index]);
return (
<Card className="border-border-button bg-transparent group">
<CardContent className="p-4 space-y-3">
<div className="flex items-start justify-between gap-2">
<div className="space-y-2 space-x-2 flex-1 min-w-0">
{title && (
<span className="text-sm font-medium text-text-primary">
<span className="line-clamp-1 text-sm font-medium text-text-primary">
{title}
</span>
)}
@@ -26,7 +42,7 @@ export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
type="button"
variant="ghost"
size="icon-xs"
onClick={onEdit}
onClick={handleEdit}
className="text-text-secondary hover:text-text-primary"
>
<Pencil className="size-4" />
@@ -35,7 +51,7 @@ export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
type="button"
variant="ghost"
size="icon-xs"
onClick={onDelete}
onClick={handleDelete}
className="text-text-secondary hover:text-state-error"
>
<Trash2 className="size-4" />
@@ -43,9 +59,9 @@ export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
</div>
</div>
{field.description && (
{description && (
<p className="text-sm text-text-secondary line-clamp-3">
{field.description}
{description}
</p>
)}
</CardContent>

View File

@@ -4,6 +4,7 @@ import { Plus } from 'lucide-react';
import { useFieldArray, useFormContext, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { SectionCardFieldMap } from '../constant';
import { FieldCard } from './field-card';
type SectionFieldGridProps = {
@@ -26,7 +27,7 @@ export function SectionFieldGrid({
name: fieldsPath,
});
const isTypedSection = sectionName === 'entity' || sectionName === 'relation';
const cardFields = SectionCardFieldMap[sectionName];
const currentFields = useWatch({
control: form.control,
@@ -40,10 +41,13 @@ export function SectionFieldGrid({
return (
<FieldCard
key={field.id}
title={isTypedSection ? fieldValue.type : undefined}
field={fieldValue}
onEdit={() => onEditField(index)}
onDelete={() => remove(index)}
index={index}
title={cardFields ? fieldValue[cardFields.title] : undefined}
description={
cardFields ? fieldValue[cardFields.description] : undefined
}
onEdit={onEditField}
onDelete={remove}
/>
);
})}

View File

@@ -16,7 +16,7 @@ import { CompilationTemplateKind } from '@/constants/compilation';
import { TreeTemplateFields } from '@/pages/user-setting/compilation-templates/create-next/components/tree-template-fields';
import { useTemplateKindChange } from '@/pages/user-setting/compilation-templates/create-next/hooks/use-template-kind-change';
import { FormSchemaType } from '@/pages/user-setting/compilation-templates/create-next/schema';
import { SectionTitleKeyMap } from '@/pages/user-setting/compilation-templates/create-next/utils';
import { SectionTitleKeyMap } from '@/pages/user-setting/compilation-templates/create-next/constant';
import { useActiveSectionTab } from '../hooks/use-active-section-tab';
import { useAvailableKindOptions } from '../hooks/use-available-kind-options';

View File

@@ -11,11 +11,9 @@ import { useTranslation } from 'react-i18next';
import { formatKindLabel } from '@/utils/compilation-template-util';
import { DefaultTemplateValues } from '@/pages/user-setting/compilation-templates/create-next/constant';
import { FormSchemaType } from '@/pages/user-setting/compilation-templates/create-next/schema';
import {
DefaultTemplateValues,
generateTemplateName,
} from '@/pages/user-setting/compilation-templates/create-next/utils';
import { generateTemplateName } from '@/pages/user-setting/compilation-templates/create-next/utils';
import { useTemplateAddButton } from '../hooks/use-template-add-button';

View File

@@ -0,0 +1,60 @@
import { FormSchemaType, TemplateSchemaType } from './schema';
export const DefaultFieldKeys = ['type', 'description', 'rule'];
export const FieldKeyOrders = [
DefaultFieldKeys,
['statement', 'subject'],
['definition_excerpt', 'term'],
];
export const DefaultTemplateValues: TemplateSchemaType = {
id: undefined,
name: '',
description: '',
llm_id: '',
kind: '',
config: {
kind: '',
llm_id: '',
global_rules: '',
example: '',
instruction: '',
page_example: '',
use_blueprint: false,
rechunk: false,
rechunk_rules: '',
},
};
export const DefaultValues: FormSchemaType = {
name: '',
description: '',
avatar: '',
templates: [DefaultTemplateValues],
};
export const SectionTitleKeyMap: Record<string, string> = {
entity: 'setting.entitySpecification',
relation: 'setting.relationSpecification',
concept: 'setting.conceptSpecification',
claim: 'setting.claimSpecification',
};
export const SectionCardFieldMap: Record<
string,
{ title: string; description: string }
> = {
entity: { title: 'type', description: 'description' },
relation: { title: 'type', description: 'description' },
claim: { title: 'statement', description: 'subject' },
concept: { title: 'definition_excerpt', description: 'term' },
};
export const SectionPriority = ['entity', 'relation'];
export const FieldLabelKeyMap: Record<string, string> = {
type: 'setting.fieldType',
description: 'setting.fieldDescription',
rule: 'setting.fieldRule',
};

View File

@@ -6,11 +6,8 @@ import { useTranslation } from 'react-i18next';
import { ICompilationTemplateGroup } from '@/interfaces/database/compilation-template';
import { buildFormSchema, FormSchemaType } from '../schema';
import {
DefaultValues,
generateTemplateName,
transformGroupDetailToForm,
} from '../utils';
import { DefaultValues } from '../constant';
import { generateTemplateName, transformGroupDetailToForm } from '../utils';
type UseCompilationTemplateGroupFormOptions = {
detail?: ICompilationTemplateGroup;

View File

@@ -13,8 +13,12 @@ import { ICompilationTemplateConfigRequest } from '@/interfaces/request/compilat
import { CompilationTemplateKind } from '@/constants/compilation';
import { FormSchemaType, TemplateSchemaType } from './schema';
export const DefaultFieldKeys = ['type', 'description', 'rule'];
import {
DefaultFieldKeys,
DefaultTemplateValues,
FieldKeyOrders,
SectionPriority,
} from './constant';
export const splitExampleToBlueprintFields = (
example: string,
@@ -30,12 +34,6 @@ export const splitExampleToBlueprintFields = (
};
};
export const FieldKeyOrders = [
DefaultFieldKeys,
['statement', 'subject'],
['definition_excerpt', 'term'],
];
export const getFieldKeyOrder = (keys: string[]): string[] => {
const sortedKeys = [...keys].sort();
return (
@@ -47,32 +45,6 @@ export const getFieldKeyOrder = (keys: string[]): string[] => {
export const generateTemplateName = () =>
humanId({ separator: ' ', capitalize: true });
export const DefaultTemplateValues: TemplateSchemaType = {
id: undefined,
name: '',
description: '',
llm_id: '',
kind: '',
config: {
kind: '',
llm_id: '',
global_rules: '',
example: '',
instruction: '',
page_example: '',
use_blueprint: false,
rechunk: false,
rechunk_rules: '',
},
};
export const DefaultValues: FormSchemaType = {
name: '',
description: '',
avatar: '',
templates: [DefaultTemplateValues],
};
export const isConfigMetaKey = (key: string) =>
[
'kind',
@@ -317,27 +289,12 @@ export const transformFormToPayload = (values: FormSchemaType) => {
};
};
export const SectionTitleKeyMap: Record<string, string> = {
entity: 'setting.entitySpecification',
relation: 'setting.relationSpecification',
concept: 'setting.conceptSpecification',
claim: 'setting.claimSpecification',
};
export const SectionPriority = ['entity', 'relation'];
export const sortSectionNames = (names: string[]): string[] => {
const priority = SectionPriority.filter((name) => names.includes(name));
const rest = names.filter((name) => !SectionPriority.includes(name));
return [...priority, ...rest];
};
export const FieldLabelKeyMap: Record<string, string> = {
type: 'setting.fieldType',
description: 'setting.fieldDescription',
rule: 'setting.fieldRule',
};
export const getTypeOptionsFromBuiltinSection = (
builtinSection?: ICompilationTemplateSection,
) => {

View File

@@ -9,7 +9,7 @@ import { startCase } from 'lodash';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { FieldLabelKeyMap } from '../utils';
import { FieldLabelKeyMap } from '../constant';
import { useAddFieldForm } from '../hooks/use-add-field-form';

View File

@@ -1,22 +1,38 @@
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Pencil, Trash2 } from 'lucide-react';
import { useCallback } from 'react';
type FieldCardProps = {
index: number;
title?: string;
field: Record<string, string>;
onEdit: () => void;
onDelete: () => void;
description?: string;
onEdit: (index: number) => void;
onDelete: (index: number) => void;
};
export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
export function FieldCard({
index,
title,
description,
onEdit,
onDelete,
}: FieldCardProps) {
const handleEdit = useCallback(() => {
onEdit(index);
}, [onEdit, index]);
const handleDelete = useCallback(() => {
onDelete(index);
}, [onDelete, index]);
return (
<Card className="border-border-button bg-transparent group">
<CardContent className="p-4 space-y-3">
<div className="flex items-start justify-between gap-2">
<div className="space-y-2 space-x-2 flex-1 min-w-0">
{title && (
<span className="text-sm font-medium text-text-primary">
<span className="line-clamp-1 text-sm font-medium text-text-primary">
{title}
</span>
)}
@@ -26,7 +42,7 @@ export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
type="button"
variant="ghost"
size="icon-xs"
onClick={onEdit}
onClick={handleEdit}
className="text-text-secondary hover:text-text-primary"
>
<Pencil className="size-4" />
@@ -35,7 +51,7 @@ export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
type="button"
variant="ghost"
size="icon-xs"
onClick={onDelete}
onClick={handleDelete}
className="text-text-secondary hover:text-state-error"
>
<Trash2 className="size-4" />
@@ -43,9 +59,9 @@ export function FieldCard({ title, field, onEdit, onDelete }: FieldCardProps) {
</div>
</div>
{field.description && (
{description && (
<p className="text-sm text-text-secondary line-clamp-3">
{field.description}
{description}
</p>
)}
</CardContent>

View File

@@ -4,6 +4,7 @@ import { Plus } from 'lucide-react';
import { useFieldArray, useFormContext, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { SectionCardFieldMap } from '../constant';
import { FieldCard } from './field-card';
type SectionFieldGridProps = {
@@ -26,7 +27,7 @@ export function SectionFieldGrid({
name: fieldsPath,
});
const isTypedSection = sectionName === 'entity' || sectionName === 'relation';
const cardFields = SectionCardFieldMap[sectionName];
const currentFields = useWatch({
control: form.control,
@@ -40,10 +41,13 @@ export function SectionFieldGrid({
return (
<FieldCard
key={field.id}
title={isTypedSection ? fieldValue.type : undefined}
field={fieldValue}
onEdit={() => onEditField(index)}
onDelete={() => remove(index)}
index={index}
title={cardFields ? fieldValue[cardFields.title] : undefined}
description={
cardFields ? fieldValue[cardFields.description] : undefined
}
onEdit={onEditField}
onDelete={remove}
/>
);
})}

View File

@@ -15,7 +15,7 @@ import { CompilationTemplateKind } from '@/constants/compilation';
import { TreeTemplateFields } from './tree-template-fields';
import { useTemplateKindChange } from '../hooks/use-template-kind-change';
import { FormSchemaType } from '../schema';
import { SectionTitleKeyMap } from '../utils';
import { SectionTitleKeyMap } from '../constant';
import { useActiveSectionTab } from '../hooks/use-active-section-tab';
import { useAvailableKindOptions } from '../hooks/use-available-kind-options';

View File

@@ -0,0 +1,60 @@
import { FormSchemaType, TemplateSchemaType } from './schema';
export const DefaultFieldKeys = ['type', 'description', 'rule'];
export const FieldKeyOrders = [
DefaultFieldKeys,
['statement', 'subject'],
['definition_excerpt', 'term'],
];
export const DefaultTemplateValues: TemplateSchemaType = {
id: undefined,
name: '',
description: '',
llm_id: '',
kind: '',
config: {
kind: '',
llm_id: '',
global_rules: '',
example: '',
instruction: '',
page_example: '',
use_blueprint: false,
rechunk: false,
rechunk_rules: '',
},
};
export const DefaultValues: FormSchemaType = {
name: '',
description: '',
avatar: '',
templates: [DefaultTemplateValues],
};
export const SectionTitleKeyMap: Record<string, string> = {
entity: 'setting.entitySpecification',
relation: 'setting.relationSpecification',
concept: 'setting.conceptSpecification',
claim: 'setting.claimSpecification',
};
export const SectionCardFieldMap: Record<
string,
{ title: string; description: string }
> = {
entity: { title: 'type', description: 'description' },
relation: { title: 'type', description: 'description' },
claim: { title: 'statement', description: 'subject' },
concept: { title: 'definition_excerpt', description: 'term' },
};
export const SectionPriority = ['entity', 'relation'];
export const FieldLabelKeyMap: Record<string, string> = {
type: 'setting.fieldType',
description: 'setting.fieldDescription',
rule: 'setting.fieldRule',
};

View File

@@ -6,7 +6,8 @@ import { useTranslation } from 'react-i18next';
import { ICompilationTemplateGroup } from '@/interfaces/database/compilation-template';
import { buildFormSchema, FormSchemaType } from '../schema';
import { DefaultValues, transformGroupDetailToForm } from '../utils';
import { DefaultValues } from '../constant';
import { transformGroupDetailToForm } from '../utils';
type UseCompilationTemplateGroupFormOptions = {
detail?: ICompilationTemplateGroup;

View File

@@ -12,8 +12,12 @@ import { ICompilationTemplateConfigRequest } from '@/interfaces/request/compilat
import { CompilationTemplateKind } from '@/constants/compilation';
import { FormSchemaType, TemplateSchemaType } from './schema';
export const DefaultFieldKeys = ['type', 'description', 'rule'];
import {
DefaultFieldKeys,
DefaultTemplateValues,
FieldKeyOrders,
SectionPriority,
} from './constant';
export const splitExampleToBlueprintFields = (
example: string,
@@ -29,12 +33,6 @@ export const splitExampleToBlueprintFields = (
};
};
export const FieldKeyOrders = [
DefaultFieldKeys,
['statement', 'subject'],
['definition_excerpt', 'term'],
];
export const getFieldKeyOrder = (keys: string[]): string[] => {
const sortedKeys = [...keys].sort();
return (
@@ -43,32 +41,6 @@ export const getFieldKeyOrder = (keys: string[]): string[] => {
);
};
export const DefaultTemplateValues: TemplateSchemaType = {
id: undefined,
name: '',
description: '',
llm_id: '',
kind: '',
config: {
kind: '',
llm_id: '',
global_rules: '',
example: '',
instruction: '',
page_example: '',
use_blueprint: false,
rechunk: false,
rechunk_rules: '',
},
};
export const DefaultValues: FormSchemaType = {
name: '',
description: '',
avatar: '',
templates: [DefaultTemplateValues],
};
export const isConfigMetaKey = (key: string) =>
[
'kind',
@@ -314,27 +286,12 @@ export const transformFormToPayload = (values: FormSchemaType) => {
};
};
export const SectionTitleKeyMap: Record<string, string> = {
entity: 'setting.entitySpecification',
relation: 'setting.relationSpecification',
concept: 'setting.conceptSpecification',
claim: 'setting.claimSpecification',
};
export const SectionPriority = ['entity', 'relation'];
export const sortSectionNames = (names: string[]): string[] => {
const priority = SectionPriority.filter((name) => names.includes(name));
const rest = names.filter((name) => !SectionPriority.includes(name));
return [...priority, ...rest];
};
export const FieldLabelKeyMap: Record<string, string> = {
type: 'setting.fieldType',
description: 'setting.fieldDescription',
rule: 'setting.fieldRule',
};
export const getTypeOptionsFromBuiltinSection = (
builtinSection?: ICompilationTemplateSection,
) => {