github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/components/manual-grading/GradeComment.tsx (about)

     1  import React, { Dispatch, SetStateAction } from "react"
     2  import { GradingBenchmark, GradingCriterion } from "../../../proto/qf/types_pb"
     3  import { useActions, useAppState } from "../../overmind"
     4  
     5  type GradeCommentProps = {
     6      grade: GradingBenchmark | GradingCriterion,
     7      editing: boolean,
     8      setEditing: Dispatch<SetStateAction<boolean>>
     9  }
    10  
    11  const GradeComment = ({ grade, editing, setEditing }: GradeCommentProps): JSX.Element | null => {
    12      const actions = useActions()
    13      const state = useAppState()
    14  
    15      /* Don't allow grading if user is not a teacher or editing is false */
    16      if (!state.isTeacher || !editing) {
    17          return null
    18      }
    19  
    20      const updateComment = (value: string) => {
    21          setEditing(false)
    22          // Exit early if the value is unchanged
    23          if (value === grade.comment) {
    24              return
    25          }
    26          actions.review.updateComment({ grade: grade, comment: value })
    27      }
    28  
    29      // handleBlur saves the comment when clicking outside the text area.
    30      const handleBlur = (event: React.FocusEvent<HTMLTextAreaElement>) => {
    31          const { value } = event.currentTarget
    32          updateComment(value)
    33      }
    34  
    35      // handleKeyUp saves the comment when pressing Ctrl/Cmd+Enter or Ctrl/Cmd+Q/q.
    36      // It also cancels the edit when pressing Escape.
    37      const handleKeyUp = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
    38          if (event.key === "Escape") {
    39              setEditing(false)
    40              return
    41          }
    42          if ((event.key === "Enter" || event.key === "q" || event.key === "Q") && (event.ctrlKey || event.metaKey)) {
    43              const { value } = event.currentTarget
    44              updateComment(value)
    45          }
    46      }
    47  
    48      return (
    49          <tr>
    50              <th colSpan={3}>
    51                  <textarea rows={20} autoFocus onBlur={handleBlur} onKeyUp={handleKeyUp} defaultValue={grade.comment} className="form-control"></textarea>
    52              </th>
    53          </tr>
    54      )
    55  
    56  }
    57  
    58  export default GradeComment