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: Refactor active meeting dropdown to get rid of some edge case bugs #9658

Merged
merged 2 commits into from
May 2, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 11 additions & 20 deletions packages/client/components/NewMeetingActionsCurrentMeetings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import graphql from 'babel-plugin-relay/macro'
import React from 'react'
import {useFragment} from 'react-relay'
import {NewMeetingActionsCurrentMeetings_team$key} from '~/__generated__/NewMeetingActionsCurrentMeetings_team.graphql'
import {MenuPosition} from '~/hooks/useCoords'
import useMenu from '~/hooks/useMenu'
import useSnacksForNewMeetings from '~/hooks/useSnacksForNewMeetings'
import {PALETTE} from '~/styles/paletteV3'
import plural from '~/utils/plural'
import {Menu} from '../ui/Menu/Menu'
import FlatButton from './FlatButton'
import SelectMeetingDropdown from './SelectMeetingDropdown'

Expand Down Expand Up @@ -43,30 +42,22 @@ const NewMeetingActionsCurrentMeetings = (props: Props) => {
`,
teamRef
)
const {togglePortal, originRef, menuPortal, menuProps} = useMenu<HTMLButtonElement>(
MenuPosition.LOWER_RIGHT,
{
isDropdown: true
}
)
const {activeMeetings} = team
useSnacksForNewMeetings(activeMeetings as any)
const meetingCount = activeMeetings.length
const label = `${meetingCount} Active ${plural(meetingCount, 'Meeting')}`
if (!meetingCount) return null
return (
<>
<CurrentButton
onClick={togglePortal}
ref={originRef}
hasMeetings={meetingCount > 0}
size={'large'}
>
<ForumIcon />
{label}
</CurrentButton>
{menuPortal(<SelectMeetingDropdown menuProps={menuProps} meetings={activeMeetings!} />)}
</>
<Menu
trigger={
<CurrentButton hasMeetings={meetingCount > 0} size={'large'}>
<ForumIcon />
{label}
</CurrentButton>
}
>
<SelectMeetingDropdown meetings={activeMeetings!} />
</Menu>
)
}

Expand Down
43 changes: 10 additions & 33 deletions packages/client/components/SelectMeetingDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
import styled from '@emotion/styled'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import graphql from 'babel-plugin-relay/macro'
import React from 'react'
import {useFragment} from 'react-relay'
import {SelectMeetingDropdown_meetings$key} from '~/__generated__/SelectMeetingDropdown_meetings.graphql'
import useRouter from '~/hooks/useRouter'
import {PALETTE} from '~/styles/paletteV3'
import plural from '~/utils/plural'
import {MenuProps} from '../hooks/useMenu'
import Menu from './Menu'
import MenuItem from './MenuItem'
import SelectMeetingDropdownItem from './SelectMeetingDropdownItem'

interface Props {
menuProps: MenuProps
meetings: SelectMeetingDropdown_meetings$key
}

const HeaderLabel = styled('div')({
color: PALETTE.SLATE_600,
fontSize: 12,
fontWeight: 600,
lineHeight: '16px',
padding: '2px 16px 8px',
userSelect: 'none'
})

const SelectMeetingDropdown = (props: Props) => {
const {meetings: meetingsRef, menuProps} = props
const {meetings: meetingsRef} = props
const meetings = useFragment(
graphql`
fragment SelectMeetingDropdown_meetings on NewMeeting @relay(plural: true) {
Expand All @@ -36,25 +21,17 @@ const SelectMeetingDropdown = (props: Props) => {
`,
meetingsRef
)
const {history} = useRouter()
const meetingCount = meetings.length
const label = `${meetingCount} Active ${plural(meetingCount, 'Meeting')}`
return (
<Menu ariaLabel={'Select the Meeting to enter'} {...menuProps}>
<HeaderLabel>{label}</HeaderLabel>
{meetings.map((meeting) => {
const handleClick = () => {
history.push(`/meet/${meeting.id}`)
}
return (
<MenuItem
key={meeting.id}
label={<SelectMeetingDropdownItem meeting={meeting} />}
onClick={handleClick}
/>
)
})}
</Menu>
<>
<DropdownMenu.Label className='select-none px-4 py-2 text-xs font-semibold text-slate-600'>
{label}
</DropdownMenu.Label>
{meetings.map((meeting) => (
<SelectMeetingDropdownItem key={meeting.id} meeting={meeting} />
))}
</>
)
}

Expand Down
73 changes: 14 additions & 59 deletions packages/client/components/SelectMeetingDropdownItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import styled from '@emotion/styled'
import {
ArrowForward as ArrowForwardIcon,
ChangeHistory,
Expand All @@ -11,53 +10,9 @@ import React from 'react'
import {useFragment} from 'react-relay'
import {SelectMeetingDropdownItem_meeting$key} from '~/__generated__/SelectMeetingDropdownItem_meeting.graphql'
import useRouter from '~/hooks/useRouter'
import {PALETTE} from '~/styles/paletteV3'
import getMeetingPhase from '~/utils/getMeetingPhase'
import {meetingTypeToIcon, phaseLabelLookup} from '~/utils/meetings/lookups'

const Wrapper = styled('div')({
alignItems: 'center',
display: 'flex',
width: '100%'
})

const MeetingIcon = styled('div')({
color: PALETTE.SLATE_600,
height: 24,
width: 24,
margin: 16
})

const MeetingSVG = styled('div')({
padding: 16
})

const MeetingInfo = styled('div')({
display: 'flex',
flexDirection: 'column'
})

const Title = styled('div')({
color: PALETTE.SLATE_700,
fontSize: 16,
lineHeight: '24px',
fontWeight: 600
})

const Subtitle = styled('div')({
color: PALETTE.SLATE_600,
fontSize: 12
})

const Action = styled('div')({
flex: 1,
display: 'flex',
justifyContent: 'end',
alignItems: 'center',
height: 24,
marginRight: 16,
width: 24
})
import {MenuItem} from '../ui/Menu/MenuItem'

interface Props {
meeting: SelectMeetingDropdownItem_meeting$key
Expand Down Expand Up @@ -105,32 +60,32 @@ const SelectMeetingDropdownItem = (props: Props) => {
const meetingPhaseLabel = (meetingPhase && phaseLabelLookup[meetingPhase.phaseType]) || 'Complete'

return (
<Wrapper onClick={gotoMeeting}>
<MenuItem onClick={gotoMeeting}>
{typeof IconOrSVG === 'string' ? (
<MeetingIcon>
<div className='size-6 m-2 text-slate-600'>
{
{
group_work: <GroupWork />,
change_history: <ChangeHistory />,
history: <History />
}[IconOrSVG]
}
</MeetingIcon>
</div>
) : (
<MeetingSVG>
<div className='p-2'>
<IconOrSVG />
</MeetingSVG>
</div>
)}
<MeetingInfo>
<Title>{name}</Title>
<Subtitle>
<div className='flex flex-col px-2'>
<div className='text-base font-semibold text-slate-700'>{name}</div>
<div className='text-xs text-slate-600'>
{meetingPhaseLabel} • {teamName}
</Subtitle>
</MeetingInfo>
<Action>
</div>
</div>
<div className='size-6 flex flex-grow items-center justify-end'>
<ArrowForwardIcon />
</Action>
</Wrapper>
</div>
</MenuItem>
)
}

Expand Down
Loading