Commit 80efdc33 authored by Marek Veselý's avatar Marek Veselý
Browse files

resolve cyclic effect dependencies

parent 577f27e5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ const InstructorEmailForm: FC<InstructorEmailFormProps> = ({
        setActivateMilestone={setActivateMilestone}
        deactivateMilestone={deactivateMilestone}
        setDeactivateMilestone={setDeactivateMilestone}
        template={template}
      />

      <ContentArea content={content} setContent={setContent} />
+40 −26
Original line number Diff line number Diff line
@@ -7,12 +7,27 @@ import { memo, useEffect, useState } from 'react'
import notEmpty from '@inject/shared/utils/notEmpty'
import { useGetTeamMilestones } from '@inject/graphql/queries/GetTeamMilestones.generated'
import { MilestoneState } from '@inject/graphql/fragments/MilestoneState.generated'
import { EmailTemplate } from '@inject/graphql/fragments/EmailTemplate.generated'

export interface MilestoneOption {
  milestoneState: MilestoneState
  selected: boolean
}

const milestoneOptionsToString = (
  milestoneOptions: MilestoneOption[],
  reached: boolean
) =>
  milestoneOptions
    .filter(milestoneOption => milestoneOption.selected)
    .filter(milestoneOption =>
      reached
        ? milestoneOption.milestoneState.reached
        : !milestoneOption.milestoneState.reached
    )
    .map(milestoneOption => milestoneOption.milestoneState.milestone.name)
    .join(' ')

const getMilestoneOptionText = (milestoneOption: MilestoneOption) =>
  milestoneOption.milestoneState.reached
    ? `not ${milestoneOption.milestoneState.milestone.name}`
@@ -52,6 +67,7 @@ interface MilestoneSelectorProps {
  deactivateMilestone: string
  setActivateMilestone: React.Dispatch<SetStateAction<string>>
  setDeactivateMilestone: React.Dispatch<SetStateAction<string>>
  template?: EmailTemplate
}

const MilestoneSelector = ({
@@ -60,6 +76,7 @@ const MilestoneSelector = ({
  deactivateMilestone,
  setActivateMilestone,
  setDeactivateMilestone,
  template,
}: MilestoneSelectorProps) => {
  const { data } = useGetTeamMilestones({
    fetchPolicy: 'cache-only',
@@ -92,25 +109,13 @@ const MilestoneSelector = ({
            )),
      }))
    )
  }, [activateMilestone, deactivateMilestone])
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [template])

  const milestoneOptionsToString = (reached: boolean) =>
    milestoneOptions
      .filter(milestoneOption => milestoneOption.selected)
      .filter(milestoneOption =>
        reached
          ? milestoneOption.milestoneState.reached
          : !milestoneOption.milestoneState.reached
      )
      .map(milestoneOption => milestoneOption.milestoneState.milestone.name)
      .join(' ')

  useEffect(() => {
    setActivateMilestone(milestoneOptionsToString(false))
    setDeactivateMilestone(milestoneOptionsToString(true))

    // TODO: not ideal, triggers the preceding useEffect
  }, [milestoneOptions])
  const updateActivateMilestone = (milestoneOptions: MilestoneOption[]) => {
    setActivateMilestone(milestoneOptionsToString(milestoneOptions, false))
    setDeactivateMilestone(milestoneOptionsToString(milestoneOptions, true))
  }

  const handleItemChange = (
    milestoneOption: MilestoneOption,
@@ -118,11 +123,15 @@ const MilestoneSelector = ({
  ) => {
    const index = milestoneOptions.indexOf(milestoneOption)

    setMilestoneOptions(prev => [
    setMilestoneOptions(prev => {
      const newMilestoneOptions = [
        ...prev.slice(0, index),
        { ...prev[index], selected },
        ...prev.slice(index + 1),
    ])
      ]
      updateActivateMilestone(newMilestoneOptions)
      return newMilestoneOptions
    })
  }

  return (
@@ -160,9 +169,14 @@ const MilestoneSelector = ({
      }
      resetOnSelect
      onClear={() => {
        setMilestoneOptions(prev =>
          prev.map(milestoneOption => ({ ...milestoneOption, selected: false }))
        )
        setMilestoneOptions(prev => {
          const newMilestoneOptions = prev.map(milestoneOption => ({
            ...milestoneOption,
            selected: false,
          }))
          updateActivateMilestone(newMilestoneOptions)
          return newMilestoneOptions
        })
      }}
      menuProps={{
        'aria-label': 'milestones',