Commit 86980b8e authored by Marek Veselý's avatar Marek Veselý
Browse files

Merge branch '213-test-and-fix-draft-behaviour' into 'master'

Resolve "Test and fix draft behaviour"

Closes #213

See merge request inject/frontend!169
parents e60a75f4 a5a8b51f
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -26,8 +26,9 @@ const InstructorEmailForm: FC<InstructorEmailFormProps> = ({
  onFinish,
}) => {
  const formState = useFormState({
    emailThread,
    threadId: threadId || '-1',
    inInstructor: true,
    teamId,
    emailThreadId: threadId,
  })
  const {
    file,
@@ -40,7 +41,7 @@ const InstructorEmailForm: FC<InstructorEmailFormProps> = ({
    setDeactivateMilestone,
    content,
    setContent,
    discard,
    discardDraft,
    storeDraft,
    senderAddress,
    setSenderAddress,
@@ -125,11 +126,11 @@ const InstructorEmailForm: FC<InstructorEmailFormProps> = ({
  )

  const onDiscard = useCallback(() => {
    discard()
    discardDraft()
    onFinish()
  }, [discard, onFinish])
  }, [discardDraft, onFinish])

  const onSaveDraft = useCallback(() => {
  const onSave = useCallback(() => {
    storeDraft()
    onFinish()
  }, [storeDraft, onFinish])
@@ -173,7 +174,6 @@ const InstructorEmailForm: FC<InstructorEmailFormProps> = ({
        setActivateMilestone={setActivateMilestone}
        deactivateMilestone={deactivateMilestone}
        setDeactivateMilestone={setDeactivateMilestone}
        template={template}
      />

      <ContentArea content={content} setContent={setContent} />
@@ -197,8 +197,8 @@ const InstructorEmailForm: FC<InstructorEmailFormProps> = ({
            <Button icon='trash' onClick={onDiscard}>
              Discard
            </Button>
            <Button icon='floppy-disk' onClick={onSaveDraft}>
              Save draft
            <Button icon='floppy-disk' onClick={onSave}>
              Save
            </Button>
            <Button
              type='submit'
+9 −8
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ const TraineeEmailForm: FC<TraineeEmailFormProps> = ({
    setFileName,
    content,
    setContent,
    discard,
    discardDraft,
    storeDraft,
    selectedContacts,
    setSelectedContacts,
@@ -38,8 +38,9 @@ const TraineeEmailForm: FC<TraineeEmailFormProps> = ({
    setSubject,
  } = useFormState({
    teamAddress,
    emailThread,
    threadId: threadId || '-1',
    inInstructor: false,
    teamId,
    emailThreadId: threadId,
  })

  const { onSend } = useThreadSubmission({
@@ -78,11 +79,11 @@ const TraineeEmailForm: FC<TraineeEmailFormProps> = ({
  const traineeList = (emailContacts?.emailContacts || []).filter(notEmpty)

  const onDiscard = useCallback(() => {
    discard()
    discardDraft()
    onFinish()
  }, [discard, onFinish])
  }, [discardDraft, onFinish])

  const onSaveDraft = useCallback(() => {
  const onSave = useCallback(() => {
    storeDraft()
    onFinish()
  }, [storeDraft, onFinish])
@@ -126,8 +127,8 @@ const TraineeEmailForm: FC<TraineeEmailFormProps> = ({
            <Button icon='trash' onClick={onDiscard}>
              Discard
            </Button>
            <Button icon='floppy-disk' onClick={onSaveDraft}>
              Save draft
            <Button icon='floppy-disk' onClick={onSave}>
              Save
            </Button>
            <Button
              type='submit'
+62 −95
Original line number Diff line number Diff line
import { useWriteEmailDraft } from '@inject/graphql/mutations/clientonly/WriteEmailDraft.generated'
import { useReturnLocalEmailDraftLazyQuery } from '@inject/graphql/queries/clientonly/ReturnLocalEmailDraft.generated'
import {
  Dispatch,
  SetStateAction,
  useCallback,
  useEffect,
  useState,
} from 'react'
import { useReturnLocalEmailDraft } from '@inject/graphql/queries/clientonly/ReturnLocalEmailDraft.generated'
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import notEmpty from '@inject/shared/utils/notEmpty'
import { EmailThread } from '@inject/graphql/fragments/EmailThread.generated'
import { EmailTemplate } from '@inject/graphql/fragments/EmailTemplate.generated'
import notEmpty from '@inject/shared/utils/notEmpty'

export interface FormState {
  content: string
@@ -24,7 +17,7 @@ export interface FormState {
  file: File | undefined
  setFile: Dispatch<SetStateAction<File | undefined>>
  storeDraft: () => void
  discard: () => void
  discardDraft: () => void
  senderAddress: string
  setSenderAddress: Dispatch<SetStateAction<string>>
  selectedContacts: string[]
@@ -37,12 +30,14 @@ export interface FormState {

const useFormState = ({
  teamAddress,
  emailThread,
  threadId,
  teamId,
  inInstructor,
  emailThreadId,
}: {
  threadId: string
  teamAddress?: string | null
  emailThread?: EmailThread
  teamId: string
  inInstructor: boolean
  emailThreadId: string | undefined
  teamAddress?: string | undefined
}): FormState => {
  const [senderAddress, setSenderAddress] = useState<string>(teamAddress || '')
  const [content, setContent] = useState<string>('')
@@ -54,24 +49,47 @@ const useFormState = ({
  const [subject, setSubject] = useState<string | undefined>()
  const [template, setTemplate] = useState<EmailTemplate>()

  const { notify } = useNotifyContext()

  const [draftMutate] = useWriteEmailDraft()
  const [getDraft] = useReturnLocalEmailDraftLazyQuery()
  const { data: draftData } = useReturnLocalEmailDraft({
    variables: {
      teamId,
      instructor: inInstructor,
      emailThreadId: emailThreadId || null,
    },
  })

  const { notify } = useNotifyContext()
  useEffect(() => {
    const draft = draftData?.returnLocalEmailDraft

    setContent(draft?.content || '')
    setActivateMilestone(draft?.activateMilestone || '')
    setDeactivateMilestone(draft?.deactivateMilestone || '')
    setFileName(draft?.fileName || undefined)

    if (draft?.emailThreadId) {
      return
    }

    setSenderAddress(draft?.senderAddress || teamAddress || '')
    setSelectedContacts(draft?.selectedContacts?.filter(notEmpty) || [])
    setSubject(draft?.subject || undefined)
  }, [draftData?.returnLocalEmailDraft, teamAddress])

  const storeDraft = useCallback(() => {
  const storeDraft = () => {
    draftMutate({
      variables: {
        email: {
        emailDraft: {
          teamId,
          instructor: inInstructor,
          emailThreadId,
          senderAddress,
            threadId,
            activateMilestone,
          content,
          activateMilestone,
          deactivateMilestone,
          fileName,
          },
          contacts: selectedContacts,
          selectedContacts,
          subject,
        },
      },
@@ -84,57 +102,9 @@ const useFormState = ({
          intent: 'danger',
        })
      })
  }, [
    activateMilestone,
    content,
    deactivateMilestone,
    draftMutate,
    fileName,
    notify,
    selectedContacts,
    senderAddress,
    subject,
    threadId,
  ])

  // effect for setting template data from location state
  useEffect(() => {
    let draft = (emailThread ?? {})?.draft

    const draftLoader = () => {
      if (draft) {
        if (draft.emailDraft) {
          const emailDraft = draft.emailDraft
          setContent(emailDraft.content || '')
          setActivateMilestone(emailDraft.activateMilestone || '')
          setDeactivateMilestone(emailDraft.deactivateMilestone || '')
          setFileName(emailDraft.fileName || undefined)
          setSenderAddress(emailDraft.senderAddress || '')
        }
        if (draft.contacts) {
          setSelectedContacts(draft.contacts.filter(notEmpty))
        }
        if (draft.subject) {
          setSubject(draft.subject || '')
        }
      }
    }

    if (!emailThread) {
      getDraft({
        variables: {
          threadId,
        },
      }).then(({ data }) => {
        draft = (data?.returnLocalEmailDraft ?? {})?.draft
        draftLoader()
      })
    } else {
      draftLoader()
  }
  }, [])

  const discard = useCallback(() => {
  const discardDraft = () => {
    setSenderAddress(teamAddress || '')
    setContent('')
    setActivateMilestone('')
@@ -145,20 +115,19 @@ const useFormState = ({
    setSubject(undefined)
    setTemplate(undefined)

    // discard draft
    draftMutate({
      variables: {
        email: {
        emailDraft: {
            senderAddress,
            threadId,
            activateMilestone,
            content,
            deactivateMilestone,
            fileName,
          },
          contacts: selectedContacts,
          subject,
          teamId,
          instructor: inInstructor,
          emailThreadId,
          senderAddress: teamAddress || '',
          content: '',
          activateMilestone: '',
          deactivateMilestone: '',
          fileName: undefined,
          selectedContacts: [],
          subject: undefined,
        },
      },
    }).catch(err => {
@@ -166,9 +135,8 @@ const useFormState = ({
        intent: 'danger',
      })
    })
  }, [])
  }

  // return //useMemo(() => (
  return {
    content,
    setContent,
@@ -181,7 +149,7 @@ const useFormState = ({
    file,
    setFile,
    storeDraft,
    discard,
    discardDraft,
    senderAddress,
    setSenderAddress,
    selectedContacts,
@@ -191,7 +159,6 @@ const useFormState = ({
    template,
    setTemplate,
  }
  // ), [content, discard, storeDraft, activateMilestone, deactivateMilestone, fileName, file, senderAddress, selectedContacts])
}

export default useFormState
+9 −1
Original line number Diff line number Diff line
@@ -3,10 +3,18 @@ import EmailFormOverlay from '.'

interface TraineeEmailFormOverlayProps {
  teamId: string
  exerciseId: string
}

const TraineeEmailFormOverlay: FC<TraineeEmailFormOverlayProps> = ({
  teamId,
}) => <EmailFormOverlay teamId={teamId} emailForm='trainee' />
  exerciseId,
}) => (
  <EmailFormOverlay
    teamId={teamId}
    emailForm='trainee'
    exerciseId={exerciseId}
  />
)

export default TraineeEmailFormOverlay
+5 −11
Original line number Diff line number Diff line
@@ -23,15 +23,9 @@ const card = css`
export const OPEN_COMPOSE_EVENT_TYPE = 'openCompose'
export const OPEN_REPLY_EVENT_TYPE = 'openReply'

type EmailFormOverlayProps =
  | {
interface EmailFormOverlayProps {
  teamId: string
      emailForm: 'trainee'
      exerciseId?: undefined
    }
  | {
      teamId: string
      emailForm: 'instructor'
  emailForm: 'trainee' | 'instructor'
  exerciseId: string
}

Loading