Skip to content

Commit

Permalink
front: add explanations feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
GiraffeReversed committed Sep 30, 2023
1 parent cce7a76 commit 28a4ba5
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ html.dark .cm-gutters {
padding-left: 0.5rem;
}

.problem button.feedback {
border: 1px solid !important;
}

.problem svg {
width: 20px;
height: 20px;
Expand Down
87 changes: 87 additions & 0 deletions src/editor/ExplanationsFeedback.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { Button, InputGroup, ToggleButton, Collapse, Form } from "react-bootstrap";
import React from "react";
import { HandThumbsUp, HandThumbsDown, ChatLeftDots } from "react-bootstrap-icons";

function sendFeedback(defectCode, opinion, comment, sourceCodeHash, line) {
fetch(`/explanations/feedback`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
defect_code: defectCode,
good: opinion === null ? null : opinion === "good",
comment: comment,
source_code_hash: sourceCodeHash,
line: line,
})
});
}

function handleOpinionClick(opinion, value, setOpinion, defectCode, sourceCodeHash, line) {
if (opinion)
setOpinion(null);
else {
setOpinion(value);
sendFeedback(defectCode, opinion, null, sourceCodeHash, line);
}
}

function handleCommentSubmitClick(comment, defectCode, sourceCodeHash, line) {
sendFeedback(defectCode, null, comment, sourceCodeHash, line);
}


export function ExplanationFeedback({ defectCode, sourceCodeHash, line }) {
let [opinion, setOpinion] = React.useState(null);
let [commentBlockOpen, setCommentBlockOpen] = React.useState(false);
let [comment, setComment] = React.useState("");

return (
<>
<InputGroup size="sm" className="mt-1 mb-2">
<InputGroup.Text id="inputGroup-sizing-sm" className="flex-fill">Was this helpful?</InputGroup.Text>
{
[
{ value: "good", variant: "success", label: <HandThumbsUp /> },
{ value: "bad", variant: "danger", label: <HandThumbsDown /> }
].map((opinion_data, idx) => (
<ToggleButton
className="d-flex align-items-center justify-content-center feedback flex-fill"
key={idx}
type="radio"
variant={"outline-" + opinion_data.variant}
value={opinion_data.value}
checked={opinion == opinion_data.value}
onClick={() => handleOpinionClick(opinion, opinion_data.value, setOpinion, defectCode, sourceCodeHash, line)}
>{opinion_data.label}</ToggleButton>
))
}

<Button
variant="secondary-outline"
className="feedback flex-fill"
onClick={() => setCommentBlockOpen(!commentBlockOpen)}
aria-controls="comment-block"
aria-expanded={commentBlockOpen}
><ChatLeftDots /></Button>
</InputGroup >
<Collapse in={commentBlockOpen}>
<div id="comment-block">
<InputGroup size="sm" className="mb-2">
<Form.Control
className="flex-fill"
aria-label="Comment"
placeholder="e.g. the examples do not help me fix the defect"
as="textarea"
value={comment}
onChange={(e) => setComment(e.target.value)}
/>
<Button
variant="primary"
onClick={() => handleCommentSubmitClick(comment, defectCode, sourceCodeHash, line)}
>Submit</Button>
</InputGroup>
</div>
</Collapse>
</>
);
}
8 changes: 6 additions & 2 deletions src/editor/Problem.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Accordion, ButtonGroup, Card, Button } from "react-bootstrap"
import { Accordion, ButtonGroup, Card, Button } from "react-bootstrap";
import React from "react";
import { useAccordionButton } from 'react-bootstrap/AccordionButton';
import { AccordionContext } from "react-bootstrap";
import { Bullseye, ChevronDown, ChevronUp } from "react-bootstrap-icons";
import { ModeContext } from "../utils/Mode";
import { ProblemClickSettingsContext } from "../utils/ProblemClickSettings";
import { ExplanationFeedback } from "./ExplanationsFeedback";


function CollapseToggle({ eventKey, hasExplanation, onClick }) {
Expand Down Expand Up @@ -40,6 +41,8 @@ export default function Problem({ path, line, enabled_by, source, code, text, ex
let why = explanation?.why;
let examples = explanation?.examples;

let sourceCodeHash = path.replace(/\.py$/, "").replace(/^[a-z]*\//, "");

return (
<Card className={(active ? "active " : "") + "problem my-2"}>
<Card.Header className="p-0 border-bottom-0">
Expand All @@ -62,9 +65,10 @@ export default function Problem({ path, line, enabled_by, source, code, text, ex
<h6>How to solve it?</h6>
<div dangerouslySetInnerHTML={{ __html: examples }} />
<hr className="my-2" /></>}
{(why || examples) && <ExplanationFeedback defectCode={code} sourceCodeHash={sourceCodeHash} line={line} />}
<p className="text-muted tiny-text mb-0">
<span className="fw-bold">Debug</span> {source} {line} {code}
<span className="text-break"> {path.replace(/\.py$/, "").replace(/^[a-z]*\//, "")}</span>
<span className="text-break"> {sourceCodeHash}</span>
</p>
</Card.Body>
</Accordion.Collapse>
Expand Down

0 comments on commit 28a4ba5

Please sign in to comment.