Skip to content

Commit

Permalink
feat: Recurring GCal event dialog (#9506)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dschoordsch authored Mar 13, 2024
1 parent 10c6f69 commit fc4429c
Show file tree
Hide file tree
Showing 10 changed files with 577 additions and 210 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import SendClientSideEvent from '../../utils/SendClientSideEvent'
import StartCheckInMutation from '../../mutations/StartCheckInMutation'
import StartTeamPromptMutation from '../../mutations/StartTeamPromptMutation'
import {PALETTE} from '../../styles/paletteV3'
import {CreateGcalEventInput} from '../../__generated__/StartRetrospectiveMutation.graphql'
import {
CreateGcalEventInput,
RecurrenceSettingsInput
} from '../../__generated__/StartRetrospectiveMutation.graphql'
import sortByTier from '../../utils/sortByTier'
import {MeetingTypeEnum} from '../../__generated__/ActivityDetailsQuery.graphql'
import {RecurrenceSettings} from '../Recurrence/RecurrenceSettings'
import NewMeetingSettingsToggleAnonymity from '../NewMeetingSettingsToggleAnonymity'
import NewMeetingSettingsToggleTeamHealth from '../NewMeetingSettingsToggleTeamHealth'
import NewMeetingSettingsToggleCheckIn from '../NewMeetingSettingsToggleCheckIn'
Expand All @@ -32,7 +34,6 @@ import FlatPrimaryButton from '../FlatPrimaryButton'
import NewMeetingActionsCurrentMeetings from '../NewMeetingActionsCurrentMeetings'
import RaisedButton from '../RaisedButton'
import NewMeetingTeamPicker from '../NewMeetingTeamPicker'
import {ActivityDetailsRecurrenceSettings} from './ActivityDetailsRecurrenceSettings'
import {AdhocTeamMultiSelect, Option} from '../AdhocTeamMultiSelect/AdhocTeamMultiSelect'
import {Select} from '../../ui/Select/Select'
import {SelectTrigger} from '../../ui/Select/SelectTrigger'
Expand Down Expand Up @@ -119,17 +120,13 @@ const ActivityDetailsSidebar = (props: Props) => {
...NewMeetingTeamPicker_teams
...NewMeetingActionsCurrentMeetings_team
...ScheduleMeetingButton_team
...ScheduleDialog_team
}
`,
teamsRef
)

const atmosphere = useAtmosphere()
const [recurrenceSettings, setRecurrenceSettings] = useState<RecurrenceSettings>({
name: '',
rrule: null
})

const templateTeam = teams.find((team) => team.id === selectedTemplate.teamId)

const availableTeams =
Expand Down Expand Up @@ -193,18 +190,23 @@ const ActivityDetailsSidebar = (props: Props) => {
}
: null

const handleStartActivity = (gcalInput?: CreateGcalEventInput) => {
const handleStartActivity = (
gcalInput?: CreateGcalEventInput,
recurrenceSettings?: RecurrenceSettingsInput
) => {
if (submitting) return
submitMutation()
if (type === 'teamPrompt') {
StartTeamPromptMutation(
atmosphere,
{
teamId: selectedTeam.id,
recurrenceSettings: {
rrule: recurrenceSettings.rrule?.toString(),
name: recurrenceSettings.name
},
recurrenceSettings: recurrenceSettings
? {
rrule: recurrenceSettings.rrule?.toString(),
name: recurrenceSettings.name
}
: undefined,
gcalInput
},
{history, onError, onCompleted}
Expand Down Expand Up @@ -238,10 +240,12 @@ const ActivityDetailsSidebar = (props: Props) => {
atmosphere,
{
teamId: selectedTeam.id,
recurrenceSettings: {
rrule: recurrenceSettings.rrule?.toString(),
name: recurrenceSettings.name
},
recurrenceSettings: recurrenceSettings
? {
rrule: recurrenceSettings.rrule?.toString(),
name: recurrenceSettings.name
}
: undefined,
gcalInput
},
{history, onError, onCompleted}
Expand Down Expand Up @@ -299,6 +303,20 @@ const ActivityDetailsSidebar = (props: Props) => {
history.push(`/me/organizations/${selectedTeam.orgId}/billing`)
}

const meetingNamePlaceholder =
type === 'retrospective'
? 'Retro'
: type === 'teamPrompt'
? 'Standup'
: type === 'poker'
? 'Poker'
: type === 'action'
? 'Check-in'
: 'Meeting'
const withRecurrence =
type === 'teamPrompt' ||
(selectedTeam.organization.featureFlags.recurringRetros && type === 'retrospective')

return (
<>
{isOpen && <div className='w-96' />}
Expand Down Expand Up @@ -404,13 +422,6 @@ const ActivityDetailsSidebar = (props: Props) => {
teamRef={selectedTeam}
/>
<NewMeetingSettingsToggleAnonymity settingsRef={selectedTeam.retroSettings} />
{selectedTeam.organization.featureFlags.recurringRetros && (
<ActivityDetailsRecurrenceSettings
onRecurrenceSettingsUpdated={setRecurrenceSettings}
recurrenceSettings={recurrenceSettings}
placeholder='Retro'
/>
)}
</>
)}
{type === 'poker' && (
Expand All @@ -419,13 +430,6 @@ const ActivityDetailsSidebar = (props: Props) => {
{type === 'action' && (
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.actionSettings} />
)}
{type === 'teamPrompt' && (
<ActivityDetailsRecurrenceSettings
onRecurrenceSettingsUpdated={setRecurrenceSettings}
recurrenceSettings={recurrenceSettings}
placeholder='Standup'
/>
)}
</>
)}
</div>
Expand All @@ -449,6 +453,8 @@ const ActivityDetailsSidebar = (props: Props) => {
handleStartActivity={handleStartActivity}
mutationProps={mutationProps}
teamRef={selectedTeam}
placeholder={meetingNamePlaceholder}
withRecurrence={withRecurrence}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import React, {useEffect, useState} from 'react'
import React from 'react'
import graphql from 'babel-plugin-relay/macro'
import SecondaryButton from '../SecondaryButton'
import GcalModal from '../../modules/userDashboard/components/GcalModal/GcalModal'
import {CreateGcalEventInput} from '../../__generated__/StartRetrospectiveMutation.graphql'
import GcalClientManager from '../../utils/GcalClientManager'
import useAtmosphere from '../../hooks/useAtmosphere'
import {
CreateGcalEventInput,
RecurrenceSettingsInput
} from '../../__generated__/StartRetrospectiveMutation.graphql'
import {useFragment} from 'react-relay'
import {ScheduleMeetingButton_team$key} from '~/__generated__/ScheduleMeetingButton_team.graphql'
import {MenuMutationProps} from '../../hooks/useMutationProps'
import useModal from '../../hooks/useModal'
import {ScheduleDialog} from '../ScheduleDialog'
import DialogContainer from '../DialogContainer'

type Props = {
mutationProps: MenuMutationProps
handleStartActivity: (gcalInput?: CreateGcalEventInput) => void
handleStartActivity: (
gcalInput?: CreateGcalEventInput,
recurrenceInput?: RecurrenceSettingsInput
) => void
teamRef: ScheduleMeetingButton_team$key
placeholder: string
withRecurrence?: boolean
}

const ScheduleMeetingButton = (props: Props) => {
const {mutationProps, handleStartActivity, teamRef} = props
const atmosphere = useAtmosphere()
const [hasStartedGcalAuthTeamId, setHasStartedGcalAuthTeamId] = useState<null | string>(null)
const {togglePortal: toggleModal, modalPortal} = useModal({
const {mutationProps, handleStartActivity, teamRef, placeholder, withRecurrence} = props
const {
togglePortal: toggleModal,
closePortal: closeModal,
modalPortal
} = useModal({
id: 'createGcalEventModal'
})
const {submitting} = mutationProps
Expand All @@ -43,32 +52,26 @@ const ScheduleMeetingButton = (props: Props) => {
}
}
}
...GcalModal_team
...ScheduleDialog_team
}
`,
teamRef
)
const {id: teamId, viewerTeamMember} = team
const hasStartedGcalAuth = hasStartedGcalAuthTeamId === teamId
const {viewerTeamMember} = team

