mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(web): repair merge tails — todo-row selector and composer handler clone
The #921 selector change and the duplication gate both first ran against this branch after the merge made it MERGEABLE: assembly-surfaces still queried the retired data-sample="todo-row" hook (the composed TodoRow carries ToolRow's data-tool attribute instead), and the redesigned QuestionComposer duplicated the custom-draft onChange/onKeyDown pair across its inline input and optionless textarea. The spec now anchors on data-tool="todo_write", and the composer shares one draftCustom / continueFromCustom handler pair (Enter continues, Shift+Enter stays a newline, IME composition stays inert).
This commit is contained in:
@@ -97,7 +97,7 @@ describe('todo_write assembly (product registrations, no outlet twins)', () => {
|
||||
const view = runtime.renderRoot()
|
||||
|
||||
// Keyed toolview registration took the row (summary derived from args).
|
||||
const row = view.container.querySelector('[data-sample="todo-row"]')
|
||||
const row = view.container.querySelector('[data-tool="todo_write"]')
|
||||
expect(row).not.toBeNull()
|
||||
expect(row!.textContent).toContain('1/3 已完成 · 实现 fixture 样本')
|
||||
|
||||
@@ -117,7 +117,7 @@ describe('todo_write assembly (product registrations, no outlet twins)', () => {
|
||||
await waitFor(() => {
|
||||
expect(view.container.querySelector('[data-testid="todo-panel"]')).toBeNull()
|
||||
})
|
||||
expect(view.container.querySelector('[data-sample="todo-row"]')).not.toBeNull()
|
||||
expect(view.container.querySelector('[data-tool="todo_write"]')).not.toBeNull()
|
||||
await runtime.dispose()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo, useState, type KeyboardEvent } from 'react'
|
||||
import { useMemo, useState, type ChangeEvent, type KeyboardEvent } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {
|
||||
Button, IconCheckOutline14, IconChevronLeftOutline14, IconChevronRightOutline14,
|
||||
@@ -149,6 +149,23 @@ function QuestionFlow({ pending, t, useLocale }: {
|
||||
submitDrafts(drafts)
|
||||
}
|
||||
|
||||
// Shared by the inline custom input and the optionless textarea: typing a
|
||||
// custom draft clears any selection, and Enter continues the flow
|
||||
// (Shift+Enter stays a newline in the textarea; on the single-line input it
|
||||
// is inert either way).
|
||||
const draftCustom = (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
|
||||
const value = event.target.value
|
||||
updateDraft(current => ({
|
||||
...current, selected: [], custom: value, skipped: false,
|
||||
}))
|
||||
}
|
||||
|
||||
const continueFromCustom = (event: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
|
||||
if (event.key !== 'Enter' || event.shiftKey || isComposing(event)) return
|
||||
event.preventDefault()
|
||||
continueFlow()
|
||||
}
|
||||
|
||||
const skipQuestion = (): void => {
|
||||
const nextDrafts = drafts.map((item, itemIndex) => itemIndex === index
|
||||
? { selected: [], custom: '', skipped: true }
|
||||
@@ -247,18 +264,8 @@ function QuestionFlow({ pending, t, useLocale }: {
|
||||
value={draft.custom}
|
||||
disabled={busy !== null}
|
||||
placeholder={t('custom.placeholder')}
|
||||
onChange={(event) => {
|
||||
const value = event.target.value
|
||||
updateDraft(current => ({
|
||||
...current, selected: [], custom: value, skipped: false,
|
||||
}))
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter' && !isComposing(event)) {
|
||||
event.preventDefault()
|
||||
continueFlow()
|
||||
}
|
||||
}}
|
||||
onChange={draftCustom}
|
||||
onKeyDown={continueFromCustom}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
@@ -270,18 +277,8 @@ function QuestionFlow({ pending, t, useLocale }: {
|
||||
disabled={busy !== null}
|
||||
rows={2}
|
||||
placeholder={t('custom.placeholder')}
|
||||
onChange={(event) => {
|
||||
const value = event.target.value
|
||||
updateDraft(current => ({
|
||||
...current, selected: [], custom: value, skipped: false,
|
||||
}))
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter' && !event.shiftKey && !isComposing(event)) {
|
||||
event.preventDefault()
|
||||
continueFlow()
|
||||
}
|
||||
}}
|
||||
onChange={draftCustom}
|
||||
onKeyDown={continueFromCustom}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user