From 34ed9ad64661dae0517c6fc51ec3719620c31548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Jaeger=20Foresti?= <60678893+juliajforesti@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:07:21 -0300 Subject: [PATCH] feat: show Recent chats on the new sidebar (#33489) Co-authored-by: Guilherme Gazzo <guilhermegazzo@gmail.com> --- .changeset/five-suns-tickle.md | 6 +++ .../client/sidebarv2/header/SearchList.tsx | 9 +++-- .../client/sidebarv2/header/SearchSection.tsx | 37 ++++++++++++++++--- packages/i18n/src/locales/en.i18n.json | 3 +- 4 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 .changeset/five-suns-tickle.md diff --git a/.changeset/five-suns-tickle.md b/.changeset/five-suns-tickle.md new file mode 100644 index 00000000000..740fc364060 --- /dev/null +++ b/.changeset/five-suns-tickle.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/i18n': minor +'@rocket.chat/meteor': minor +--- + +Adds `Recent` button on the new sidebar Search section to replicate the previous behavior of focusing the search bar - show recent chats. diff --git a/apps/meteor/client/sidebarv2/header/SearchList.tsx b/apps/meteor/client/sidebarv2/header/SearchList.tsx index b132af80f67..066b82ce768 100644 --- a/apps/meteor/client/sidebarv2/header/SearchList.tsx +++ b/apps/meteor/client/sidebarv2/header/SearchList.tsx @@ -1,4 +1,4 @@ -import { Box } from '@rocket.chat/fuselage'; +import { Box, SidebarV2GroupTitle } from '@rocket.chat/fuselage'; import { useTranslation, useUserPreference, useSetting } from '@rocket.chat/ui-contexts'; import type { MouseEventHandler, ReactElement } from 'react'; import React, { useMemo, useRef } from 'react'; @@ -12,9 +12,9 @@ import { useTemplateByViewMode } from '../hooks/useTemplateByViewMode'; import Row from '../search/Row'; import { useSearchItems } from './hooks/useSearchItems'; -type SearchListProps = { filterText: string; onEscSearch: () => void }; +type SearchListProps = { filterText: string; onEscSearch: () => void; showRecentList?: boolean }; -const SearchList = ({ filterText, onEscSearch }: SearchListProps) => { +const SearchList = ({ filterText, onEscSearch, showRecentList }: SearchListProps) => { const t = useTranslation(); const boxRef = useRef<HTMLDivElement>(null); @@ -58,12 +58,13 @@ const SearchList = ({ filterText, onEscSearch }: SearchListProps) => { flexShrink={1} h='full' w='full' - pbs={8} + pbs={showRecentList ? 0 : 8} aria-live='polite' aria-atomic='true' aria-busy={isLoading} onClick={handleClick} > + {showRecentList && <SidebarV2GroupTitle title={t('Recent')} />} <Virtuoso style={{ height: '100%', width: '100%' }} totalCount={items.length} diff --git a/apps/meteor/client/sidebarv2/header/SearchSection.tsx b/apps/meteor/client/sidebarv2/header/SearchSection.tsx index 71b26b2e405..e8a85ca0bb5 100644 --- a/apps/meteor/client/sidebarv2/header/SearchSection.tsx +++ b/apps/meteor/client/sidebarv2/header/SearchSection.tsx @@ -1,8 +1,10 @@ +import { useFocusManager } from '@react-aria/focus'; import { css } from '@rocket.chat/css-in-js'; -import { Box, Icon, TextInput, Palette, SidebarV2Section } from '@rocket.chat/fuselage'; +import { Box, Icon, TextInput, Palette, SidebarV2Section, IconButton } from '@rocket.chat/fuselage'; import { useMergedRefs, useOutsideClick } from '@rocket.chat/fuselage-hooks'; import { useTranslation, useUser } from '@rocket.chat/ui-contexts'; -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { FocusScope } from 'react-aria'; import { useForm } from 'react-hook-form'; import tinykeys from 'tinykeys'; @@ -48,9 +50,13 @@ const shortcut = ((): string => { return '(Ctrl+K)'; })(); +const isRecentButton = (node: EventTarget) => (node as HTMLElement).title === 'Recent'; + const SearchSection = () => { const t = useTranslation(); + const focusManager = useFocusManager(); const user = useUser(); + const [recentButtonPressed, setRecentButtonPressed] = useState(false); const { formState: { isDirty }, @@ -62,12 +68,15 @@ const SearchSection = () => { const { filterText } = watch(); const { ref: filterRef, ...rest } = register('filterText'); + const showRecentList = Boolean(recentButtonPressed && !filterText); + const inputRef = useRef<HTMLInputElement>(null); const wrapperRef = useRef<HTMLDivElement>(null); const mergedRefs = useMergedRefs(filterRef, inputRef); const handleEscSearch = useCallback(() => { resetField('filterText'); + setRecentButtonPressed(false); inputRef.current?.blur(); }, [resetField]); @@ -83,6 +92,11 @@ const SearchSection = () => { event.preventDefault(); setFocus('filterText'); }, + 'Shift+$mod+K': (event) => { + event.preventDefault(); + setRecentButtonPressed(true); + focusManager.focusNext({ accept: (node) => isRecentButton(node) }); + }, 'Escape': (event) => { event.preventDefault(); handleEscSearch(); @@ -92,12 +106,12 @@ const SearchSection = () => { return (): void => { unsubscribe(); }; - }, [handleEscSearch, setFocus]); + }, [focusManager, handleEscSearch, setFocus]); const placeholder = [t('Search'), shortcut].filter(Boolean).join(' '); return ( - <Box className={['rcx-sidebar', isDirty && wrapperStyle]} ref={wrapperRef} role='search'> + <Box className={['rcx-sidebar', (isDirty || showRecentList) && wrapperStyle]} ref={wrapperRef} role='search'> <SidebarV2Section> <TextInput placeholder={placeholder} @@ -110,12 +124,23 @@ const SearchSection = () => { {user && !isDirty && ( <> - <Sort /> + <IconButton + small + icon='clock' + title={t('Recent')} + onClick={() => setRecentButtonPressed(!recentButtonPressed)} + pressed={recentButtonPressed} + /> + {recentButtonPressed ? <IconButton icon='sort' disabled small /> : <Sort />} <CreateRoom /> </> )} </SidebarV2Section> - {isDirty && <SearchList filterText={filterText} onEscSearch={handleEscSearch} />} + {(isDirty || recentButtonPressed) && ( + <FocusScope> + <SearchList filterText={filterText} onEscSearch={handleEscSearch} showRecentList={showRecentList} /> + </FocusScope> + )} </Box> ); }; diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 92056badc0b..9273b890f26 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -6643,5 +6643,6 @@ "Sidepanel_navigation": "Secondary navigation for teams", "Sidepanel_navigation_description": "Display channels and/or discussions associated with teams by default. This allows team owners to customize communication methods to best meet their team’s needs. This is currently in feature preview and will be a premium capability once fully released.", "Show_channels_description": "Show team channels in second sidebar", - "Show_discussions_description": "Show team discussions in second sidebar" + "Show_discussions_description": "Show team discussions in second sidebar", + "Recent": "Recent" } -- GitLab