Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: only query templates when a user clicks the options menu #9651

Merged
merged 3 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 53 additions & 8 deletions packages/client/components/MeetingOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import SwapHorizIcon from '@mui/icons-material/SwapHoriz'
import React, {useState} from 'react'
import graphql from 'babel-plugin-relay/macro'
import React, {useEffect, useState} from 'react'
import {useLazyLoadQuery} from 'react-relay'
import {MeetingOptionsQuery} from '../__generated__/MeetingOptionsQuery.graphql'
import {Menu} from '../ui/Menu/Menu'
import {MenuItem} from '../ui/Menu/MenuItem'
import {Tooltip} from '../ui/Tooltip/Tooltip'
Expand All @@ -11,13 +14,43 @@ import {OptionsButton} from './TeamPrompt/TeamPromptOptions'
type Props = {
setShowDrawer: (showDrawer: boolean) => void
showDrawer: boolean
hasReflections: boolean
isPhaseComplete: boolean
handleOpenMenu: () => void
meetingId: string
}

const MeetingOptions = (props: Props) => {
const {setShowDrawer, showDrawer, hasReflections, isPhaseComplete} = props
const [isOpen, setIsOpen] = useState(false)
const {setShowDrawer, showDrawer, meetingId, handleOpenMenu} = props
const {viewer} = useLazyLoadQuery<MeetingOptionsQuery>(
graphql`
query MeetingOptionsQuery($meetingId: ID!) {
viewer {
meeting(meetingId: $meetingId) {
... on RetrospectiveMeeting {
id
reflectionGroups {
id
}
localPhase {
... on ReflectPhase {
phaseType
stages {
isComplete
}
}
}
}
}
}
}
`,
{meetingId}
)
const meeting = viewer?.meeting
const [openTooltip, setOpenTooltip] = useState(false)
const hasReflections = !!meeting?.reflectionGroups?.length
const isPhaseComplete = !!meeting?.localPhase?.stages?.every((stage) => stage.isComplete)
const phaseType = meeting?.localPhase?.phaseType

const isDisabled = hasReflections || isPhaseComplete
const tooltipCopy = hasReflections
? 'You can only change the template if no reflections have been added.'
Expand All @@ -30,24 +63,36 @@ const MeetingOptions = (props: Props) => {

const handleMouseEnter = () => {
if (isDisabled) {
setIsOpen(true)
setOpenTooltip(true)
}
}

const handleMouseLeave = () => {
setIsOpen(false)
setOpenTooltip(false)
}

const handleCloseDrawer = () => {
setShowDrawer(false)
}

useEffect(() => {
if (hasReflections && showDrawer) {
handleCloseDrawer()
}
}, [hasReflections])

if (!phaseType || phaseType !== 'reflect') return null
return (
<Menu
onOpenChange={handleOpenMenu}
trigger={
<OptionsButton>
<IconLabel icon='tune' iconLarge />
<div className='text-slate-700'>Options</div>
</OptionsButton>
}
>
<Tooltip open={isOpen}>
<Tooltip open={openTooltip}>
<div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<TooltipTrigger asChild>
<MenuItem onClick={handleClick} isDisabled={isDisabled}>
Expand Down
11 changes: 2 additions & 9 deletions packages/client/components/MeetingTopBar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from '@emotion/styled'
import {Comment} from '@mui/icons-material'
import React, {ReactElement, ReactNode, useState} from 'react'
import React, {ReactElement, ReactNode} from 'react'
import {PALETTE} from '~/styles/paletteV3'
import {meetingAvatarMediaQueries} from '../styles/meeting'
import hasToken from '../utils/hasToken'
Expand Down Expand Up @@ -165,7 +165,6 @@ const MeetingTopBar = (props: Props) => {
} = props
const showButton = isDemoRoute() && !hasToken()
const showDiscussionButton = toggleDrawer && !isRightDrawerOpen
const [showDrawer, setShowDrawer] = useState(false)
const isOptionsVisible = !!meetingId && !isDemoRoute()

return (
Expand All @@ -183,13 +182,7 @@ const MeetingTopBar = (props: Props) => {
</PrimaryActionBlock>
)}
{avatarGroup}
{isOptionsVisible && (
<RetroDrawerRoot
meetingId={meetingId}
setShowDrawer={setShowDrawer}
showDrawer={showDrawer}
/>
)}
{isOptionsVisible && <RetroDrawerRoot meetingId={meetingId} />}
{showDiscussionButton && toggleDrawer && (
<ButtonContainer>
<Badge>
Expand Down
55 changes: 16 additions & 39 deletions packages/client/components/RetroDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,38 @@
import {Close} from '@mui/icons-material'
import graphql from 'babel-plugin-relay/macro'
import React, {useEffect} from 'react'
import React from 'react'
import {PreloadedQuery, usePreloadedQuery} from 'react-relay'
import {RetroDrawerQuery} from '../__generated__/RetroDrawerQuery.graphql'
import useBreakpoint from '../hooks/useBreakpoint'
import {Breakpoint, DiscussionThreadEnum} from '../types/constEnums'
import MeetingOptions from './MeetingOptions'
import ResponsiveDashSidebar from './ResponsiveDashSidebar'
import RetroDrawerTemplateCard from './RetroDrawerTemplateCard'
import {Drawer} from './TeamPrompt/TeamPromptDrawer'

interface Props {
setShowDrawer: (showDrawer: boolean) => void
showDrawer: boolean
queryRef: PreloadedQuery<RetroDrawerQuery>
showDrawer: boolean
setShowDrawer: (showDrawer: boolean) => void
}

const RetroDrawer = (props: Props) => {
const {queryRef, showDrawer, setShowDrawer} = props

const {viewer} = usePreloadedQuery<RetroDrawerQuery>(
graphql`
query RetroDrawerQuery($first: Int!, $type: MeetingTypeEnum!, $meetingId: ID!) {
query RetroDrawerQuery(
$first: Int!
$type: MeetingTypeEnum!
$meetingId: ID!
$isMenuOpen: Boolean!
) {
viewer {
meeting(meetingId: $meetingId) {
... on RetrospectiveMeeting {
id
reflectionGroups {
id
}
localPhase {
... on ReflectPhase {
phaseType
stages {
isComplete
}
}
}
}
id
}
availableTemplates(first: $first, type: $type)
@connection(key: "RetroDrawer_availableTemplates") {
@connection(key: "RetroDrawer_availableTemplates")
@include(if: $isMenuOpen) {
edges {
node {
...RetroDrawerTemplateCard_template
Expand All @@ -53,13 +46,10 @@ const RetroDrawer = (props: Props) => {
queryRef
)

const templates = viewer.availableTemplates.edges
const templates = viewer.availableTemplates?.edges
const meeting = viewer.meeting
const hasReflections = !!(meeting?.reflectionGroups && meeting.reflectionGroups.length > 0)
const phaseType = meeting?.localPhase?.phaseType
const isMobile = !useBreakpoint(Breakpoint.FUZZY_TABLET)
const isDesktop = useBreakpoint(Breakpoint.SIDEBAR_LEFT)
const isPhaseComplete = meeting?.localPhase?.stages?.every((stage) => stage.isComplete) ?? false

const toggleDrawer = () => {
setShowDrawer(!showDrawer)
Expand All @@ -69,21 +59,8 @@ const RetroDrawer = (props: Props) => {
setShowDrawer(false)
}

useEffect(() => {
if (hasReflections && showDrawer) {
handleCloseDrawer()
}
}, [hasReflections])

if (!phaseType || phaseType !== 'reflect') return null
return (
<>
<MeetingOptions
hasReflections={hasReflections}
showDrawer={showDrawer}
isPhaseComplete={isPhaseComplete}
setShowDrawer={setShowDrawer}
/>
<ResponsiveDashSidebar
isOpen={showDrawer}
isRightDrawer
Expand All @@ -106,10 +83,10 @@ const RetroDrawer = (props: Props) => {
<Close />
</div>
</div>
{templates.map((template) => (
{templates?.map((template) => (
<RetroDrawerTemplateCard
key={template.node.id}
meetingId={meeting.id!}
meetingId={meeting!.id}
templateRef={template.node}
handleCloseDrawer={handleCloseDrawer}
/>
Expand Down
35 changes: 25 additions & 10 deletions packages/client/components/RetroDrawerRoot.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
import React, {Suspense} from 'react'
import React, {Suspense, useState} from 'react'
import retroDrawerQuery, {RetroDrawerQuery} from '../__generated__/RetroDrawerQuery.graphql'
import useQueryLoaderNow from '../hooks/useQueryLoaderNow'
import MeetingOptions from './MeetingOptions'
import RetroDrawer from './RetroDrawer'

type Props = {
showDrawer: boolean
setShowDrawer: (showDrawer: boolean) => void
meetingId: string
}

const RetroDrawerRoot = (props: Props) => {
const {showDrawer, setShowDrawer, meetingId} = props
const {meetingId} = props
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [showDrawer, setShowDrawer] = useState(false)

const handleOpenMenu = () => {
setIsMenuOpen(true)
}

const queryRef = useQueryLoaderNow<RetroDrawerQuery>(retroDrawerQuery, {
first: 2000,
type: 'retrospective',
meetingId
meetingId,
isMenuOpen
})
return (
<Suspense fallback={''}>
{queryRef && (
<RetroDrawer showDrawer={showDrawer} setShowDrawer={setShowDrawer} queryRef={queryRef} />
)}
</Suspense>
<>
<MeetingOptions
showDrawer={showDrawer}
setShowDrawer={setShowDrawer}
handleOpenMenu={handleOpenMenu}
meetingId={meetingId}
/>
<Suspense fallback={''}>
{queryRef && (
<RetroDrawer queryRef={queryRef} showDrawer={showDrawer} setShowDrawer={setShowDrawer} />
)}
</Suspense>
</>
)
}

Expand Down
9 changes: 4 additions & 5 deletions packages/client/ui/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import React from 'react'
import {twMerge} from 'tailwind-merge'

interface MenuProps {
trigger: React.ReactNode
interface MenuProps extends DropdownMenu.DropdownMenuProps {
className?: string
children: React.ReactNode
trigger: React.ReactNode
}

export const Menu = React.forwardRef<HTMLDivElement, MenuProps>(
({trigger, className, children}, ref) => {
({trigger, className, children, ...props}, ref) => {
return (
<DropdownMenu.Root>
<DropdownMenu.Root {...props}>
<DropdownMenu.Trigger asChild>{trigger}</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content
Expand Down