const viewerGcalIntegration = viewerTeamMember?.integrations.gcal
const cloudProvider = viewerGcalIntegration?.cloudProvider

const handleClick = () => {
if (viewerGcalIntegration?.auth) {
toggleModal()
} else if (cloudProvider) {
const {clientId, id: providerId} = cloudProvider
GcalClientManager.openOAuth(atmosphere, providerId, clientId, teamId, mutationProps)
setHasStartedGcalAuthTeamId(teamId)
}
toggleModal()
}
const onStartActivity = (
gcalInput?: CreateGcalEventInput,
recurrenceInput?: RecurrenceSettingsInput
) => {
handleStartActivity(gcalInput, recurrenceInput)
closeModal()
}

useEffect(() => {
if (hasStartedGcalAuth && viewerGcalIntegration?.auth) {
toggleModal()
}
}, [hasStartedGcalAuth, viewerGcalIntegration])

if (!cloudProvider) return null
return (
Expand All @@ -77,11 +80,16 @@ const ScheduleMeetingButton = (props: Props) => {
<div className='text-lg'>Schedule</div>
</SecondaryButton>
{modalPortal(
<GcalModal
closeModal={toggleModal}
handleStartActivityWithGcalEvent={handleStartActivity}
teamRef={team}
/>
<DialogContainer className='bg-white'>
<ScheduleDialog
teamRef={team}
placeholder={placeholder}
onStartActivity={onStartActivity}
onCancel={closeModal}
mutationProps={mutationProps}
withRecurrence={withRecurrence}
/>
</DialogContainer>
)}
</>
)
Expand Down
32 changes: 26 additions & 6 deletions packages/client/components/NewMeetingRecurrenceSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import React, {ChangeEvent} from 'react'
import {RRule} from 'rrule'
import {MenuPosition} from '../hooks/useCoords'
import useMenu from '../hooks/useMenu'
import {PortalStatus} from '../hooks/usePortal'
Expand All @@ -14,6 +15,17 @@ interface Props {

export const NewMeetingRecurrenceSettings = (props: Props) => {
const {onRecurrenceSettingsUpdated, recurrenceSettings, placeholder} = props
const {rrule, name} = recurrenceSettings

const onNameChange = (e: ChangeEvent<HTMLInputElement>) => {
const title = e.target.value || placeholder
onRecurrenceSettingsUpdated({...recurrenceSettings, name: title})
}

const onRruleChange = (rrule: RRule | null) => {
onRecurrenceSettingsUpdated({...recurrenceSettings, rrule})
}

const {togglePortal, menuPortal, originRef, portalStatus} = useMenu<HTMLDivElement>(
MenuPosition.LOWER_RIGHT,
{
Expand All @@ -39,11 +51,19 @@ export const NewMeetingRecurrenceSettings = (props: Props) => {
ref={originRef}
/>
{menuPortal(
<RecurrenceSettings
onRecurrenceSettingsUpdated={onRecurrenceSettingsUpdated}
recurrenceSettings={recurrenceSettings}
placeholder={placeholder}
/>
<div className='flex flex-col'>
<input
className='form-input m-2 rounded border border-solid border-slate-500 p-2 font-sans text-base hover:border-slate-600 focus:border-slate-600 focus:outline-none focus:ring-1 focus:ring-slate-600'
type='text'
name='title'
placeholder={placeholder}
value={name}
onChange={onNameChange}
min={1}
max={50}
/>
<RecurrenceSettings title={name} rrule={rrule} onRruleUpdated={onRruleChange} />
</div>
)}
</>
)
Expand Down
Loading

0 comments on commit fc4429c

Please sign in to comment.