Improve "Delimiter for text" UX: clearer tooltip + live parsed-delimiter preview (#17385)

## Summary

Improve the UX of the **"Delimiter for text"** field on the dataset
configuration page. The field is a single string with a backtick-based
mini-syntax, but both the tooltip and the surrounding UI failed to
surface what delimiters the backend would actually derive from a given
value — leaving users to discover by trial-and-error that the same
string produces different splits depending on file type (see #7436,
#4704, #9680).
This commit is contained in:
S
2026-07-27 10:51:54 +05:30
committed by GitHub
parent 1571abd98a
commit c48eb70e67
5 changed files with 170 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ import { cn } from '@/lib/utils';
import { forwardRef } from 'react';
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { DelimiterPreview } from './delimiter-preview';
import {
FormControl,
FormField,
@@ -108,6 +109,7 @@ export function ChildrenDelimiterForm() {
data-testid="ds-settings-parser-child-chunk-delimiter-input"
/>
</FormControl>
<DelimiterPreview value={field.value} />
</div>
</div>
<div className="flex pt-1">

View File

@@ -2,6 +2,7 @@ import { cn } from '@/lib/utils';
import { forwardRef } from 'react';
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { DelimiterPreview } from './delimiter-preview';
import {
FormControl,
FormField,
@@ -74,6 +75,7 @@ export function DelimiterFormField() {
<FormControl>
<DelimiterInput {...field}></DelimiterInput>
</FormControl>
<DelimiterPreview value={field.value} />
</div>
</div>
<div className="flex pt-1">

View File

@@ -0,0 +1,66 @@
import { useTranslation } from 'react-i18next';
import { Badge } from './ui/badge';
import { parseDelimitersForDisplay } from '@/utils/delimiter-preview';
interface Props {
/** The current value of the delimiter field. */
value: string | undefined;
}
/**
* Renders a best-effort, informational preview of the delimiters
* derived from `value`. Pure display — does not affect the stored value
* or the chunking behavior. The preview may differ from what the
* backend actually parses (see #17383).
*
* Each delimiter is shown as a small monospace badge; whitespace
* characters (which would otherwise be invisible in the single-line
* input) are rendered with visible Unicode glyphs (`↵` for newline,
* `⇥` for tab, `␣` for space, etc.).
*/
export function DelimiterPreview({ value }: Props) {
const { t } = useTranslation();
const parsed = parseDelimitersForDisplay(value);
if (parsed.length === 0) {
return (
<p
className="pt-1 text-xs italic text-text-secondary"
data-testid="delimiter-preview-empty"
>
{t('knowledgeDetails.delimiterPreviewEmpty', {
defaultValue: 'No delimiters — text will be chunked by size only.',
})}
</p>
);
}
return (
<div
className="flex flex-wrap items-center gap-1 pt-1"
data-testid="delimiter-preview"
>
<span className="text-xs text-text-secondary">
{t('knowledgeDetails.delimiterPreviewLabel', {
defaultValue: 'Splits at:',
})}
</span>
{parsed.map((d, i) => (
<Badge
key={`${d.display}-${i}`}
variant="secondary"
className="font-mono text-xs"
>
{d.display}
</Badge>
))}
<span className="text-xs text-text-secondary">
{t('knowledgeDetails.delimiterPreviewCount', {
count: parsed.length,
defaultValue: '({{count}})',
}).replace('{{count}}', String(parsed.length))}
</span>
</div>
);
}