mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-12 00:40:07 +08:00
website: Support new widget types for labelling (#966)
* website: Support new widget types for labelling Adds proper support for yes/no spam style questions as well as a simple interface for flag style labels. Also cleaned up the Task component to fix some rerender issues. * website: Fix some UI text, adjust yes/no button alignment * website: Remove left over console.log Co-authored-by: notmd <33456881+notmd@users.noreply.github.com> --------- Co-authored-by: notmd <33456881+notmd@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
import { Box, Button, Flex, HStack, Text, useColorModeValue } from "@chakra-ui/react";
|
||||
import { Box, useBoolean, useColorModeValue } from "@chakra-ui/react";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MessageView } from "src/components/Messages";
|
||||
import { LabelInputGroup } from "src/components/Messages/LabelInputGroup";
|
||||
import { MessageTable } from "src/components/Messages/MessageTable";
|
||||
import { LabelInputGroup } from "src/components/Survey/LabelInputGroup";
|
||||
import { TwoColumnsWithCards } from "src/components/Survey/TwoColumnsWithCards";
|
||||
import { TaskSurveyProps } from "src/components/Tasks/Task";
|
||||
import { TaskHeader } from "src/components/Tasks/TaskHeader";
|
||||
import { TaskType } from "src/types/Task";
|
||||
import { LabelTaskType } from "src/types/Tasks";
|
||||
|
||||
const isRequired = (labelName: string, requiredLabels?: string[]) => {
|
||||
return requiredLabels ? requiredLabels.includes(labelName) : false;
|
||||
};
|
||||
|
||||
export const LabelTask = ({
|
||||
task,
|
||||
@@ -13,15 +20,33 @@ export const LabelTask = ({
|
||||
isEditable,
|
||||
onReplyChanged,
|
||||
onValidityChanged,
|
||||
}: TaskSurveyProps<{ text: string; labels: Record<string, number>; message_id: string }>) => {
|
||||
const [sliderValues, setSliderValues] = useState<number[]>(new Array(task.valid_labels.length).fill(null));
|
||||
}: TaskSurveyProps<LabelTaskType, { text: string; labels: Record<string, number>; message_id: string }>) => {
|
||||
const { t } = useTranslation("labelling");
|
||||
const [values, setValues] = useState<number[]>(new Array(task.labels.length).fill(null));
|
||||
const [userInputMade, setUserInputMade] = useBoolean(false);
|
||||
|
||||
// Initial setup to run when the task changes
|
||||
useEffect(() => {
|
||||
console.assert(task.valid_labels.length === sliderValues.length);
|
||||
const labels = Object.fromEntries(task.valid_labels.map((label, i) => [label, sliderValues[i]]));
|
||||
onReplyChanged({ labels, text: task.reply || task.prompt, message_id: task.message_id });
|
||||
onValidityChanged(sliderValues.every((value) => value !== null) ? "VALID" : "INVALID");
|
||||
}, [task, sliderValues, onReplyChanged, onValidityChanged]);
|
||||
setValues(new Array(task.labels.length).fill(null));
|
||||
onValidityChanged(task.labels.some(({ name }) => isRequired(name, task.mandatory_labels)) ? "INVALID" : "DEFAULT");
|
||||
setUserInputMade.off();
|
||||
}, [task, setUserInputMade, onValidityChanged]);
|
||||
|
||||
// Update the reply and validity when the values change
|
||||
useEffect(() => {
|
||||
onReplyChanged({
|
||||
text: "unused?",
|
||||
labels: Object.fromEntries(task.labels.map(({ name }, idx) => [name, values[idx] || 0])),
|
||||
message_id: task.message_id,
|
||||
});
|
||||
onValidityChanged(
|
||||
task.labels.some(({ name }, idx) => values[idx] === null && isRequired(name, task.mandatory_labels))
|
||||
? "INVALID"
|
||||
: userInputMade
|
||||
? "VALID"
|
||||
: "DEFAULT"
|
||||
);
|
||||
}, [task, values, onReplyChanged, userInputMade, onValidityChanged]);
|
||||
|
||||
const cardColor = useColorModeValue("gray.50", "gray.800");
|
||||
const isSpamTask = task.mode === "simple" && task.valid_labels.length === 1 && task.valid_labels[0] === "spam";
|
||||
@@ -31,12 +56,9 @@ export const LabelTask = ({
|
||||
<TwoColumnsWithCards>
|
||||
<>
|
||||
<TaskHeader taskType={taskType} />
|
||||
{task.conversation ? (
|
||||
{task.type !== TaskType.label_initial_prompt ? (
|
||||
<Box mt="4" p={[4, 6]} borderRadius="lg" bg={cardColor}>
|
||||
<MessageTable
|
||||
messages={[...(task.conversation?.messages ?? []), task.reply_message]}
|
||||
highlightLastMessage
|
||||
/>
|
||||
<MessageTable messages={task.conversation.messages} highlightLastMessage />
|
||||
</Box>
|
||||
) : (
|
||||
<Box mt="4">
|
||||
@@ -44,51 +66,22 @@ export const LabelTask = ({
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
{isSpamTask ? (
|
||||
<SpamTaskInput
|
||||
value={sliderValues[0]}
|
||||
onChange={(value) => setSliderValues([value])}
|
||||
isEditable={isEditable}
|
||||
/>
|
||||
) : (
|
||||
<Flex direction="column" alignItems="stretch">
|
||||
<Text>The highlighted message:</Text>
|
||||
<LabelInputGroup labelIDs={task.valid_labels} isEditable={isEditable} onChange={setSliderValues} />
|
||||
</Flex>
|
||||
)}
|
||||
<LabelInputGroup
|
||||
labels={task.labels}
|
||||
values={values}
|
||||
requiredLabels={task.mandatory_labels}
|
||||
isEditable={isEditable}
|
||||
instructions={{
|
||||
yesNoInstruction: t("label_highlighted_yes_no_instruction"),
|
||||
flagInstruction: t("label_highlighted_flag_instruction"),
|
||||
likertInstruction: t("label_highlighted_likert_instruction"),
|
||||
}}
|
||||
onChange={(values) => {
|
||||
setValues(values);
|
||||
setUserInputMade.on();
|
||||
}}
|
||||
/>
|
||||
</TwoColumnsWithCards>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const SpamTaskInput = ({
|
||||
isEditable,
|
||||
value,
|
||||
onChange,
|
||||
}: {
|
||||
isEditable: boolean;
|
||||
value: number;
|
||||
onChange: (number) => void;
|
||||
}) => {
|
||||
return (
|
||||
<HStack>
|
||||
<Text>Is the highlighted message spam?</Text>
|
||||
<Button
|
||||
data-cy="spam-button"
|
||||
isDisabled={!isEditable}
|
||||
colorScheme={value === 1 ? "blue" : undefined}
|
||||
onClick={() => onChange(1)}
|
||||
>
|
||||
Yes
|
||||
</Button>
|
||||
<Button
|
||||
data-cy="not-spam-button"
|
||||
isDisabled={!isEditable}
|
||||
colorScheme={value === 0 ? "blue" : undefined}
|
||||
onClick={() => onChange(0)}
|
||||
>
|
||||
No
|
||||
</Button>
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user