Commit 7f1cc2dd authored by Patrik Kotúček's avatar Patrik Kotúček Committed by Marek Veselý
Browse files

275-Exercise panel: add link to instructor notes to exercises in Select your exercise

parent bdf1d7c8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import { useTranslationFrontend } from '@inject/locale'
import { dialogBody, maximizedDialog } from '@inject/shared'
import type { FC } from 'react'
import { useState } from 'react'
import { FilePageRoute } from '../../routes/_layout/$exerciseId/file.$fileId'

interface ExerciseSelectorProps {
  buttonProps?: ButtonProps | undefined
@@ -51,6 +52,10 @@ export const ExerciseSelector: FC<ExerciseSelectorProps> = ({
              },
              type: 'selecting',
              isSelected: exercise => isSelected(exercise),
              getFileLink: (exercise, fileId) => ({
                to: FilePageRoute.to,
                params: { exerciseId: exercise.id, fileId },
              }),
              t,
            })}
          />
+5 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ import type { ExerciseSimple } from '@inject/graphql'
import type { FC } from 'react'
import { ExerciseCard } from '.'
import { ExerciseAssignmentRoute } from '../../routes/_protected/_navbar/exercise-panel/exercise.$exerciseId'
import { InstructorFilePageRoute } from '../../routes/_protected/instructor/$exerciseId/file.$fileId'
import { InstructorSelectTeamRoute } from '../../routes/_protected/instructor/$exerciseId/select'
import { ExerciseButtons } from '../ExerciseList/ExerciseButtons'

@@ -28,6 +29,10 @@ export const InstructorExerciseCard: FC<InstructorExerciseCardProps> = ({
          to: ExerciseAssignmentRoute.to,
          params: { exerciseId: exercise.id },
        }}
        getFileLink={fileId => ({
          to: InstructorFilePageRoute.to,
          params: { exerciseId: exercise.id, fileId },
        })}
      />
    }
    sandbox={exercise.technical}
+81 −0
Original line number Diff line number Diff line
import type { Intent } from '@blueprintjs/core'
import { Button, Dialog, DialogBody } from '@blueprintjs/core'
import { GetInstructorNotes, useTypedQuery } from '@inject/graphql'
import { useTranslationFrontend } from '@inject/locale'
import {
  CenteredSpinner,
  dialogBody,
  variableHeightMaximizedDialog,
} from '@inject/shared'
import type { NavigateOptions } from '@tanstack/react-router'
import { useState, type FC } from 'react'
import { AttachmentsRow } from '../../../AttachmentsRow'
import { RenderedContent } from '../../../RenderedContent'

interface NotesButtonProps {
  exerciseId: string
  intent?: Intent
  getFileLink: (fileId: string) => NavigateOptions
}

export const NotesButton: FC<NotesButtonProps> = ({
  exerciseId,
  intent,
  getFileLink,
}) => {
  const [dialogOpen, setDialogOpen] = useState(false)
  const { t } = useTranslationFrontend()

  const [{ data: instructorNotesData, fetching }] = useTypedQuery({
    query: GetInstructorNotes,
    variables: { exerciseId },
  })
  if (fetching || !instructorNotesData?.exerciseId) {
    return <CenteredSpinner />
  }

  return (
    <>
      <Button
        icon='book'
        title={t('instructorNotes.title')}
        active={dialogOpen}
        onClick={() => setDialogOpen(true)}
        intent={intent}
      />
      <Dialog
        isOpen={dialogOpen}
        onClose={() => setDialogOpen(false)}
        title={
          <span
            title={`${t('instructorNotes.title')} ${instructorNotesData.exerciseId.name}`}
          >{`${t('instructorNotes.title')} - ${instructorNotesData.exerciseId.name}`}</span>
        }
        className={variableHeightMaximizedDialog}
      >
        <DialogBody className={dialogBody}>
          {instructorNotesData &&
          instructorNotesData.exerciseId.config.instructorNotes ? (
            <>
              <RenderedContent
                renderedContent={
                  instructorNotesData.exerciseId.config.instructorNotes.rendered
                }
                exerciseId={exerciseId}
              />
              <AttachmentsRow
                attachments={
                  instructorNotesData.exerciseId.config.instructorNotes
                    .attachments
                }
                getFileLink={getFileLink}
              />
            </>
          ) : (
            <p>{t('instructorNotes.notFound')}</p>
          )}
        </DialogBody>
      </Dialog>
    </>
  )
}
+8 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import type { NavigateOptions } from '@tanstack/react-router'
import { useMemo, type FC } from 'react'
import { InfoButton } from './InfoButton'
import { ManagingExerciseButtons } from './ManagingExerciseButtons'
import { NotesButton } from './NotesButton'

const buttonGroup = css`
  .${Classes.BUTTON} {
@@ -17,6 +18,7 @@ const buttonGroup = css`
type ExerciseButtonsProps = {
  isSelected?: boolean
  exercise: ExerciseSimple
  getFileLink: (fileId: string) => NavigateOptions
  large?: boolean
} & (
  | {
@@ -34,6 +36,7 @@ export const ExerciseButtons: FC<ExerciseButtonsProps> = ({
  onSelect,
  assignmentLink,
  large,
  getFileLink,
}) => {
  const intent: Intent | undefined = useMemo(() => {
    if (exercise.onDemand) {
@@ -66,6 +69,11 @@ export const ExerciseButtons: FC<ExerciseButtonsProps> = ({
        />
      )}
      <InfoButton intent={intent} exerciseId={exercise.id} />
      <NotesButton
        intent={intent}
        exerciseId={exercise.id}
        getFileLink={getFileLink}
      />
    </ButtonGroup>
  )
}
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ const hideOnSmallScreen = css`
type ExerciseColumnsProps = {
  isSelected?: (exercise: ExerciseSimple) => boolean
  t: ReturnType<typeof useTranslationFrontend>['t']
  getFileLink: (exercise: ExerciseSimple, fileId: string) => NavigateOptions
} & (
  | {
      type: 'selecting'
@@ -46,6 +47,7 @@ export const getExerciseColumns = ({
  type,
  assignmentLink,
  t,
  getFileLink,
}: ExerciseColumnsProps): Column<ExerciseSimple>[] => [
  {
    id: 'name',
@@ -183,6 +185,7 @@ export const getExerciseColumns = ({
      <ExerciseButtons
        isSelected={isSelected?.(exercise)}
        exercise={exercise}
        getFileLink={fileId => getFileLink(exercise, fileId)}
        {...(type === 'selecting'
          ? { type: 'selecting', onSelect: () => onSelect(exercise) }
          : {
Loading