mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-08-21 22:55:55 +00:00
fix(vscode): multi-select question jumps to next after only one answe… (#3079)
* fix(vscode): multi-select question jumps to next after only one answer selected * chore: add changeset --------- Co-authored-by: gaoyuan <gaoyuan@moonshot.ai>
This commit is contained in:
parent
be8e017597
commit
35befdcef2
2 changed files with 75 additions and 14 deletions
5
.changeset/swift-views-scream.md
Normal file
5
.changeset/swift-views-scream.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"kimi-code": patch
|
||||
---
|
||||
|
||||
multi-select question jumps to next after only one answer selected
|
||||
|
|
@ -9,9 +9,12 @@ export function QuestionDialog() {
|
|||
const [selectedIndex, setSelectedIndex] = useState(1);
|
||||
const [questionIndex, setQuestionIndex] = useState(0);
|
||||
const [answers, setAnswers] = useState<Record<string, string>>({});
|
||||
const [multiSelected, setMultiSelected] = useState<string[]>([]);
|
||||
|
||||
const questions = pendingQuestion?.questions ?? [];
|
||||
const question = questions[questionIndex];
|
||||
const isMultiSelect = question?.multi_select === true;
|
||||
const isLastQuestion = questionIndex + 1 >= questions.length;
|
||||
|
||||
useEffect(() => {
|
||||
if (pendingQuestion) {
|
||||
|
|
@ -20,6 +23,7 @@ export function QuestionDialog() {
|
|||
setSelectedIndex(1);
|
||||
setQuestionIndex(0);
|
||||
setAnswers({});
|
||||
setMultiSelected([]);
|
||||
}
|
||||
}, [pendingQuestion?.id]);
|
||||
|
||||
|
|
@ -28,28 +32,43 @@ export function QuestionDialog() {
|
|||
// Step through the questions one by one; submit all answers after the last.
|
||||
const handleAnswer = async (answer: string) => {
|
||||
const nextAnswers = { ...answers, [question.question]: answer };
|
||||
if (questionIndex + 1 < questions.length) {
|
||||
if (!isLastQuestion) {
|
||||
setAnswers(nextAnswers);
|
||||
setQuestionIndex(questionIndex + 1);
|
||||
setShowCustom(false);
|
||||
setCustomInput("");
|
||||
setSelectedIndex(1);
|
||||
setMultiSelected([]);
|
||||
} else {
|
||||
await respondQuestion(nextAnswers);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelect = async (optionLabel: string) => {
|
||||
if (isMultiSelect) {
|
||||
setMultiSelected((prev) =>
|
||||
prev.includes(optionLabel) ? prev.filter((value) => value !== optionLabel) : [...prev, optionLabel],
|
||||
);
|
||||
return;
|
||||
}
|
||||
await handleAnswer(optionLabel);
|
||||
};
|
||||
|
||||
const handleCustomSubmit = async () => {
|
||||
if (!customInput.trim()) return;
|
||||
await handleAnswer(customInput.trim());
|
||||
const value = customInput.trim();
|
||||
if (!value) return;
|
||||
if (isMultiSelect) {
|
||||
setMultiSelected((prev) => (prev.includes(value) ? prev : [...prev, value]));
|
||||
setCustomInput("");
|
||||
setShowCustom(false);
|
||||
return;
|
||||
}
|
||||
await handleAnswer(value);
|
||||
};
|
||||
|
||||
const options = question.options || [];
|
||||
const customIndex = options.length + 1;
|
||||
const customValues = multiSelected.filter((value) => !options.some((option) => option.label === value));
|
||||
|
||||
return (
|
||||
<div className={cn("mb-0.5 border border-blue-200 dark:border-blue-800 rounded-lg overflow-hidden bg-background flex flex-col shrink")}>
|
||||
|
|
@ -61,25 +80,51 @@ export function QuestionDialog() {
|
|||
)}
|
||||
{question.header && <div className="text-[10px] text-muted-foreground uppercase tracking-wide">{question.header}</div>}
|
||||
<div className="text-xs font-semibold text-foreground">{question.question}</div>
|
||||
{isMultiSelect && <div className="text-[10px] text-muted-foreground">Select all that apply</div>}
|
||||
<div className="space-y-1.5">
|
||||
{options.map((option, idx) => (
|
||||
{options.map((option, idx) => {
|
||||
const isChecked = isMultiSelect && multiSelected.includes(option.label);
|
||||
const isHighlighted = selectedIndex === idx + 1;
|
||||
return (
|
||||
<button
|
||||
key={idx}
|
||||
onClick={() => {
|
||||
void handleSelect(option.label);
|
||||
}}
|
||||
onMouseEnter={() => setSelectedIndex(idx + 1)}
|
||||
className={cn(
|
||||
"w-full text-left px-2 py-1 rounded-md text-xs transition-colors",
|
||||
"border cursor-pointer",
|
||||
isChecked
|
||||
? "bg-blue-500/15 border-blue-500"
|
||||
: isHighlighted
|
||||
? "bg-blue-500 text-white border-blue-500"
|
||||
: "bg-background border-border hover:bg-muted/50",
|
||||
)}
|
||||
>
|
||||
<span className={cn("mr-2", isHighlighted && !isChecked ? "text-blue-200" : "text-muted-foreground")}>
|
||||
{isChecked ? "✓" : idx + 1}
|
||||
</span>
|
||||
<span className="font-medium">{option.label}</span>
|
||||
{option.description && (
|
||||
<span className={cn("ml-2", isHighlighted && !isChecked ? "text-blue-200" : "text-muted-foreground")}>- {option.description}</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
{customValues.map((value) => (
|
||||
<button
|
||||
key={idx}
|
||||
key={value}
|
||||
onClick={() => {
|
||||
void handleSelect(option.label);
|
||||
void handleSelect(value);
|
||||
}}
|
||||
onMouseEnter={() => setSelectedIndex(idx + 1)}
|
||||
className={cn(
|
||||
"w-full text-left px-2 py-1 rounded-md text-xs transition-colors",
|
||||
"border border-border cursor-pointer",
|
||||
selectedIndex === idx + 1 ? "bg-blue-500 text-white border-blue-500" : "bg-background hover:bg-muted/50",
|
||||
"border cursor-pointer bg-blue-500/15 border-blue-500",
|
||||
)}
|
||||
>
|
||||
<span className={cn("mr-2", selectedIndex === idx + 1 ? "text-blue-200" : "text-muted-foreground")}>{idx + 1}</span>
|
||||
<span className="font-medium">{option.label}</span>
|
||||
{option.description && (
|
||||
<span className={cn("ml-2", selectedIndex === idx + 1 ? "text-blue-200" : "text-muted-foreground")}>- {option.description}</span>
|
||||
)}
|
||||
<span className="mr-2 text-muted-foreground">✓</span>
|
||||
<span className="font-medium">{value}</span>
|
||||
</button>
|
||||
))}
|
||||
{showCustom ? (
|
||||
|
|
@ -119,6 +164,17 @@ export function QuestionDialog() {
|
|||
<span className="font-medium">Custom response...</span>
|
||||
</button>
|
||||
)}
|
||||
{isMultiSelect && (
|
||||
<button
|
||||
onClick={() => {
|
||||
void handleAnswer(multiSelected.join(", "));
|
||||
}}
|
||||
disabled={multiSelected.length === 0}
|
||||
className="w-full px-2 py-1 rounded-md text-xs bg-blue-500 text-white disabled:opacity-50 cursor-pointer"
|
||||
>
|
||||
{isLastQuestion ? "Submit" : "Next"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue