From 1e96deceae19e6855b96808a904fd905f3f2f348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Fri, 7 Jul 2023 11:31:58 +0200 Subject: [PATCH] Dropdown button, design improvement --- front/src/generated/graphql.tsx | 3 +- .../components/CommentThreadCreateMode.tsx | 141 +++++++----------- .../components/CommentThreadEditMode.tsx | 114 ++++++++++++++ .../CommentThreadRelationPicker.tsx | 3 +- .../components/CommentThreadTypeDropdown.tsx | 18 +++ .../{CommentThread.tsx => Comments.tsx} | 17 +-- .../RightDrawerCreateCommentThread.tsx | 72 ++++++++- .../RightDrawerEditCommentThread.tsx | 17 +++ .../comments/components/ShowPageComments.tsx | 65 -------- .../modules/comments/components/Timeline.tsx | 52 +++++-- ...andleCheckableCommentThreadTargetChange.ts | 3 +- front/src/modules/comments/services/select.ts | 1 + .../ui/components/buttons/DropdownButton.tsx | 94 ++++++++++++ .../components/property-box/PropertyBox.tsx | 1 - .../right-drawer/components/RightDrawer.tsx | 3 +- .../components/RightDrawerBody.tsx | 2 + .../components/RightDrawerRouter.tsx | 3 + .../components/RightDrawerTopBar.tsx | 7 +- .../right-drawer/types/RightDrawerPage.ts | 5 +- front/src/pages/companies/CompanyShow.tsx | 38 ++--- 20 files changed, 452 insertions(+), 207 deletions(-) create mode 100644 front/src/modules/comments/components/CommentThreadEditMode.tsx create mode 100644 front/src/modules/comments/components/CommentThreadTypeDropdown.tsx rename front/src/modules/comments/components/{CommentThread.tsx => Comments.tsx} (89%) create mode 100644 front/src/modules/comments/components/RightDrawerEditCommentThread.tsx delete mode 100644 front/src/modules/comments/components/ShowPageComments.tsx create mode 100644 front/src/modules/ui/components/buttons/DropdownButton.tsx diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index 28f3d641b66..7c63f6cb43a 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -1941,7 +1941,7 @@ export type GetCommentThreadQueryVariables = Exact<{ }>; -export type GetCommentThreadQuery = { __typename?: 'Query', findManyCommentThreads: Array<{ __typename?: 'CommentThread', id: string, createdAt: string, author: { __typename?: 'User', id: string, firstName: string, lastName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName: string, lastName: string, avatarUrl?: string | null } }> | null, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', commentableId: string, commentableType: CommentableType }> | null }> }; +export type GetCommentThreadQuery = { __typename?: 'Query', findManyCommentThreads: Array<{ __typename?: 'CommentThread', id: string, createdAt: string, author: { __typename?: 'User', id: string, firstName: string, lastName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName: string, lastName: string, avatarUrl?: string | null } }> | null, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, commentableId: string, commentableType: CommentableType }> | null }> }; export type AddCommentThreadTargetOnCommentThreadMutationVariables = Exact<{ commentThreadId: Scalars['String']; @@ -2540,6 +2540,7 @@ export const GetCommentThreadDocument = gql` } } commentThreadTargets { + id commentableId commentableType } diff --git a/front/src/modules/comments/components/CommentThreadCreateMode.tsx b/front/src/modules/comments/components/CommentThreadCreateMode.tsx index 00977677754..f8292e0724a 100644 --- a/front/src/modules/comments/components/CommentThreadCreateMode.tsx +++ b/front/src/modules/comments/components/CommentThreadCreateMode.tsx @@ -11,6 +11,7 @@ import { createdCommentThreadIdState } from '@/comments/states/createdCommentThr import CompanyChip from '@/companies/components/CompanyChip'; import { GET_COMPANIES } from '@/companies/services'; import { GET_PEOPLE } from '@/people/services'; +import { DropdownButton } from '@/ui/components/buttons/DropdownButton'; import { AutosizeTextInput } from '@/ui/components/inputs/AutosizeTextInput'; import { PropertyBox } from '@/ui/components/property-box/PropertyBox'; import { PropertyBoxItem } from '@/ui/components/property-box/PropertyBoxItem'; @@ -26,9 +27,11 @@ import { } from '~/generated/graphql'; import { GET_COMMENT_THREAD } from '../services'; +import { CommentableEntity } from '../types/CommentableEntity'; import { CommentThreadItem } from './CommentThreadItem'; import { CommentThreadRelationPicker } from './CommentThreadRelationPicker'; +import { CommentThreadTypeDropdown } from './CommentThreadTypeDropdown'; import '@blocknote/core/style.css'; @@ -40,116 +43,74 @@ const StyledContainer = styled.div` justify-content: flex-start; - max-height: calc(100% - 16px); padding: ${({ theme }) => theme.spacing(2)}; `; -const StyledThreadItemListContainer = styled.div` - align-items: flex-start; - display: flex; - - flex-direction: column-reverse; - gap: ${({ theme }) => theme.spacing(4)}; - - justify-content: flex-start; - overflow: auto; - - width: 100%; -`; - const BlockNoteStyledContainer = styled.div` width: 100%; `; -export function CommentThreadCreateMode() { - const [commentableEntityArray] = useRecoilState(commentableEntityArrayState); +const StyledTopContainer = styled.div` + align-items: flex-start; + align-self: stretch; + background: ${({ theme }) => theme.background.secondary}; + border-bottom: 1px solid ${({ theme }) => theme.border.color.medium}; + display: flex; + flex-direction: column; + gap: 24px; + padding: 24px; +`; - const [createdCommmentThreadId, setCreatedCommentThreadId] = useRecoilState( - createdCommentThreadIdState, - ); +const StyledEditableTitleInput = styled.input` + background: transparent; - const openRightDrawer = useOpenRightDrawer(); + border: none; + color: ${({ theme }) => theme.font.color.primary}; + display: flex; + flex: 1 0 0; - const [createCommentMutation] = useCreateCommentMutation(); + flex-direction: column; + font-family: Inter; + font-size: 20px; + font-style: normal; + font-weight: 600; + justify-content: center; - const [createCommentThreadWithComment] = - useCreateCommentThreadWithCommentMutation(); + line-height: 120%; + outline: none; + width: 318px; - const { data } = useGetCommentThreadQuery({ - variables: { - commentThreadId: createdCommmentThreadId ?? '', - }, - skip: !createdCommmentThreadId, - }); - - const comments = data?.findManyCommentThreads[0]?.comments; - - const displayCommentList = (comments?.length ?? 0) > 0; - - const currentUser = useRecoilValue(currentUserState); - - function handleNewComment(commentText: string) { - if (!isNonEmptyString(commentText)) { - return; - } - - if (!isDefined(currentUser)) { - logError( - 'In handleCreateCommentThread, currentUser is not defined, this should not happen.', - ); - return; - } - - createCommentThreadWithComment({ - variables: { - authorId: currentUser.id, - commentText: commentText, - commentThreadId: v4(), - createdAt: new Date().toISOString(), - commentThreadTargetArray: commentableEntityArray.map( - (commentableEntity) => ({ - commentableId: commentableEntity.id, - commentableType: commentableEntity.type, - id: v4(), - createdAt: new Date().toISOString(), - }), - ), - }, - refetchQueries: [ - getOperationName(GET_COMPANIES) ?? '', - getOperationName(GET_PEOPLE) ?? '', - getOperationName(GET_COMMENT_THREAD) ?? '', - ], - onCompleted(data) { - setCreatedCommentThreadId(data.createOneCommentThread.id); - openRightDrawer('comments'); - }, - }); + :placeholder { + color: ${({ theme }) => theme.font.color.light}; } +`; +export function CommentThreadCreateMode({ + commentableEntityArray, +}: { + commentableEntityArray: CommentableEntity[]; +}) { const editor: BlockNoteEditor | null = useBlockNote({ theme: 'light', }); return ( - {displayCommentList && ( - - {comments?.map((comment) => ( - - ))} - - )} - - } - value={ - - } - label="Relations" - /> - - + + + + + } + value={ + + } + label="Relations" + /> + + diff --git a/front/src/modules/comments/components/CommentThreadEditMode.tsx b/front/src/modules/comments/components/CommentThreadEditMode.tsx new file mode 100644 index 00000000000..5f897d4c3e9 --- /dev/null +++ b/front/src/modules/comments/components/CommentThreadEditMode.tsx @@ -0,0 +1,114 @@ +import { BlockNoteEditor } from '@blocknote/core'; +import { BlockNoteView, useBlockNote } from '@blocknote/react'; +import styled from '@emotion/styled'; + +import { PropertyBox } from '@/ui/components/property-box/PropertyBox'; +import { PropertyBoxItem } from '@/ui/components/property-box/PropertyBoxItem'; +import { IconArrowUpRight } from '@/ui/icons/index'; +import { useGetCommentThreadQuery } from '~/generated/graphql'; + +import { CommentableEntity } from '../types/CommentableEntity'; +import { CommentThreadForDrawer } from '../types/CommentThreadForDrawer'; + +import { Comments } from './Comments'; +import { CommentThreadRelationPicker } from './CommentThreadRelationPicker'; +import { CommentThreadTypeDropdown } from './CommentThreadTypeDropdown'; + +import '@blocknote/core/style.css'; + +const StyledContainer = styled.div` + align-items: flex-start; + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing(4)}; + + justify-content: flex-start; + + padding: ${({ theme }) => theme.spacing(2)}; +`; + +const BlockNoteStyledContainer = styled.div` + width: 100%; +`; + +const StyledTopContainer = styled.div` + align-items: flex-start; + align-self: stretch; + background: ${({ theme }) => theme.background.secondary}; + border-bottom: 1px solid ${({ theme }) => theme.border.color.medium}; + display: flex; + flex-direction: column; + gap: 24px; + padding: 24px; +`; + +const StyledEditableTitleInput = styled.input` + background: transparent; + + border: none; + color: ${({ theme }) => theme.font.color.primary}; + display: flex; + flex: 1 0 0; + + flex-direction: column; + font-family: Inter; + font-size: 20px; + font-style: normal; + font-weight: 600; + justify-content: center; + + line-height: 120%; + outline: none; + width: 318px; + + :placeholder { + color: ${({ theme }) => theme.font.color.light}; + } +`; + +export function CommentThreadEditMode({ + commentThreadId, +}: { + commentThreadId: string; +}) { + const editor: BlockNoteEditor | null = useBlockNote({ + theme: 'light', + }); + + const { data } = useGetCommentThreadQuery({ + variables: { + commentThreadId: commentThreadId ?? '', + }, + skip: !commentThreadId, + }); + + if (typeof data?.findManyCommentThreads[0] === 'undefined') { + return null; + } + + const commentThread = data?.findManyCommentThreads[0]; + + // TODO : prevent editor from creating loops + + return ( + + + + + + } + value={ + + } + label="Relations" + /> + + + + + + + + ); +} diff --git a/front/src/modules/comments/components/CommentThreadRelationPicker.tsx b/front/src/modules/comments/components/CommentThreadRelationPicker.tsx index 2fc2587600b..962f61ba970 100644 --- a/front/src/modules/comments/components/CommentThreadRelationPicker.tsx +++ b/front/src/modules/comments/components/CommentThreadRelationPicker.tsx @@ -19,6 +19,7 @@ import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/ui/utils/flat import { getLogoUrlFromDomainName } from '@/utils/utils'; import { CommentableType, + GetCommentThreadQuery, useSearchCompanyQuery, useSearchPeopleQuery, } from '~/generated/graphql'; @@ -29,7 +30,7 @@ import { CommentableEntity } from '../types/CommentableEntity'; import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect'; type OwnProps = { - commentThread?: CommentThreadForDrawer; + commentThread?: GetCommentThreadQuery['findManyCommentThreads'][0]; preselected?: CommentableEntity[]; }; diff --git a/front/src/modules/comments/components/CommentThreadTypeDropdown.tsx b/front/src/modules/comments/components/CommentThreadTypeDropdown.tsx new file mode 100644 index 00000000000..81be99f5c2d --- /dev/null +++ b/front/src/modules/comments/components/CommentThreadTypeDropdown.tsx @@ -0,0 +1,18 @@ +import { + DropdownButton, + DropdownOptionType, +} from '@/ui/components/buttons/DropdownButton'; +import { IconNotes, IconPhone } from '@/ui/icons/index'; + +export function CommentThreadTypeDropdown() { + const options: DropdownOptionType[] = [ + { label: 'Notes', icon: }, + // { label: 'Call', icon: }, + ]; + + const handleSelect = (selectedOption: DropdownOptionType) => { + console.log(`You selected: ${selectedOption.label}`); + }; + + return ; +} diff --git a/front/src/modules/comments/components/CommentThread.tsx b/front/src/modules/comments/components/Comments.tsx similarity index 89% rename from front/src/modules/comments/components/CommentThread.tsx rename to front/src/modules/comments/components/Comments.tsx index 68f1b35f858..7021c994595 100644 --- a/front/src/modules/comments/components/CommentThread.tsx +++ b/front/src/modules/comments/components/Comments.tsx @@ -14,7 +14,10 @@ import { IconArrowUpRight } from '@/ui/icons/index'; import { logError } from '@/utils/logs/logError'; import { isDefined } from '@/utils/type-guards/isDefined'; import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString'; -import { useCreateCommentMutation } from '~/generated/graphql'; +import { + GetCommentThreadQuery, + useCreateCommentMutation, +} from '~/generated/graphql'; import { GET_COMMENT_THREADS_BY_TARGETS } from '../services'; @@ -23,7 +26,7 @@ import { CommentThreadItem } from './CommentThreadItem'; import { CommentThreadRelationPicker } from './CommentThreadRelationPicker'; type OwnProps = { - commentThread: CommentThreadForDrawer; + commentThread: GetCommentThreadQuery['findManyCommentThreads'][0]; }; const StyledContainer = styled.div` @@ -36,6 +39,7 @@ const StyledContainer = styled.div` justify-content: flex-start; padding: ${({ theme }) => theme.spacing(2)}; + width: 100%; `; const StyledThreadItemListContainer = styled.div` @@ -50,7 +54,7 @@ const StyledThreadItemListContainer = styled.div` width: 100%; `; -export function CommentThread({ commentThread }: OwnProps) { +export function Comments({ commentThread }: OwnProps) { const [createCommentMutation] = useCreateCommentMutation(); const currentUser = useRecoilValue(currentUserState); @@ -89,13 +93,6 @@ export function CommentThread({ commentThread }: OwnProps) { return ( - - } - value={} - label="Relations" - /> - {commentThread.comments?.map((comment, index) => ( ({ + commentableId: commentableEntity.id, + commentableType: commentableEntity.type, + id: v4(), + createdAt: new Date().toISOString(), + }), + ), + }, + refetchQueries: [ + getOperationName(GET_COMPANIES) ?? '', + getOperationName(GET_PEOPLE) ?? '', + getOperationName(GET_COMMENT_THREAD) ?? '', + ], + onCompleted(data) { + // TODO : redirect to drawer comment thread with data.createOneCommentThread.id + openRightDrawer('comments'); + }, + }); + } + return ( - + handleNewCommentThread('text')} + /> - + ); diff --git a/front/src/modules/comments/components/RightDrawerEditCommentThread.tsx b/front/src/modules/comments/components/RightDrawerEditCommentThread.tsx new file mode 100644 index 00000000000..faa2a24594c --- /dev/null +++ b/front/src/modules/comments/components/RightDrawerEditCommentThread.tsx @@ -0,0 +1,17 @@ +import { RightDrawerBody } from '@/ui/layout/right-drawer/components/RightDrawerBody'; +import { RightDrawerPage } from '@/ui/layout/right-drawer/components/RightDrawerPage'; +import { RightDrawerTopBar } from '@/ui/layout/right-drawer/components/RightDrawerTopBar'; +import { CommentableType } from '~/generated/graphql'; + +import { CommentThreadEditMode } from './CommentThreadEditMode'; + +export function RightDrawerEditCommentThread() { + return ( + + + + + + + ); +} diff --git a/front/src/modules/comments/components/ShowPageComments.tsx b/front/src/modules/comments/components/ShowPageComments.tsx deleted file mode 100644 index eac1e19f8e9..00000000000 --- a/front/src/modules/comments/components/ShowPageComments.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import styled from '@emotion/styled'; - -import { CommentThreadForDrawer } from '@/comments/types/CommentThreadForDrawer'; -import { RightDrawerBody } from '@/ui/layout/right-drawer/components/RightDrawerBody'; -import { RightDrawerPage } from '@/ui/layout/right-drawer/components/RightDrawerPage'; -import { - SortOrder, - useGetCommentThreadsByTargetsQuery, -} from '~/generated/graphql'; - -import { CommentableEntity } from '../types/CommentableEntity'; - -import { CommentThread } from './CommentThread'; - -const StyledTopBar = styled.div` - align-items: center; - border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; - color: ${({ theme }) => theme.font.color.secondary}; - display: flex; - flex-direction: row; - font-size: 13px; - justify-content: space-between; - min-height: 40px; - padding-left: 8px; - padding-right: 8px; -`; - -const StyledTopBarTitle = styled.div` - align-items: center; - font-weight: 500; - margin-right: ${({ theme }) => theme.spacing(1)}; -`; - -export function ShowPageComments({ - commentableEntity, -}: { - commentableEntity?: CommentableEntity; -}) { - const { data: queryResult } = useGetCommentThreadsByTargetsQuery({ - variables: { - commentThreadTargetIds: commentableEntity ? [commentableEntity.id] : [], - orderBy: [ - { - createdAt: SortOrder.Desc, - }, - ], - }, - }); - - const commentThreads: CommentThreadForDrawer[] = - queryResult?.findManyCommentThreads ?? []; - - return ( - - - Timeline - - - {commentThreads.map((commentThread) => ( - - ))} - - - ); -} diff --git a/front/src/modules/comments/components/Timeline.tsx b/front/src/modules/comments/components/Timeline.tsx index ccb1bd429ad..ee3268b3e05 100644 --- a/front/src/modules/comments/components/Timeline.tsx +++ b/front/src/modules/comments/components/Timeline.tsx @@ -2,6 +2,7 @@ import { Tooltip } from 'react-tooltip'; import styled from '@emotion/styled'; import { IconNotes, IconPlus } from '@/ui/icons/index'; +import { useOpenRightDrawer } from '@/ui/layout/right-drawer/hooks/useOpenRightDrawer'; import { beautifyExactDate, beautifyPastDateRelativeToNow, @@ -24,7 +25,7 @@ const StyledTimelineContainer = styled.div` gap: 4px; justify-content: flex-start; overflow-y: auto; - padding: 12px 16px 64px 16px; + padding: 64px 16px 12px 16px; `; const StyledTimelineEmptyContainer = styled.div` @@ -38,6 +39,20 @@ const StyledTimelineEmptyContainer = styled.div` padding: 12px 16px 64px 16px; `; +const StyledEmptyTimelineTitle = styled.div` + color: ${({ theme }) => theme.font.color.secondary}; + font-size: 24px; + font-weight: 600; + line-height: 120%; +`; + +const StyledEmptyTimelineSubTitle = styled.div` + color: ${({ theme }) => theme.font.color.extraLight}; + font-size: 24px; + font-weight: 600; + line-height: 120%; +`; + const StyledTimelineItemContainer = styled.div` align-items: center; align-self: stretch; @@ -73,7 +88,6 @@ const StyledItemTitleDate = styled.div` display: flex; gap: 8px; justify-content: flex-end; - width: 110px; `; const StyledVerticalLineContainer = styled.div` @@ -94,6 +108,7 @@ const StyledVerticalLine = styled.div` const StyledCardContainer = styled.div` align-items: center; + cursor: pointer; display: flex; flex-direction: column; gap: 8px; @@ -145,13 +160,13 @@ const StyledTooltip = styled(Tooltip)` padding: 8px; `; -const StyledBottomActionBar = styled.div` +const StyledTopActionBar = styled.div` align-items: flex-start; align-self: stretch; - bottom: 8px; display: flex; flex-direction: column; position: absolute; + top: 12px; `; export function Timeline({ entity }: { entity: CommentableEntity }) { @@ -166,13 +181,16 @@ export function Timeline({ entity }: { entity: CommentableEntity }) { }, }); + const openRightDrawer = useOpenRightDrawer(); + const commentThreads: CommentThreadForDrawer[] = queryResult?.findManyCommentThreads ?? []; if (!commentThreads.length) { return ( -

No activity yet

+ No activity yet + Create one:
); @@ -188,6 +206,16 @@ export function Timeline({ entity }: { entity: CommentableEntity }) { return ( <> + + + + + + + + + + @@ -214,7 +242,9 @@ export function Timeline({ entity }: { entity: CommentableEntity }) { - null}> + openRightDrawer('edit-comment-thread')} + > {commentThread.title} {commentThread.body} @@ -223,16 +253,6 @@ export function Timeline({ entity }: { entity: CommentableEntity }) { ); })} - - - - - - - - - - ); } diff --git a/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts b/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts index 7716f12eaed..c7ceec24ce0 100644 --- a/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts +++ b/front/src/modules/comments/hooks/useHandleCheckableCommentThreadTargetChange.ts @@ -4,6 +4,7 @@ import { v4 } from 'uuid'; import { GET_COMPANIES } from '@/companies/services'; import { GET_PEOPLE } from '@/people/services'; import { + GetCommentThreadQuery, useAddCommentThreadTargetOnCommentThreadMutation, useRemoveCommentThreadTargetOnCommentThreadMutation, } from '~/generated/graphql'; @@ -15,7 +16,7 @@ import { CommentThreadForDrawer } from '../types/CommentThreadForDrawer'; export function useHandleCheckableCommentThreadTargetChange({ commentThread, }: { - commentThread?: CommentThreadForDrawer; + commentThread?: GetCommentThreadQuery['findManyCommentThreads'][0]; }) { const [addCommentThreadTargetOnCommentThread] = useAddCommentThreadTargetOnCommentThreadMutation({ diff --git a/front/src/modules/comments/services/select.ts b/front/src/modules/comments/services/select.ts index 6d3f873db7f..e04712be9dc 100644 --- a/front/src/modules/comments/services/select.ts +++ b/front/src/modules/comments/services/select.ts @@ -68,6 +68,7 @@ export const GET_COMMENT_THREAD = gql` } } commentThreadTargets { + id commentableId commentableType } diff --git a/front/src/modules/ui/components/buttons/DropdownButton.tsx b/front/src/modules/ui/components/buttons/DropdownButton.tsx new file mode 100644 index 00000000000..eb56f16a866 --- /dev/null +++ b/front/src/modules/ui/components/buttons/DropdownButton.tsx @@ -0,0 +1,94 @@ +import React, { useState } from 'react'; +import styled from '@emotion/styled'; + +import { IconChevronDown } from '@/ui/icons/index'; + +type ButtonProps = React.ComponentProps<'button'>; + +export type DropdownOptionType = { + label: string; + icon: React.ReactNode; +}; + +type Props = { + options: DropdownOptionType[]; + onSelection: (value: DropdownOptionType) => void; +} & ButtonProps; + +const StyledButton = styled.button` + align-items: center; + background: ${({ theme }) => theme.background.tertiary}; + border: 1px solid ${({ theme }) => theme.border.color.medium}; + border-radius: 4px; + color: ${({ theme }) => theme.font.color.secondary}; + display: flex; + font-size: 13px; + font-weight: 500; + gap: 8px; + height: 24px; + line-height: 150%; + padding: 3px 8px; + + svg { + align-items: center; + display: flex; + height: 14px; + justify-content: center; + width: 14px; + } +`; + +const DropdownContainer = styled.div` + position: relative; +`; + +const DropdownMenu = styled.div` + display: flex; + flex-direction: column; + margin-top: -2px; + position: absolute; +`; + +export function DropdownButton({ + options, + onSelection, + ...buttonProps +}: Props) { + const [isOpen, setIsOpen] = useState(false); + const [selectedOption, setSelectedOption] = useState(options[0]); + + if (!options.length) { + throw new Error('You must provide at least one option.'); + } + + const handleSelect = + (option: DropdownOptionType) => + (event: React.MouseEvent) => { + event.preventDefault(); + onSelection(option); + setSelectedOption(option); + setIsOpen(false); + }; + + return ( + + setIsOpen(!isOpen)} {...buttonProps}> + {selectedOption.icon} + {selectedOption.label} + {options.length > 1 && } + + {isOpen && ( + + {options + .filter((option) => option.label !== selectedOption.label) + .map((option, index) => ( + + {option.icon} + {option.label} + + ))} + + )} + + ); +} diff --git a/front/src/modules/ui/components/property-box/PropertyBox.tsx b/front/src/modules/ui/components/property-box/PropertyBox.tsx index 87d675f26f7..a0e975c987d 100644 --- a/front/src/modules/ui/components/property-box/PropertyBox.tsx +++ b/front/src/modules/ui/components/property-box/PropertyBox.tsx @@ -6,7 +6,6 @@ const StyledCompanyPropertyBox = styled.div` display: flex; flex-direction: column; gap: 8px; - padding: 0px 12px; `; const StyledCompanyPropertyBoxContainer = styled.div` diff --git a/front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx b/front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx index 7eeb873c01f..4dac76b53fa 100644 --- a/front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx +++ b/front/src/modules/ui/layout/right-drawer/components/RightDrawer.tsx @@ -12,7 +12,7 @@ import { rightDrawerPageState } from '../states/rightDrawerPageState'; import { RightDrawerRouter } from './RightDrawerRouter'; const ClickableBackground = styled.div` - backdrop-filter: blur(1px); + //backdrop-filter: blur(1px); height: 100%; left: 0; position: fixed; @@ -33,6 +33,7 @@ const StyledContainer = styled.div` width: ${({ theme }) => theme.rightDrawerWidth}; z-index: 2; `; + const StyledRightDrawer = styled.div` display: flex; flex-direction: row; diff --git a/front/src/modules/ui/layout/right-drawer/components/RightDrawerBody.tsx b/front/src/modules/ui/layout/right-drawer/components/RightDrawerBody.tsx index 3abc1b49f22..d632f16a9fe 100644 --- a/front/src/modules/ui/layout/right-drawer/components/RightDrawerBody.tsx +++ b/front/src/modules/ui/layout/right-drawer/components/RightDrawerBody.tsx @@ -3,5 +3,7 @@ import styled from '@emotion/styled'; export const RightDrawerBody = styled.div` display: flex; flex-direction: column; + height: calc(100vh - 41px); // TODO: improve overflow: auto; + position: relative; `; diff --git a/front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx b/front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx index 83c8c5f3133..2eeee2e8aae 100644 --- a/front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx +++ b/front/src/modules/ui/layout/right-drawer/components/RightDrawerRouter.tsx @@ -1,6 +1,7 @@ import { useRecoilState } from 'recoil'; import { RightDrawerCreateCommentThread } from '@/comments/components/RightDrawerCreateCommentThread'; +import { RightDrawerEditCommentThread } from '@/comments/components/RightDrawerEditCommentThread'; import { RightDrawerTimeline } from '@/comments/components/RightDrawerTimeline'; import { isDefined } from '@/utils/type-guards/isDefined'; @@ -17,6 +18,8 @@ export function RightDrawerRouter() { ) : rightDrawerPage === 'create-comment-thread' ? ( + ) : rightDrawerPage === 'edit-comment-thread' ? ( + ) : ( <> ); diff --git a/front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx b/front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx index b89dede43a2..8d4f4891965 100644 --- a/front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx +++ b/front/src/modules/ui/layout/right-drawer/components/RightDrawerTopBar.tsx @@ -25,14 +25,19 @@ const StyledTopBarTitle = styled.div` export function RightDrawerTopBar({ title, + onClick, }: { title: string | null | undefined; + onClick?: () => void; }) { + function handleOnClick() { + onClick?.(); + } return ( {title} -