import { Button, Checkbox, Flex, Grid, Popover, PopoverAnchor, PopoverArrow, PopoverBody, PopoverCloseButton, PopoverContent, PopoverTrigger, Slider, SliderFilledTrack, SliderThumb, SliderTrack, Spacer, useBoolean, useId, } from "@chakra-ui/react"; import { FlagIcon, QuestionMarkCircleIcon } from "@heroicons/react/20/solid"; import { useState } from "react"; import poster from "src/lib/poster"; import useSWRMutation from "swr/mutation"; export const FlaggableElement = (props) => { const [isEditing, setIsEditing] = useBoolean(); const { trigger } = useSWRMutation("/api/v1/text_labels", poster, { onSuccess: () => { setIsEditing.off; }, }); const submitResponse = () => { const label_map: Map = new Map(); TEXT_LABEL_FLAGS.forEach((flag, i) => { if (checkboxValues[i]) { label_map.set(flag.attributeName, sliderValues[i]); } }); trigger({ post_id: props.post_id, label_map: Object.fromEntries(label_map), text: props.text }); }; const [checkboxValues, setCheckboxValues] = useState(new Array(TEXT_LABEL_FLAGS.length).fill(false)); const [sliderValues, setSliderValues] = useState(new Array(TEXT_LABEL_FLAGS.length).fill(1)); const handleCheckboxState = (isChecked, idx) => { setCheckboxValues( checkboxValues.map((val, i) => { return i == idx ? isChecked : val; }) ); }; const handleSliderState = (newVal, idx) => { setSliderValues( sliderValues.map((val, i) => { return i == idx ? newVal : val; }) ); }; return ( {props.children}
{TEXT_LABEL_FLAGS.map((option, i) => ( ))}
); }; function FlagCheckbox(props: { option: textFlagLabels; idx: number; checkboxValues: boolean[]; sliderValues: number[]; checkboxHandler: (newVal: boolean, idx: number) => void; sliderHandler: (newVal: number, idx: number) => void; }): JSX.Element { let AdditionalExplanation = null; if (props.option.additionalExplanation) { AdditionalExplanation = ( ); } const id = useId(); return ( { props.checkboxHandler(e.target.checked, props.idx); }} /> { props.sliderHandler(val / 100, props.idx); }} > ); } interface textFlagLabels { attributeName: string; labelText: string; additionalExplanation?: string; } const TEXT_LABEL_FLAGS: textFlagLabels[] = [ // For the time being this list is configured on the FE. // In the future it may be provided by the API. { attributeName: "fails_task", labelText: "Fails to follow the correct instruction / task", additionalExplanation: "__TODO__", }, { attributeName: "not_customer_assistant_appropriate", labelText: "Inappropriate for customer assistant", additionalExplanation: "__TODO__", }, { attributeName: "contains_sexual_content", labelText: "Contains sexual content", }, { attributeName: "contains_violent_content", labelText: "Contains violent content", }, { attributeName: "encourages_violence", labelText: "Encourages or fails to discourage violence/abuse/terrorism/self-harm", }, { attributeName: "denigrates_a_protected_class", labelText: "Denigrates a protected class", }, { attributeName: "gives_harmful_advice", labelText: "Fails to follow the correct instruction / task", additionalExplanation: "The advice given in the output is harmful or counter-productive. This may be in addition to, but is distinct from the question about encouraging violence/abuse/terrorism/self-harm.", }, { attributeName: "expresses_moral_judgement", labelText: "Expresses moral judgement", }, ];