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: activity library settings mobile #9275

Merged
merged 4 commits into from
Dec 7, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ const ActivityDetails = (props: Props) => {
}`

const isOwner = viewerLowestScope === 'TEAM'
const MOBILE_SETTINGS_HEIGHT = 208

return (
<div className='flex h-full flex-col bg-white'>
<div className='flex grow'>
<div className={clsx(`flex grow pb-[${MOBILE_SETTINGS_HEIGHT}px]`)}>
<div className='mt-4 grow'>
<div className='mb-14 ml-4 flex h-min w-max items-center'>
<div className='mr-4'>
Expand Down Expand Up @@ -140,6 +141,18 @@ const ActivityDetails = (props: Props) => {
</div>
</div>
</div>
<div className='hidden lg:block'>
<ActivityDetailsSidebar
selectedTemplateRef={activity}
teamsRef={teams}
isOpen={!isEditing}
type={activity.type}
preferredTeamId={preferredTeamId}
viewerRef={viewer}
/>
</div>
</div>
<div className={`fixed min-h-[${MOBILE_SETTINGS_HEIGHT}px] bottom-0 w-full lg:hidden`}>
<ActivityDetailsSidebar
selectedTemplateRef={activity}
teamsRef={teams}
Expand Down
250 changes: 140 additions & 110 deletions packages/client/components/ActivityLibrary/ActivityDetailsSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {LockOpen} from '@mui/icons-material'
import graphql from 'babel-plugin-relay/macro'
import clsx from 'clsx'
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import React, {useState, useEffect, useRef} from 'react'
import {useFragment} from 'react-relay'
import StartSprintPokerMutation from '~/mutations/StartSprintPokerMutation'
Expand Down Expand Up @@ -40,6 +42,8 @@ import {SelectGroup} from '../../ui/Select/SelectGroup'
import {SelectItem} from '../../ui/Select/SelectItem'
import OneOnOneTeamStatus from './OneOnOneTeamStatus'
import ScheduleMeetingButton from './ScheduleMeetingButton'
import useBreakpoint from '../../hooks/useBreakpoint'
import {Breakpoint} from '../../types/constEnums'

interface Props {
selectedTemplateRef: ActivityDetailsSidebar_template$key
Expand All @@ -52,6 +56,8 @@ interface Props {

const ActivityDetailsSidebar = (props: Props) => {
const {selectedTemplateRef, teamsRef, type, isOpen, preferredTeamId, viewerRef} = props
const [isMinimized, setIsMinimized] = useState(false)
const isMobile = !useBreakpoint(Breakpoint.INVOICE)
const selectedTemplate = useFragment(
graphql`
fragment ActivityDetailsSidebar_template on MeetingTemplate {
Expand Down Expand Up @@ -288,129 +294,153 @@ const ActivityDetailsSidebar = (props: Props) => {
{isOpen && <div className='w-96' />}
<div
className={clsx(
'fixed right-0 flex h-screen translate-x-0 flex-col border-l border-solid border-slate-300 px-4 pb-9 pt-14 transition-all',
isOpen ? ' w-96' : 'w-0 overflow-hidden opacity-0'
'fixed bottom-0 flex w-full flex-col overflow-hidden border-t border-solid border-slate-300 bg-white px-4 pt-2 lg:right-0 lg:top-0 lg:w-96 lg:border-l lg:pt-14',
isOpen ? 'translate-y-0' : 'translate-y-full lg:translate-x-0 lg:translate-y-0',
isOpen ? 'opacity-100' : 'opacity-0 lg:opacity-100'
)}
>
<div className='mb-6 text-xl font-semibold'>Settings</div>
<div className='flex-grow'>
<div className='flex items-center justify-between pt-2 text-xl font-semibold lg:pt-0'>
Settings
<span
className='hover:cursor-pointer lg:hidden'
onClick={() => setIsMinimized(!isMinimized)}
>
{isMinimized ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</span>
</div>

<div className='flex grow flex-col gap-2'>
{/* TODO: move one-on-one logic to its own component */}
{selectedTemplate.id === 'oneOnOneAction' ? (
<div className='rounded-lg bg-slate-200 p-3'>
<div className='text-gray-700 pb-3 text-lg font-semibold'>Teammate</div>
<AdhocTeamMultiSelect
viewerRef={viewer}
onChange={onUserSelected}
value={selectedUser ? [selectedUser] : []}
multiple={false}
/>
<div
className={clsx(
'transition-max-height duration-300 ease-in-out',
isMinimized
? 'max-h-0 opacity-0 lg:max-h-[100vh] lg:opacity-100'
: 'max-h-[100vh] pb-4 lg:pb-0'
)}
>
<div className='mt-6 flex grow flex-col gap-2'>
{/* TODO: move one-on-one logic to its own component */}
{selectedTemplate.id === 'oneOnOneAction' ? (
<div className='rounded-lg bg-slate-200 p-3'>
<div className='text-gray-700 pb-3 text-lg font-semibold'>Teammate</div>
<AdhocTeamMultiSelect
viewerRef={viewer}
onChange={onUserSelected}
value={selectedUser ? [selectedUser] : []}
multiple={false}
/>

{showOrgPicker && (
<>
<div className='text-gray-700 my-4 text-sm font-semibold'>Organization</div>
<Select
onValueChange={(orgId) => setSelectedOrgId(orgId)}
value={selectedOrgId}
>
<SelectTrigger className='bg-white'>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{viewerOrganizations
.filter((org) =>
mutualOrgsIds.length ? mutualOrgsIds.includes(org.id) : true
)
.map((org) => (
<SelectItem value={org.id} key={org.id}>
{org.name}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</>
)}
</div>
) : (
<NewMeetingTeamPicker
positionOverride={isMobile ? MenuPosition.UPPER_RIGHT : MenuPosition.UPPER_LEFT} // refactor this: https://github.com/ParabolInc/parabol/issues/9274
onSelectTeam={onSelectTeam}
selectedTeamRef={selectedTeam}
teamsRef={availableTeams}
customPortal={teamScopePopover}
allowAddTeam={viewer.featureFlags.adHocTeams}
/>
)}

{showOrgPicker && (
{selectedTeam.tier === 'starter' &&
!viewer.featureFlags.noTemplateLimit &&
!selectedTemplate.isFree ? (
<div className='flex grow flex-col'>
<div className='my-auto text-center'>
Upgrade to the <b>Team Plan</b> to create custom activities unlocking your
team’s ideal workflow.
</div>
<RaisedButton
palette='pink'
className='h-12 w-full text-lg font-semibold text-white focus:outline-none focus:ring-2 focus:ring-offset-2'
onClick={handleUpgrade}
>
Upgrade to Team Plan
</RaisedButton>
</div>
) : (
<>
<div className='text-gray-700 my-4 text-sm font-semibold'>Organization</div>
<Select onValueChange={(orgId) => setSelectedOrgId(orgId)} value={selectedOrgId}>
<SelectTrigger className='bg-white'>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{viewerOrganizations
.filter((org) =>
mutualOrgsIds.length ? mutualOrgsIds.includes(org.id) : true
)
.map((org) => (
<SelectItem value={org.id} key={org.id}>
{org.name}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
{type === 'retrospective' && (
<>
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.retroSettings} />
<NewMeetingSettingsToggleTeamHealth
settingsRef={selectedTeam.retroSettings}
teamRef={selectedTeam}
/>
<NewMeetingSettingsToggleAnonymity settingsRef={selectedTeam.retroSettings} />
</>
)}
{type === 'poker' && (
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.pokerSettings} />
)}
{type === 'action' && (
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.actionSettings} />
)}
{type === 'teamPrompt' && (
<ActivityDetailsRecurrenceSettings
onRecurrenceSettingsUpdated={setRecurrenceSettings}
recurrenceSettings={recurrenceSettings}
/>
)}
</>
)}
</div>
) : (
<NewMeetingTeamPicker
positionOverride={MenuPosition.UPPER_LEFT}
onSelectTeam={onSelectTeam}
selectedTeamRef={selectedTeam}
teamsRef={availableTeams}
customPortal={teamScopePopover}
allowAddTeam={viewer.featureFlags.adHocTeams}
</div>
</div>

<div className='z-10 flex h-fit w-full flex-col gap-2 pb-4'>
{oneOnOneTeamInput && (
<OneOnOneTeamStatus
email={oneOnOneTeamInput.email}
orgId={oneOnOneTeamInput.orgId}
name={(selectedUser?.id ? selectedUser?.label : selectedUser?.email) ?? ''}
/>
)}

{selectedTeam.tier === 'starter' &&
!viewer.featureFlags.noTemplateLimit &&
!selectedTemplate.isFree ? (
<div className='flex grow flex-col'>
<div className='my-auto text-center'>
Upgrade to the <b>Team Plan</b> to create custom activities unlocking your team’s
ideal workflow.
</div>
<RaisedButton
palette='pink'
className='h-12 w-full text-lg font-semibold text-white focus:outline-none focus:ring-2 focus:ring-offset-2'
onClick={handleUpgrade}
>
Upgrade to Team Plan
</RaisedButton>
</div>
) : (
{error && <StyledError>{error.message}</StyledError>}
{selectedTemplate.id !== 'oneOnOneAction' && (
<>
{type === 'retrospective' && (
<>
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.retroSettings} />
<NewMeetingSettingsToggleTeamHealth
settingsRef={selectedTeam.retroSettings}
teamRef={selectedTeam}
/>
<NewMeetingSettingsToggleAnonymity settingsRef={selectedTeam.retroSettings} />
</>
)}
{type === 'poker' && (
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.pokerSettings} />
)}
{type === 'action' && (
<NewMeetingSettingsToggleCheckIn settingsRef={selectedTeam.actionSettings} />
)}
{type === 'teamPrompt' && (
<ActivityDetailsRecurrenceSettings
onRecurrenceSettingsUpdated={setRecurrenceSettings}
recurrenceSettings={recurrenceSettings}
/>
)}
<div className='flex grow flex-col justify-end gap-2'>
{oneOnOneTeamInput && (
<OneOnOneTeamStatus
email={oneOnOneTeamInput.email}
orgId={oneOnOneTeamInput.orgId}
name={(selectedUser?.id ? selectedUser?.label : selectedUser?.email) ?? ''}
/>
)}
{error && <StyledError>{error.message}</StyledError>}
{selectedTemplate.id !== 'oneOnOneAction' && (
<>
<NewMeetingActionsCurrentMeetings team={selectedTeam} />
{/* TODO: scheduling meeting does not work with one-on-one https://github.com/ParabolInc/parabol/issues/8820 */}
<ScheduleMeetingButton
handleStartActivity={handleStartActivity}
mutationProps={mutationProps}
teamRef={selectedTeam}
/>
</>
)}
<FlatPrimaryButton
onClick={() => handleStartActivity()}
waiting={submitting}
className='h-14'
>
<div className='text-lg'>Start Activity</div>
</FlatPrimaryButton>
</div>
<NewMeetingActionsCurrentMeetings team={selectedTeam} />
{/* TODO: scheduling meeting does not work with one-on-one https://github.com/ParabolInc/parabol/issues/8820 */}
<ScheduleMeetingButton
handleStartActivity={handleStartActivity}
mutationProps={mutationProps}
teamRef={selectedTeam}
/>
</>
)}
<FlatPrimaryButton
onClick={() => handleStartActivity()}
waiting={submitting}
className='h-14'
>
<div className='text-lg'>Start Activity</div>
</FlatPrimaryButton>
</div>
</div>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const NewMeetingActionsCurrentMeetings = (props: Props) => {
useSnacksForNewMeetings(activeMeetings as any)
const meetingCount = activeMeetings.length
const label = `${meetingCount} Active ${plural(meetingCount, 'Meeting')}`
if (!meetingCount) return null
return (
<>
<CurrentButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const Wrapper = styled('div')({
})

const StyledDialogContainer = styled(DialogContainer)({
width: 'auto'
width: 'auto',
overflowY: 'scroll'
})

const CloseIcon = styled(Close)({
Expand Down
Loading