diff --git a/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx b/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx index 51b5cfbf60f..7170bb22b03 100644 --- a/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx +++ b/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx @@ -46,7 +46,7 @@ const ActivityCardFavorite = (props: Props) => {
diff --git a/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx b/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx index 0adf77aab6b..c867489d298 100644 --- a/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx +++ b/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx @@ -1,7 +1,7 @@ import {ContentCopy} from '@mui/icons-material' import graphql from 'babel-plugin-relay/macro' import clsx from 'clsx' -import React, {useCallback, useEffect} from 'react' +import React, {useCallback, useEffect, useState} from 'react' import {useFragment} from 'react-relay' import {useHistory} from 'react-router' import {MeetingTypeEnum} from '~/__generated__/ActivityDetailsQuery.graphql' @@ -175,13 +175,7 @@ export const TemplateDetails = (props: Props) => { removeTemplateMutation(atmosphere, {templateId: activityId}, mutationArgs) }, [activityId, submitting, submitMutation, onError, onCompleted]) - const { - togglePortal: toggleTeamPickerPortal, - modalPortal: teamPickerModalPortal, - closePortal: closeTeamPickerPortal - } = useModal({ - id: 'templateTeamPickerModal' - }) + const [teamPickerOpen, setTeamPickerOpen] = useState(false) const { openPortal: openPokerTemplateScaleDetailsPortal, @@ -250,7 +244,7 @@ export const TemplateDetails = (props: Props) => { />
- + setTeamPickerOpen(true)} />
)} @@ -270,7 +264,7 @@ export const TemplateDetails = (props: Props) => { setTeamPickerOpen(true)} >
Clone & Edit
@@ -323,16 +317,17 @@ export const TemplateDetails = (props: Props) => { )} - {teamPickerModalPortal( - - )} + { + setTeamPickerOpen(false) + }} + /> {type === 'poker' && editingScaleId && diff --git a/packages/client/components/ActivityLibrary/ActivityDetailsSidebar.tsx b/packages/client/components/ActivityLibrary/ActivityDetailsSidebar.tsx index a0f2a00b16c..3d688e42d93 100644 --- a/packages/client/components/ActivityLibrary/ActivityDetailsSidebar.tsx +++ b/packages/client/components/ActivityLibrary/ActivityDetailsSidebar.tsx @@ -1,4 +1,3 @@ -import {LockOpen} from '@mui/icons-material' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp' import graphql from 'babel-plugin-relay/macro' @@ -17,14 +16,10 @@ import { RecurrenceSettingsInput } from '../../__generated__/StartRetrospectiveMutation.graphql' import useAtmosphere from '../../hooks/useAtmosphere' -import useBreakpoint from '../../hooks/useBreakpoint' -import {MenuPosition} from '../../hooks/useCoords' import useMutationProps from '../../hooks/useMutationProps' import SelectTemplateMutation from '../../mutations/SelectTemplateMutation' import StartCheckInMutation from '../../mutations/StartCheckInMutation' import StartTeamPromptMutation from '../../mutations/StartTeamPromptMutation' -import {PALETTE} from '../../styles/paletteV3' -import {Breakpoint} from '../../types/constEnums' import sortByTier from '../../utils/sortByTier' import FlatPrimaryButton from '../FlatPrimaryButton' import NewMeetingActionsCurrentMeetings from '../NewMeetingActionsCurrentMeetings' @@ -45,7 +40,6 @@ interface Props { const ActivityDetailsSidebar = (props: Props) => { const {selectedTemplateRef, teamsRef, type, preferredTeamId} = props const [isMinimized, setIsMinimized] = useState(false) - const isMobile = !useBreakpoint(Breakpoint.INVOICE) const selectedTemplate = useFragment( graphql` fragment ActivityDetailsSidebar_template on MeetingTemplate { @@ -67,9 +61,6 @@ const ActivityDetailsSidebar = (props: Props) => { name tier orgId - organization { - name - } retroSettings: meetingSettings(meetingType: retrospective) { ...NewMeetingSettingsToggleCheckIn_settings ...NewMeetingSettingsToggleTeamHealth_settings @@ -188,36 +179,17 @@ const ActivityDetailsSidebar = (props: Props) => { } } - const handleShareToOrg = () => { - selectedTemplate && - UpdateReflectTemplateScopeMutation( - atmosphere, - {scope: 'ORGANIZATION', templateId: selectedTemplate.id}, - {onError, onCompleted} - ) - } - - const teamScopePopover = templateTeam && selectedTemplate.scope === 'TEAM' && ( -
-
- This custom activity is private to the {templateTeam.name} team. -
-
-
- As a member of the team you can share this activity with other teams at the{' '} - {templateTeam.organization.name} organization so that they can also use the activity. -
- -
- ) + : undefined const meetingNamePlaceholder = type === 'retrospective' @@ -255,11 +227,10 @@ const ActivityDetailsSidebar = (props: Props) => { >
{type === 'retrospective' && ( <> diff --git a/packages/client/components/ActivityLibrary/TeamPickerModal.tsx b/packages/client/components/ActivityLibrary/TeamPickerModal.tsx index 07ab1ba8d2c..9f9a3083622 100644 --- a/packages/client/components/ActivityLibrary/TeamPickerModal.tsx +++ b/packages/client/components/ActivityLibrary/TeamPickerModal.tsx @@ -9,10 +9,11 @@ import {TeamPickerModal_teams$key} from '~/__generated__/TeamPickerModal_teams.g import {MeetingTypeEnum} from '~/__generated__/TemplateDetails_activity.graphql' import {AddPokerTemplateMutation$data} from '../../__generated__/AddPokerTemplateMutation.graphql' import useAtmosphere from '../../hooks/useAtmosphere' -import {MenuPosition} from '../../hooks/useCoords' import useMutationProps from '../../hooks/useMutationProps' import AddPokerTemplateMutation from '../../mutations/AddPokerTemplateMutation' import AddReflectTemplateMutation from '../../mutations/AddReflectTemplateMutation' +import {Dialog} from '../../ui/Dialog/Dialog' +import {DialogContent} from '../../ui/Dialog/DialogContent' import SendClientSideEvent from '../../utils/SendClientSideEvent' import sortByTier from '../../utils/sortByTier' import NewMeetingTeamPicker from '../NewMeetingTeamPicker' @@ -23,14 +24,15 @@ const ACTION_BUTTON_CLASSES = interface Props { preferredTeamId: string | null teamsRef: TeamPickerModal_teams$key - closePortal: () => void category: string parentTemplateId: string type: MeetingTypeEnum + isOpen: boolean + closeModal: () => void } const TeamPickerModal = (props: Props) => { - const {teamsRef, closePortal, category, parentTemplateId, type, preferredTeamId} = props + const {teamsRef, category, parentTemplateId, type, preferredTeamId, isOpen, closeModal} = props const teams = useFragment( graphql` fragment TeamPickerModal_teams on Team @relay(plural: true) { @@ -71,7 +73,7 @@ const TeamPickerModal = (props: Props) => { { onError, onCompleted: (res: AddReflectTemplateMutation$data) => { - closePortal() + closeModal() const templateId = res.addReflectTemplate?.reflectTemplate?.id if (templateId) { history.push(`/activity-library/details/${templateId}`, { @@ -91,7 +93,7 @@ const TeamPickerModal = (props: Props) => { { onError, onCompleted: (res: AddPokerTemplateMutation$data) => { - closePortal() + closeModal() const templateId = res.addPokerTemplate?.pokerTemplate?.id if (templateId) { history.push(`/activity-library/details/${templateId}`, { @@ -115,63 +117,64 @@ const TeamPickerModal = (props: Props) => { } return ( -
-
-
- Select the team to manage this cloned template -
- { - const newTeam = teams.find((team) => team.id === teamId) - newTeam && setSelectedTeam(newTeam) - }} - selectedTeamRef={selectedTeam} - teamsRef={teams} - /> - {selectedTeam.tier === 'starter' && ( + + +
- This team is on the Starter plan. Upgrade to clone and edit templates on - this team. + Select the team to manage this cloned template
- )} - {error?.message &&
{error.message}
} -
- - {selectedTeam.tier === 'starter' ? ( - - ) : ( + { + const newTeam = teams.find((team) => team.id === teamId) + newTeam && setSelectedTeam(newTeam) + }} + selectedTeamRef={selectedTeam} + teamsRef={teams} + /> + {selectedTeam.tier === 'starter' && ( +
+ This team is on the Starter plan. Upgrade to clone and edit templates on + this team. +
+ )} + {error?.message &&
{error.message}
} +
- )} + {selectedTeam.tier === 'starter' ? ( + + ) : ( + + )} +
-
-
+ + ) } diff --git a/packages/client/components/DropdownToggleInner.tsx b/packages/client/components/DropdownToggleInner.tsx deleted file mode 100644 index 673493093eb..00000000000 --- a/packages/client/components/DropdownToggleInner.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import styled from '@emotion/styled' -import React, {forwardRef} from 'react' -import {PALETTE} from '~/styles/paletteV3' - -const Container = styled('div')({ - alignItems: 'center', - display: 'flex', - flex: 1, - minWidth: 0 -}) - -const IconContainer = styled('div')({ - marginRight: 16 -}) - -const MenuToggleLabelContainer = styled('div')({ - overflow: 'hidden' -}) - -const MenuToggleLabel = styled('div')({ - flex: 1, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - fontSize: 20, - fontWeight: 600, - color: PALETTE.SLATE_900 -}) - -const MenuToggleTitle = styled('div')({ - fontSize: 14, - lineHeight: '16px', - fontWeight: 400, - color: PALETTE.SLATE_900 -}) - -interface Props { - label: string - icon?: React.ReactElement - title?: string -} -const DropdownToggleInner = forwardRef((props: Props, ref: any) => { - const {icon, label, title} = props - return ( - - {icon && {icon}} - - {title && {title}} - {label} - - - ) -}) - -export default DropdownToggleInner diff --git a/packages/client/components/DropdownToggleV2.tsx b/packages/client/components/DropdownToggleV2.tsx deleted file mode 100644 index b7111cd7384..00000000000 --- a/packages/client/components/DropdownToggleV2.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import styled from '@emotion/styled' -import {ExpandMore as ExpandMoreIcon, KeyboardArrowRight} from '@mui/icons-material' -import React, {ReactNode, Ref, forwardRef} from 'react' -import useMenu from '../hooks/useMenu' -import {PALETTE} from '../styles/paletteV3' - -const DropdownIcon = styled('div')<{opened: boolean | undefined}>(({opened}) => ({ - color: PALETTE.SLATE_600, - height: 36, - width: 36, - svg: { - fontSize: 36 - }, - alignSelf: 'center', - transform: opened ? 'rotateX(180deg)' : 'none', - transition: 'transform 0.2s' -})) - -const DropdownBlock = styled('div')<{disabled: boolean | undefined}>(({disabled}) => ({ - background: PALETTE.SLATE_200, - borderRadius: '8px', - cursor: disabled ? 'not-allowed' : 'pointer', - display: 'flex', - fontSize: 14, - lineHeight: '24px', - fontWeight: 600, - userSelect: 'none', - width: '100%', - ':hover': { - backgroundColor: PALETTE.SLATE_300 - }, - padding: 16 -})) - -interface Props { - className?: string - disabled?: boolean - icon?: string - onClick: ReturnType['togglePortal'] - onMouseEnter?: () => void - children: ReactNode - opened?: boolean -} - -const DropdownToggleV2 = forwardRef((props: Props, ref: Ref) => { - const {className, children, icon, onClick, onMouseEnter, disabled, opened} = props - return ( - - {children} - {!disabled && ( - - {icon ? : } - - )} - - ) -}) - -export default DropdownToggleV2 diff --git a/packages/client/components/NewMeetingDropdown.tsx b/packages/client/components/NewMeetingDropdown.tsx deleted file mode 100644 index c27f812c293..00000000000 --- a/packages/client/components/NewMeetingDropdown.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, {forwardRef} from 'react' -import useMenu from '../hooks/useMenu' -import DropdownToggleInner from './DropdownToggleInner' -import DropdownToggleV2 from './DropdownToggleV2' - -interface Props { - className?: string - icon?: React.ReactElement - dropdownIcon?: string - label: string - disabled?: boolean - onClick: ReturnType['togglePortal'] - onMouseEnter?: () => void - title?: string - opened?: boolean -} - -const NewMeetingDropdown = forwardRef((props: Props, ref: any) => { - const {className, icon, dropdownIcon, label, disabled, onClick, onMouseEnter, title, opened} = - props - return ( - - - - ) -}) - -export default NewMeetingDropdown diff --git a/packages/client/components/NewMeetingTeamPicker.tsx b/packages/client/components/NewMeetingTeamPicker.tsx index 199499dc2dc..9ce8af3b5bb 100644 --- a/packages/client/components/NewMeetingTeamPicker.tsx +++ b/packages/client/components/NewMeetingTeamPicker.tsx @@ -1,41 +1,25 @@ +import {ExpandMore, LockOpen} from '@mui/icons-material' +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 {NewMeetingTeamPicker_selectedTeam$key} from '~/__generated__/NewMeetingTeamPicker_selectedTeam.graphql' import {NewMeetingTeamPicker_teams$key} from '~/__generated__/NewMeetingTeamPicker_teams.graphql' import useAtmosphere from '../hooks/useAtmosphere' -import {MenuPosition} from '../hooks/useCoords' -import useMenu from '../hooks/useMenu' -import {PortalStatus} from '../hooks/usePortal' -import lazyPreload from '../utils/lazyPreload' +import {PALETTE} from '../styles/paletteV3' +import {Menu} from '../ui/Menu/Menu' import setPreferredTeamId from '../utils/relay/setPreferredTeamId' -import NewMeetingDropdown from './NewMeetingDropdown' import NewMeetingTeamPickerAvatars from './NewMeetingTeamPickerAvatars' -const SelectTeamDropdown = lazyPreload( - () => - import( - /* webpackChunkName: 'SelectTeamDropdown' */ - './SelectTeamDropdown' - ) -) - interface Props { selectedTeamRef: NewMeetingTeamPicker_selectedTeam$key teamsRef: NewMeetingTeamPicker_teams$key onSelectTeam: (teamId: string) => void - positionOverride?: MenuPosition - customPortal?: React.ReactNode + onShareToOrg?: () => void } const NewMeetingTeamPicker = (props: Props) => { - const {selectedTeamRef, teamsRef, onSelectTeam, positionOverride, customPortal} = props - const {togglePortal, menuPortal, originRef, menuProps, portalStatus} = useMenu( - positionOverride ?? MenuPosition.LOWER_RIGHT, - { - isDropdown: true - } - ) + const {selectedTeamRef, teamsRef, onSelectTeam, onShareToOrg} = props const atmosphere = useAtmosphere() @@ -49,6 +33,9 @@ const NewMeetingTeamPicker = (props: Props) => { fragment NewMeetingTeamPicker_selectedTeam on Team { ...NewMeetingTeamPickerAvatars_team name + organization { + name + } } `, selectedTeamRef @@ -66,30 +53,72 @@ const NewMeetingTeamPicker = (props: Props) => { ) const {name} = selectedTeam + return ( - <> - } - label={name} - onClick={togglePortal} - onMouseEnter={SelectTeamDropdown.preload} - disabled={teams.length === 0} - ref={originRef} - title={'Team'} - opened={[PortalStatus.Entering, PortalStatus.Entered].includes(portalStatus)} - /> - {menuPortal( - customPortal ? ( - customPortal + +
+ +
+
+
Team
+
{name}
+
+
+ +
+
+ } + > +
+ {onShareToOrg ? ( +
+
+ This custom activity is private to the {selectedTeam.name} team. +
+
+
+ As a member of the team you can share this activity with other teams at the{' '} + {selectedTeam.organization.name} organization so that they can also use the + activity. +
+ +
) : ( - - ) - )} - + <> + + Select Team: + + +
+ {teams.map((team) => { + return ( + { + handleSelectTeam(team.id) + }} + > + {team.name} + + ) + })} +
+ + )} +
+ ) } diff --git a/packages/client/components/SelectMeetingDropdown.tsx b/packages/client/components/SelectMeetingDropdown.tsx index fde41ff30f1..c7c23b172f2 100644 --- a/packages/client/components/SelectMeetingDropdown.tsx +++ b/packages/client/components/SelectMeetingDropdown.tsx @@ -24,14 +24,14 @@ const SelectMeetingDropdown = (props: Props) => { const meetingCount = meetings.length const label = `${meetingCount} Active ${plural(meetingCount, 'Meeting')}` return ( - <> +
{label} {meetings.map((meeting) => ( ))} - +
) } diff --git a/packages/client/package.json b/packages/client/package.json index 15a2985aa7d..219ac5501dc 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -76,7 +76,7 @@ "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.4", - "@radix-ui/react-dropdown-menu": "^2.0.4", + "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-radio-group": "^1.1.2", "@radix-ui/react-scroll-area": "^1.0.3", "@radix-ui/react-select": "^1.2.2", diff --git a/packages/client/tailwindTheme.ts b/packages/client/tailwindTheme.ts index 8e27c1efdfa..ad30c0d94b7 100644 --- a/packages/client/tailwindTheme.ts +++ b/packages/client/tailwindTheme.ts @@ -168,12 +168,34 @@ export default { opacity: 0, transform: 'scale(0)' } + }, + slideUp: { + from: { + opacity: 0, + transform: 'translateY(10px)' + }, + to: { + opacity: 1, + transform: 'translateY(0)' + } + }, + slideDown: { + from: { + opacity: 0, + transform: 'translateY(-10px)' + }, + to: { + opacity: 1, + transform: 'translateY(0)' + } } }, animation: { overlayShow: 'overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1)', contentShow: 'contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1)', - scaleIn: 'scaleIn 150ms cubic-bezier(0, 0, .2, 1)' + scaleIn: 'scaleIn 150ms cubic-bezier(0, 0, .2, 1)', + slideUp: 'slideUp 200ms cubic-bezier(0, 0, 0.2, 1)', + slideDown: 'slideDown 200ms cubic-bezier(0, 0, 0.2, 1)' } } } as const diff --git a/yarn.lock b/yarn.lock index 99f8e2a34c3..dbefe89118d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5970,7 +5970,7 @@ "@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-escape-keydown" "1.0.3" -"@radix-ui/react-dropdown-menu@^2.0.4", "@radix-ui/react-dropdown-menu@^2.0.5": +"@radix-ui/react-dropdown-menu@^2.0.5": version "2.0.5" resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.5.tgz#19bf4de8ffa348b4eb6a86842f14eff93d741170" integrity sha512-xdOrZzOTocqqkCkYo8yRPCib5OkTkqN7lqNCdxwPOdE466DOaNl4N8PkUIlsXthQvW5Wwkd+aEmWpfWlBoDPEw== @@ -5984,6 +5984,20 @@ "@radix-ui/react-primitive" "1.0.3" "@radix-ui/react-use-controllable-state" "1.0.1" +"@radix-ui/react-dropdown-menu@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz#cdf13c956c5e263afe4e5f3587b3071a25755b63" + integrity sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-menu" "2.0.6" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-focus-guards@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" @@ -6052,6 +6066,31 @@ aria-hidden "^1.1.1" react-remove-scroll "2.5.5" +"@radix-ui/react-menu@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.0.6.tgz#2c9e093c1a5d5daa87304b2a2f884e32288ae79e" + integrity sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + "@radix-ui/react-popper@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.2.tgz#4c0b96fcd188dc1f334e02dba2d538973ad842e9"