From 7f78a5fc9b3a29aa59f455823af430fac9803c37 Mon Sep 17 00:00:00 2001 From: Nick O'Ferrall Date: Tue, 16 Apr 2024 18:02:37 +0100 Subject: [PATCH 1/3] refactor meetingOptions query to lazy query --- packages/client/components/MeetingOptions.tsx | 61 ++++++++++++++++--- packages/client/components/MeetingTopBar.tsx | 11 +--- packages/client/components/RetroDrawer.tsx | 43 +++---------- .../client/components/RetroDrawerRoot.tsx | 32 +++++++--- packages/client/ui/Menu/Menu.tsx | 9 ++- 5 files changed, 89 insertions(+), 67 deletions(-) diff --git a/packages/client/components/MeetingOptions.tsx b/packages/client/components/MeetingOptions.tsx index 17fef02c6c3..7d471eba77b 100644 --- a/packages/client/components/MeetingOptions.tsx +++ b/packages/client/components/MeetingOptions.tsx @@ -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' @@ -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( + 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.' @@ -30,16 +63,28 @@ 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 ( @@ -47,7 +92,7 @@ const MeetingOptions = (props: Props) => { } > - +
diff --git a/packages/client/components/MeetingTopBar.tsx b/packages/client/components/MeetingTopBar.tsx index f8768749365..22f8420a66a 100644 --- a/packages/client/components/MeetingTopBar.tsx +++ b/packages/client/components/MeetingTopBar.tsx @@ -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' @@ -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 ( @@ -183,13 +182,7 @@ const MeetingTopBar = (props: Props) => { )} {avatarGroup} - {isOptionsVisible && ( - - )} + {isOptionsVisible && } {showDiscussionButton && toggleDrawer && ( diff --git a/packages/client/components/RetroDrawer.tsx b/packages/client/components/RetroDrawer.tsx index bb877492d7c..31d7bdee218 100644 --- a/packages/client/components/RetroDrawer.tsx +++ b/packages/client/components/RetroDrawer.tsx @@ -1,42 +1,29 @@ 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 + showDrawer: boolean + setShowDrawer: (showDrawer: boolean) => void } const RetroDrawer = (props: Props) => { const {queryRef, showDrawer, setShowDrawer} = props + const {viewer} = usePreloadedQuery( graphql` query RetroDrawerQuery($first: Int!, $type: MeetingTypeEnum!, $meetingId: ID!) { 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") { @@ -53,13 +40,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) @@ -69,21 +53,8 @@ const RetroDrawer = (props: Props) => { setShowDrawer(false) } - useEffect(() => { - if (hasReflections && showDrawer) { - handleCloseDrawer() - } - }, [hasReflections]) - - if (!phaseType || phaseType !== 'reflect') return null return ( <> - { {templates.map((template) => ( diff --git a/packages/client/components/RetroDrawerRoot.tsx b/packages/client/components/RetroDrawerRoot.tsx index cb2698bbbe3..951f8eae49b 100644 --- a/packages/client/components/RetroDrawerRoot.tsx +++ b/packages/client/components/RetroDrawerRoot.tsx @@ -1,27 +1,41 @@ -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, { first: 2000, type: 'retrospective', meetingId }) return ( - - {queryRef && ( - - )} - + <> + + + {queryRef && isMenuOpen && ( + + )} + + ) } diff --git a/packages/client/ui/Menu/Menu.tsx b/packages/client/ui/Menu/Menu.tsx index 47afbbbf35b..9dc63da80d0 100644 --- a/packages/client/ui/Menu/Menu.tsx +++ b/packages/client/ui/Menu/Menu.tsx @@ -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( - ({trigger, className, children}, ref) => { + ({trigger, className, children, ...props}, ref) => { return ( - + {trigger} Date: Tue, 16 Apr 2024 18:16:03 +0100 Subject: [PATCH 2/3] clean up --- packages/client/components/RetroDrawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/components/RetroDrawer.tsx b/packages/client/components/RetroDrawer.tsx index 31d7bdee218..a68a98f0862 100644 --- a/packages/client/components/RetroDrawer.tsx +++ b/packages/client/components/RetroDrawer.tsx @@ -40,7 +40,7 @@ const RetroDrawer = (props: Props) => { queryRef ) - const templates = viewer?.availableTemplates?.edges ?? [] + const templates = viewer.availableTemplates.edges const meeting = viewer.meeting const isMobile = !useBreakpoint(Breakpoint.FUZZY_TABLET) const isDesktop = useBreakpoint(Breakpoint.SIDEBAR_LEFT) From fdf934b24d1a76fb3cae08b158d3df69346daf18 Mon Sep 17 00:00:00 2001 From: Nick O'Ferrall Date: Tue, 30 Apr 2024 16:41:07 +0100 Subject: [PATCH 3/3] add @include isMenuOpen to retro drawer query --- packages/client/components/RetroDrawer.tsx | 14 ++++++++++---- packages/client/components/RetroDrawerRoot.tsx | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/client/components/RetroDrawer.tsx b/packages/client/components/RetroDrawer.tsx index a68a98f0862..19cba982af2 100644 --- a/packages/client/components/RetroDrawer.tsx +++ b/packages/client/components/RetroDrawer.tsx @@ -20,13 +20,19 @@ const RetroDrawer = (props: Props) => { const {viewer} = usePreloadedQuery( graphql` - query RetroDrawerQuery($first: Int!, $type: MeetingTypeEnum!, $meetingId: ID!) { + query RetroDrawerQuery( + $first: Int! + $type: MeetingTypeEnum! + $meetingId: ID! + $isMenuOpen: Boolean! + ) { viewer { meeting(meetingId: $meetingId) { id } availableTemplates(first: $first, type: $type) - @connection(key: "RetroDrawer_availableTemplates") { + @connection(key: "RetroDrawer_availableTemplates") + @include(if: $isMenuOpen) { edges { node { ...RetroDrawerTemplateCard_template @@ -40,7 +46,7 @@ const RetroDrawer = (props: Props) => { queryRef ) - const templates = viewer.availableTemplates.edges + const templates = viewer.availableTemplates?.edges const meeting = viewer.meeting const isMobile = !useBreakpoint(Breakpoint.FUZZY_TABLET) const isDesktop = useBreakpoint(Breakpoint.SIDEBAR_LEFT) @@ -77,7 +83,7 @@ const RetroDrawer = (props: Props) => {
- {templates.map((template) => ( + {templates?.map((template) => ( { const queryRef = useQueryLoaderNow(retroDrawerQuery, { first: 2000, type: 'retrospective', - meetingId + meetingId, + isMenuOpen }) return ( <> @@ -31,7 +32,7 @@ const RetroDrawerRoot = (props: Props) => { meetingId={meetingId} /> - {queryRef && isMenuOpen && ( + {queryRef && ( )}