diff --git a/apps/meteor/client/NavBarV2/NavBar.tsx b/apps/meteor/client/NavBarV2/NavBar.tsx index 8827cdb36fc46..67ccd67311e5b 100644 --- a/apps/meteor/client/NavBarV2/NavBar.tsx +++ b/apps/meteor/client/NavBarV2/NavBar.tsx @@ -1,9 +1,9 @@ -import { useToolbar } from '@react-aria/toolbar'; import { NavBar as NavBarComponent, NavBarSection, NavBarGroup, NavBarDivider } from '@rocket.chat/fuselage'; -import { usePermission, useTranslation, useUser } from '@rocket.chat/ui-contexts'; +import { usePermission, useUser } from '@rocket.chat/ui-contexts'; import { useVoipState } from '@rocket.chat/ui-voip'; -import { useRef } from 'react'; +import { useTranslation } from 'react-i18next'; +import NavbarNavigation from './NavBarNavigation'; import { NavBarItemOmniChannelCallDialPad, NavBarItemOmnichannelContact, @@ -25,7 +25,7 @@ import { useOmnichannelEnabled } from '../hooks/omnichannel/useOmnichannelEnable import { useOmnichannelShowQueueLink } from '../hooks/omnichannel/useOmnichannelShowQueueLink'; const NavBar = () => { - const t = useTranslation(); + const { t } = useTranslation(); const user = useUser(); const showOmnichannel = useOmnichannelEnabled(); @@ -38,19 +38,10 @@ const NavBar = () => { const isCallReady = useIsCallReady(); const { isEnabled: showVoip } = useVoipState(); - const pagesToolbarRef = useRef(null); - const { toolbarProps: pagesToolbarProps } = useToolbar({ 'aria-label': t('Pages') }, pagesToolbarRef); - - const omnichannelToolbarRef = useRef(null); - const { toolbarProps: omnichannelToolbarProps } = useToolbar({ 'aria-label': t('Omnichannel') }, omnichannelToolbarRef); - - const voipToolbarRef = useRef(null); - const { toolbarProps: voipToolbarProps } = useToolbar({ 'aria-label': t('Voice_Call') }, voipToolbarRef); - return ( - + {showMarketplace && } @@ -58,10 +49,11 @@ const NavBar = () => { + {showVoip && ( <> - + @@ -70,7 +62,7 @@ const NavBar = () => { )} {showOmnichannel && ( <> - + {showOmnichannelQueueLink && } {isCallReady && } @@ -80,7 +72,7 @@ const NavBar = () => { )} - + {user ? : } diff --git a/apps/meteor/client/NavBarV2/NavBarNavigation.tsx b/apps/meteor/client/NavBarV2/NavBarNavigation.tsx new file mode 100644 index 0000000000000..c8507341a45f3 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarNavigation.tsx @@ -0,0 +1,25 @@ +import { NavBarGroup, NavBarSection, NavBarItem } from '@rocket.chat/fuselage'; +import { useRouter } from '@rocket.chat/ui-contexts'; +import { FocusScope } from 'react-aria'; +import { useTranslation } from 'react-i18next'; + +import NavBarSearch from './NavBarSearch'; + +const NavbarNavigation = () => { + const { t } = useTranslation(); + const { navigate } = useRouter(); + + return ( + + + + + + navigate(-1)} icon='chevron-right' small /> + navigate(1)} icon='chevron-left' small /> + + + ); +}; + +export default NavbarNavigation; diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearch.tsx b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearch.tsx new file mode 100644 index 0000000000000..0d5ce3d62d296 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearch.tsx @@ -0,0 +1,176 @@ +import { Box, Icon, TextInput, Tile } from '@rocket.chat/fuselage'; +import { useDebouncedValue, useEffectEvent, useMergedRefs, useOutsideClick } from '@rocket.chat/fuselage-hooks'; +import type { KeyboardEvent } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; +import { useFocusManager, useOverlayTrigger } from 'react-aria'; +import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { useOverlayTriggerState } from 'react-stately'; +import tinykeys from 'tinykeys'; + +import NavBarSearchNoResults from './NavBarSearchNoResults'; +import NavBarSearchRow from './NavBarSearchRow'; +import { getShortcut } from './getShortcut'; +import { useSearchItems } from './hooks/useSearchItems'; +import { CustomScrollbars } from '../../components/CustomScrollbars'; + +const isOption = (node: Element) => node.getAttribute('role') === 'option'; + +const NavBarSearch = () => { + const { t } = useTranslation(); + const focusManager = useFocusManager(); + const shortcut = getShortcut(); + + const placeholder = [t('Search_rooms'), shortcut].filter(Boolean).join(' '); + + const { + formState: { isDirty }, + register, + watch, + resetField, + setFocus, + } = useForm({ defaultValues: { filterText: '' } }); + const { ref: filterRef, ...rest } = register('filterText'); + const debouncedFilter = useDebouncedValue(watch('filterText'), 200); + + const { filterText } = watch(); + + const { data: items = [], isLoading } = useSearchItems(debouncedFilter); + + const triggerRef = useRef(null); + + const state = useOverlayTriggerState({}); + const { triggerProps, overlayProps } = useOverlayTrigger({ type: 'listbox' }, state, triggerRef); + delete triggerProps.onPress; + + const handleEscSearch = useCallback(() => { + resetField('filterText'); + state.close(); + }, [resetField, state]); + + const handleClearText = useEffectEvent(() => { + resetField('filterText'); + setFocus('filterText'); + }); + + const handleSelect = useEffectEvent(() => { + state.close(); + resetField('filterText'); + }); + + const containerRef = useRef(null); + const mergedRefs = useMergedRefs(filterRef, triggerRef); + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.code === 'Tab') { + state.close(); + } + + if (e.code === 'ArrowUp' || e.code === 'ArrowDown') { + e.preventDefault(); + + if (e.code === 'ArrowUp') { + return focusManager?.focusPrevious({ + wrap: true, + accept: (node) => isOption(node), + }); + } + + if (e.code === 'ArrowDown') { + focusManager?.focusNext({ + wrap: true, + accept: (node) => isOption(node), + }); + } + } + }; + + useOutsideClick([containerRef], state.close); + + useEffect(() => { + const unsubscribe = tinykeys(window, { + '$mod+K': (event) => { + event.preventDefault(); + setFocus('filterText'); + }, + '$mod+P': (event) => { + event.preventDefault(); + setFocus('filterText'); + }, + 'Escape': (event) => { + event.preventDefault(); + handleEscSearch(); + }, + }); + + return (): void => { + unsubscribe(); + }; + }, [focusManager, handleEscSearch, setFocus]); + + return ( + + state.setOpen(true)} + onKeyDown={(e) => { + state.setOpen(true); + + if ((e.code === 'Tab' && e.shiftKey) || e.key === 'Escape') { + state.close(); + } + + if (e.code === 'ArrowUp' || e.code === 'ArrowDown') { + e.preventDefault(); + + focusManager?.focusNext({ + accept: (node) => isOption(node), + }); + } + }} + autoComplete='off' + placeholder={placeholder} + ref={mergedRefs} + role='combobox' + small + addon={} + /> + {state.isOpen && ( + + +
+ {items.length === 0 && !isLoading && } + {items.length > 0 && ( + + {filterText ? t('Results') : t('Recent')} + + )} + {items.map((item) => ( +
+ +
+ ))} +
+
+
+ )} +
+ ); +}; + +export default NavBarSearch; diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchItem.tsx b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchItem.tsx new file mode 100644 index 0000000000000..7c26ad4febcee --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchItem.tsx @@ -0,0 +1,28 @@ +import { SidebarV2Item, SidebarV2ItemAvatarWrapper, SidebarV2ItemTitle } from '@rocket.chat/fuselage'; +import type { HTMLAttributes, ReactElement, ReactNode } from 'react'; + +type NavBarSearchItemProps = { + title: string; + avatar: ReactElement; + icon: ReactNode; + actions?: ReactElement; + href?: string; + unread?: boolean; + selected?: boolean; + badges?: ReactElement; + clickable?: boolean; +} & Omit, 'is'>; + +const NavBarSearchItem = ({ icon, title, avatar, actions, unread, badges, ...props }: NavBarSearchItemProps) => { + return ( + + {avatar && {avatar}} + {icon && icon} + {title} + {badges && badges} + {actions && actions} + + ); +}; + +export default NavBarSearchItem; diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchItemWithData.tsx b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchItemWithData.tsx new file mode 100644 index 0000000000000..da83a9ca1c129 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchItemWithData.tsx @@ -0,0 +1,59 @@ +import { isOmnichannelRoom } from '@rocket.chat/core-typings'; +import { SidebarV2ItemBadge, SidebarV2ItemIcon } from '@rocket.chat/fuselage'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; +import type { ComponentProps, ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; + +import NavBarSearchItem from './NavBarSearchItem'; +import { RoomIcon } from '../../components/RoomIcon'; +import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; +import { OmnichannelBadges } from '../../sidebarv2/badges/OmnichannelBadges'; +import { useUnreadDisplay } from '../../sidebarv2/hooks/useUnreadDisplay'; + +type NavBarSearchItemWithDataProps = { + room: SubscriptionWithRoom; + id: string; + AvatarTemplate: ReactElement; +} & Partial>; + +const NavBarSearchItemWithData = ({ room, AvatarTemplate, ...props }: NavBarSearchItemWithDataProps) => { + const { t } = useTranslation(); + + const href = roomCoordinator.getRouteLink(room.t, room) || ''; + const title = roomCoordinator.getRoomName(room.t, room) || ''; + + const { unreadTitle, unreadVariant, showUnread, unreadCount, highlightUnread: highlighted } = useUnreadDisplay(room); + + const icon = } />; + + const badges = ( + <> + {showUnread && ( + + {unreadCount.total} + + )} + {isOmnichannelRoom(room) && } + + ); + + return ( + + ); +}; + +export default NavBarSearchItemWithData; diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchNoResults.tsx b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchNoResults.tsx new file mode 100644 index 0000000000000..ef468da5d166b --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchNoResults.tsx @@ -0,0 +1,10 @@ +import { useTranslation } from 'react-i18next'; + +import GenericNoResults from '../../components/GenericNoResults'; + +const NavBarSearchNoResults = () => { + const { t } = useTranslation(); + return ; +}; + +export default NavBarSearchNoResults; diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchRow.tsx b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchRow.tsx new file mode 100644 index 0000000000000..e60d9c6ae5c77 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchRow.tsx @@ -0,0 +1,24 @@ +import { RoomAvatar } from '@rocket.chat/ui-avatar'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; +import type { ReactElement } from 'react'; +import { memo } from 'react'; + +import NavBarSearchItemWithData from './NavBarSearchItemWithData'; +import NavBarSearchUserRow from './NavBarSearchUserRow'; + +type NavBarSearchRowProps = { + room: SubscriptionWithRoom; + onClick: () => void; +}; + +const NavBarSearchRow = ({ room, onClick }: NavBarSearchRowProps): ReactElement => { + const Avatar = ; + + if (room.t === 'd' && !room.u) { + return ; + } + + return ; +}; + +export default memo(NavBarSearchRow); diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchUserRow.tsx b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchUserRow.tsx new file mode 100644 index 0000000000000..4dab2f976d936 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/NavBarSearchUserRow.tsx @@ -0,0 +1,26 @@ +import { SidebarV2ItemIcon } from '@rocket.chat/fuselage'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; +import { useSetting } from '@rocket.chat/ui-contexts'; +import type { ComponentProps, ReactElement } from 'react'; +import { memo } from 'react'; + +import NavBarSearchItem from './NavBarSearchItem'; +import { ReactiveUserStatus } from '../../components/UserStatus'; +import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; + +type NavBarSearchUserRowProps = { + room: SubscriptionWithRoom; + id: string; + AvatarTemplate: ReactElement; +} & Partial>; + +const NavBarSearchUserRow = ({ room, id, AvatarTemplate, ...props }: NavBarSearchUserRowProps) => { + const useRealName = useSetting('UI_Use_Real_Name'); + const title = useRealName ? room.fname || room.name : room.name || room.fname || ''; + const icon = } />; + const href = roomCoordinator.getRouteLink(room.t, { name: room.name }) || ''; + + return ; +}; + +export default memo(NavBarSearchUserRow); diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/getShortcut.ts b/apps/meteor/client/NavBarV2/NavBarSearch/getShortcut.ts new file mode 100644 index 0000000000000..31279e96d68d3 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/getShortcut.ts @@ -0,0 +1,25 @@ +const mobileCheck = function () { + let check = false; + (function (a: string) { + if ( + /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( + a, + ) || + /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( + a.substr(0, 4), + ) + ) + check = true; + })(navigator.userAgent || navigator.vendor || window.opera || ''); + return check; +}; + +export const getShortcut = (): string => { + if (navigator.userAgentData?.mobile || mobileCheck()) { + return ''; + } + if (window.navigator.platform.toLowerCase().includes('mac')) { + return '(\u2318+K)'; + } + return '(Ctrl+K)'; +}; diff --git a/apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts b/apps/meteor/client/NavBarV2/NavBarSearch/hooks/useSearchItems.ts similarity index 100% rename from apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts rename to apps/meteor/client/NavBarV2/NavBarSearch/hooks/useSearchItems.ts diff --git a/apps/meteor/client/NavBarV2/NavBarSearch/index.ts b/apps/meteor/client/NavBarV2/NavBarSearch/index.ts new file mode 100644 index 0000000000000..4cee7a4b8ea42 --- /dev/null +++ b/apps/meteor/client/NavBarV2/NavBarSearch/index.ts @@ -0,0 +1 @@ +export { default } from './NavBarSearch'; diff --git a/apps/meteor/client/sidebarv2/Sidebar.tsx b/apps/meteor/client/sidebarv2/Sidebar.tsx index e292a1a0da80d..278c8b4f9d589 100644 --- a/apps/meteor/client/sidebarv2/Sidebar.tsx +++ b/apps/meteor/client/sidebarv2/Sidebar.tsx @@ -4,7 +4,6 @@ import { memo } from 'react'; import SidebarRoomList from './RoomList'; import SidebarFooter from './footer'; -import SearchSection from './header/SearchSection'; import BannerSection from './sections/BannerSection'; const Sidebar = () => { @@ -18,7 +17,6 @@ const Sidebar = () => { .filter(Boolean) .join(' ')} > - diff --git a/apps/meteor/client/sidebarv2/header/SearchList.tsx b/apps/meteor/client/sidebarv2/header/SearchList.tsx deleted file mode 100644 index 2f9d09b704ab2..0000000000000 --- a/apps/meteor/client/sidebarv2/header/SearchList.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Box, SidebarV2GroupTitle } from '@rocket.chat/fuselage'; -import { useTranslation, useUserPreference, useSetting } from '@rocket.chat/ui-contexts'; -import type { MouseEventHandler, ReactElement } from 'react'; -import { useMemo, useRef } from 'react'; -import { Virtuoso } from 'react-virtuoso'; - -import { VirtualizedScrollbars } from '../../components/CustomScrollbars'; -import RoomListWrapper from '../RoomList/RoomListWrapper'; -import { useAvatarTemplate } from '../hooks/useAvatarTemplate'; -import { usePreventDefault } from '../hooks/usePreventDefault'; -import { useTemplateByViewMode } from '../hooks/useTemplateByViewMode'; -import Row from '../search/Row'; -import { useSearchItems } from './hooks/useSearchItems'; - -type SearchListProps = { filterText: string; onEscSearch: () => void; showRecentList?: boolean }; - -const SearchList = ({ filterText, onEscSearch, showRecentList }: SearchListProps) => { - const t = useTranslation(); - - const boxRef = useRef(null); - usePreventDefault(boxRef); - - const { data: items = [], isLoading } = useSearchItems(filterText); - - const sidebarViewMode = useUserPreference('sidebarViewMode'); - const useRealName = useSetting('UI_Use_Real_Name'); - - const sideBarItemTemplate = useTemplateByViewMode(); - const avatarTemplate = useAvatarTemplate(); - - const extended = sidebarViewMode === 'extended'; - - const itemData = useMemo( - () => ({ - items, - t, - SidebarItemTemplate: sideBarItemTemplate, - avatarTemplate, - useRealName, - extended, - sidebarViewMode, - }), - [avatarTemplate, extended, items, useRealName, sideBarItemTemplate, sidebarViewMode, t], - ); - - const handleClick: MouseEventHandler = (e): void => { - if (e.target instanceof Element && [e.target.tagName, e.target.parentElement?.tagName].includes('BUTTON')) { - return; - } - return onEscSearch(); - }; - - return ( - - {showRecentList && } - - room._id} - itemContent={(_, data): ReactElement => } - /> - - - ); -}; - -export default SearchList; diff --git a/apps/meteor/client/sidebarv2/header/SearchSection.tsx b/apps/meteor/client/sidebarv2/header/SearchSection.tsx deleted file mode 100644 index 4a4d3586ac2e7..0000000000000 --- a/apps/meteor/client/sidebarv2/header/SearchSection.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import { css } from '@rocket.chat/css-in-js'; -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 { useCallback, useEffect, useRef, useState } from 'react'; -import { FocusScope, useFocusManager } from 'react-aria'; -import { useForm } from 'react-hook-form'; -import tinykeys from 'tinykeys'; - -import SearchList from './SearchList'; - -const wrapperStyle = css` - position: absolute; - height: 100%; - width: 100%; - display: flex; - flex-direction: column; - z-index: 99; - top: 0; - left: 0; - background-color: ${Palette.surface['surface-sidebar']}; -`; - -const mobileCheck = function () { - let check = false; - (function (a: string) { - if ( - /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( - a, - ) || - /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( - a.substr(0, 4), - ) - ) - check = true; - })(navigator.userAgent || navigator.vendor || window.opera || ''); - return check; -}; - -const shortcut = ((): string => { - if (navigator.userAgentData?.mobile || mobileCheck()) { - return ''; - } - if (window.navigator.platform.toLowerCase().includes('mac')) { - return '(\u2318+K)'; - } - 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 }, - register, - watch, - resetField, - setFocus, - } = useForm({ defaultValues: { filterText: '' } }); - const { filterText } = watch(); - const { ref: filterRef, ...rest } = register('filterText'); - - const showRecentList = Boolean(recentButtonPressed && !filterText); - - const inputRef = useRef(null); - const wrapperRef = useRef(null); - const mergedRefs = useMergedRefs(filterRef, inputRef); - - const handleEscSearch = useCallback(() => { - resetField('filterText'); - setRecentButtonPressed(false); - inputRef.current?.blur(); - }, [resetField]); - - useOutsideClick([wrapperRef], handleEscSearch); - - useEffect(() => { - const unsubscribe = tinykeys(window, { - '$mod+K': (event) => { - event.preventDefault(); - setFocus('filterText'); - }, - '$mod+P': (event) => { - event.preventDefault(); - setFocus('filterText'); - }, - 'Shift+$mod+K': (event) => { - event.preventDefault(); - setRecentButtonPressed(true); - focusManager?.focusNext({ accept: (node) => isRecentButton(node) }); - }, - 'Escape': (event) => { - event.preventDefault(); - handleEscSearch(); - }, - }); - - return (): void => { - unsubscribe(); - }; - }, [focusManager, handleEscSearch, setFocus]); - - const placeholder = [t('Search'), shortcut].filter(Boolean).join(' '); - - return ( - - - } - /> - - {user && !isDirty && ( - <> - setRecentButtonPressed(!recentButtonPressed)} - pressed={recentButtonPressed} - /> - - )} - - {(isDirty || recentButtonPressed) && ( - - - - )} - - ); -}; - -export default SearchSection; diff --git a/apps/meteor/tests/e2e/feature-preview.spec.ts b/apps/meteor/tests/e2e/feature-preview.spec.ts index 60a634a193ca0..9d1fe55b72c36 100644 --- a/apps/meteor/tests/e2e/feature-preview.spec.ts +++ b/apps/meteor/tests/e2e/feature-preview.spec.ts @@ -90,11 +90,11 @@ test.describe.serial('feature preview', () => { await expect(poHomeChannel.navbar.navbar).toBeVisible(); }); - test('should display "Recent" button on sidebar search section, and display recent chats when clicked', async ({ page }) => { + test('should display recent chats when navbar search is clicked', async ({ page }) => { await page.goto('/home'); - await poHomeChannel.sidebar.btnRecent.click(); - await expect(poHomeChannel.sidebar.sidebar.getByRole('heading', { name: 'Recent' })).toBeVisible(); + await poHomeChannel.navbar.searchInput.click(); + await expect(poHomeChannel.navbar.searchList).toBeVisible(); }); test('should not display room topic in direct message', async ({ page }) => { @@ -169,10 +169,9 @@ test.describe.serial('feature preview', () => { test('should show unread badge on collapser when group is collapsed and has unread items', async ({ page }) => { await page.goto('/home'); - await poHomeChannel.sidebar.openChat(targetChannel); + await poHomeChannel.navbar.openChat(targetChannel); await poHomeChannel.content.sendMessage('hello world'); - await poHomeChannel.sidebar.typeSearch(targetChannel); const item = poHomeChannel.sidebar.getSearchRoomByName(targetChannel); await poHomeChannel.sidebar.markItemAsUnread(item); await poHomeChannel.sidebar.escSearch(); @@ -185,7 +184,7 @@ test.describe.serial('feature preview', () => { test('should not show NavBar in embedded layout', async ({ page }) => { await page.goto('/home'); - await poHomeChannel.sidebar.openChat(targetChannel); + await poHomeChannel.navbar.openChat(targetChannel); await expect(page.locator('role=navigation[name="header"]')).toBeVisible(); const embeddedLayoutURL = `${page.url()}?layout=embedded`; await page.goto(embeddedLayoutURL); @@ -194,7 +193,7 @@ test.describe.serial('feature preview', () => { test('should display the room header properly', async ({ page }) => { await page.goto('/home'); - await poHomeChannel.sidebar.openChat(targetDiscussion.fname); + await poHomeChannel.navbar.openChat(targetDiscussion.fname); await test.step('should not display avatar in room header', async () => { await expect(page.locator('main').locator('header').getByRole('figure')).not.toBeVisible(); @@ -331,7 +330,7 @@ test.describe.serial('feature preview', () => { const message = 'hello world'; await poHomeChannel.navbar.setDisplayMode('Extended'); - await poHomeChannel.sidebar.openChat(sidepanelTeam); + await poHomeChannel.navbar.openChat(sidepanelTeam); await poHomeChannel.content.sendMessage(message); await expect(poHomeChannel.sidepanel.getExtendedItem(sidepanelTeam, message)).toBeVisible(); }); @@ -342,7 +341,7 @@ test.describe.serial('feature preview', () => { const parsedWrong = 'hello > world'; await poHomeChannel.navbar.setDisplayMode('Extended'); - await poHomeChannel.sidebar.openChat(sidepanelTeam); + await poHomeChannel.navbar.openChat(sidepanelTeam); await poHomeChannel.content.sendMessage(message); await expect(poHomeChannel.sidepanel.getExtendedItem(sidepanelTeam, message)).toBeVisible(); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts b/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts index 2d0d68d17d028..ddf79a6188b88 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/navbar.ts @@ -1,5 +1,7 @@ import type { Locator, Page } from '@playwright/test'; +import { expect } from '../../utils/test'; + export class Navbar { private readonly page: Page; @@ -11,17 +13,52 @@ export class Navbar { return this.page.getByRole('navigation', { name: 'header' }); } - get pagesToolbar(): Locator { - return this.navbar.getByRole('toolbar', { name: 'Pages' }); + get pagesGroup(): Locator { + return this.navbar.getByRole('group', { name: 'Pages and actions' }); } get homeButton(): Locator { - return this.pagesToolbar.getByRole('button', { name: 'Home' }); + return this.pagesGroup.getByRole('button', { name: 'Home' }); + } + + get navbarSearchSection(): Locator { + return this.navbar.getByRole('search'); + } + + get searchInput(): Locator { + return this.navbarSearchSection.getByRole('combobox'); + } + + get searchList(): Locator { + return this.navbarSearchSection.getByRole('listbox', { name: 'Channels' }); + } + + async typeSearch(name: string): Promise { + return this.searchInput.fill(name); + } + + async waitForChannel(): Promise { + await this.page.locator('role=main').waitFor(); + await this.page.locator('role=main >> role=heading[level=1]').waitFor(); + const messageList = this.page.getByRole('main').getByRole('list', { name: 'Message list', exact: true }); + await messageList.waitFor(); + + await expect(messageList).not.toHaveAttribute('aria-busy', 'true'); + } + + getSearchRoomByName(name: string): Locator { + return this.searchList.getByRole('option', { name }); + } + + async openChat(name: string): Promise { + await this.typeSearch(name); + await this.getSearchRoomByName(name).click(); + await this.waitForChannel(); } async setDisplayMode(mode: 'Extended' | 'Medium' | 'Condensed'): Promise { - await this.pagesToolbar.getByRole('button', { name: 'Display', exact: true }).click(); - await this.pagesToolbar.getByRole('menuitemcheckbox', { name: mode }).click(); - await this.pagesToolbar.click(); + await this.pagesGroup.getByRole('button', { name: 'Display', exact: true }).click(); + await this.pagesGroup.getByRole('menuitemcheckbox', { name: mode }).click(); + await this.pagesGroup.click(); } } diff --git a/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts b/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts index 4f0cefd6b7a80..27ae799b4e4d9 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/sidebar.ts @@ -1,7 +1,5 @@ import type { Locator, Page } from '@playwright/test'; -import { expect } from '../../utils/test'; - export class Sidebar { private readonly page: Page; @@ -14,20 +12,12 @@ export class Sidebar { return this.page.getByRole('navigation', { name: 'sidebar' }); } - get sidebarSearchSection(): Locator { - return this.sidebar.getByRole('search'); - } - - get btnRecent(): Locator { - return this.sidebarSearchSection.getByRole('button', { name: 'Recent' }); - } - get channelsList(): Locator { return this.sidebar.getByRole('list', { name: 'Channels' }); } - get searchList(): Locator { - return this.sidebar.getByRole('search').getByRole('list', { name: 'Channels' }); + getSearchRoomByName(name: string) { + return this.channelsList.getByRole('link', { name }); } get firstCollapser(): Locator { @@ -38,37 +28,10 @@ export class Sidebar { return this.channelsList.getByRole('listitem').first(); } - get searchInput(): Locator { - return this.sidebarSearchSection.getByRole('searchbox'); - } - async escSearch(): Promise { await this.page.keyboard.press('Escape'); } - async waitForChannel(): Promise { - await this.page.locator('role=main').waitFor(); - await this.page.locator('role=main >> role=heading[level=1]').waitFor(); - const messageList = this.page.getByRole('main').getByRole('list', { name: 'Message list', exact: true }); - await messageList.waitFor(); - - await expect(messageList).not.toHaveAttribute('aria-busy', 'true'); - } - - async typeSearch(name: string): Promise { - return this.searchInput.fill(name); - } - - getSearchRoomByName(name: string): Locator { - return this.searchList.getByRole('link', { name }); - } - - async openChat(name: string): Promise { - await this.typeSearch(name); - await this.getSearchRoomByName(name).click(); - await this.waitForChannel(); - } - async markItemAsUnread(item: Locator): Promise { await item.hover(); await item.focus(); diff --git a/packages/i18n/src/locales/ar.i18n.json b/packages/i18n/src/locales/ar.i18n.json index a2cbd69e5fccb..c278f98d429b7 100644 --- a/packages/i18n/src/locales/ar.i18n.json +++ b/packages/i18n/src/locales/ar.i18n.json @@ -2831,7 +2831,6 @@ "PID": "معرّف العملية", "Page_URL": "عنوان URL للصفحة", "Page_title": "عنوان الصفحة", - "Pages": "صفحات", "Paid_Apps": "تطبيقات مدفوعة", "Parent_channel_doesnt_exist": "Channel غير موجودة.", "Participants": "المشاركون", diff --git a/packages/i18n/src/locales/ca.i18n.json b/packages/i18n/src/locales/ca.i18n.json index d124edade00fe..d0548d9fa6b6d 100644 --- a/packages/i18n/src/locales/ca.i18n.json +++ b/packages/i18n/src/locales/ca.i18n.json @@ -2796,7 +2796,6 @@ "PID": "PID", "Page_URL": "Adreça URL de la pàgina", "Page_title": "Titol de la pàgina", - "Pages": "Pàgines", "Parent_channel_doesnt_exist": "Channel no existeix.", "Participants": "Participants", "Password": "Contrasenya", diff --git a/packages/i18n/src/locales/de.i18n.json b/packages/i18n/src/locales/de.i18n.json index 0508b1b86ae49..ce8b4272a3e75 100644 --- a/packages/i18n/src/locales/de.i18n.json +++ b/packages/i18n/src/locales/de.i18n.json @@ -3995,7 +3995,6 @@ "Page_not_found": "Seite nicht gefunden", "set-react-when-readonly_description": "Berechtigung, Reaktionen in einem schreibgeschützten Kanal zu erlauben", "set-readonly": "Mit Schreibschutz versehem", - "Pages": "Seiten", "set-readonly_description": "Berechtigung, einen Raum schreibgeschützt zu machen", "Settings": "Einstellungen", "Settings_updated": "Die Einstellungen wurden aktualisiert", diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 2c8b13028198a..c20c2dfc29ae0 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -761,6 +761,7 @@ "away": "away", "Away": "Away", "Back": "Back", + "Back_in_history": "Back in history", "Back_to_applications": "Back to applications", "Back_to_chat": "Back to chat", "Back_to_integration_detail": "Back to the integration detail", @@ -2395,6 +2396,7 @@ "Estimated_due_time": "Estimated due time", "error-password-in-history": "Entered password has been previously used", "Forward": "Forward", + "Forward_in_history": "Forward in history", "Estimated_due_time_in_minutes": "Estimated due time (time in minutes)", "Forward_chat": "Forward chat", "Forward_to_department": "Forward to department", @@ -2509,6 +2511,7 @@ "Highlights_How_To": "To be notified when someone mentions a word or phrase, add it here. You can separate words or phrases with commas. Highlight Words are not case sensitive.", "Highlights_List": "Highlight words", "History": "History", + "History_navigation": "History navigation", "every_12_hours": "Once every 12 hours", "every_24_hours": "Once every 24 hours", "every_48_hours": "Once every 48 hours", @@ -4679,7 +4682,7 @@ "Page_not_found": "Page not found", "set-react-when-readonly_description": "Permission to set the ability to react to messages in a read only channel", "set-readonly": "Set ReadOnly", - "Pages": "Pages", + "Pages_and_actions": "Pages and actions", "set-readonly_description": "Permission to set a channel to read only channel", "Settings": "Settings", "Setting": "Setting", @@ -5975,6 +5978,7 @@ "Troubleshoot_Force_Caching_Version": "Force browsers to clear networking cache based on version change", "Troubleshoot_Force_Caching_Version_Alert": "If the value provided is not empty and different from previous one the browsers will try to clear the cache. This setting should not be set for a long period since it affects the browser performance, please clear it as soon as possible.", "Try_now": "Try now", + "Try_entering_a_different_search_term": "Try entering a different search term.", "Try_different_filters": "Try different filters", "Try_searching_in_the_marketplace_instead": "Try searching in the Marketplace instead", "Turn_on_video": "Turn on video", @@ -6778,7 +6782,7 @@ "You_cant_take_chats_offline": "You cannot take new conversations because you're offline", "New_navigation": "Enhanced navigation experience", "New_navigation_description": "Explore our improved navigation, designed with clear scopes for easy access to what you need. This change serves as the foundation for future advancements in navigation management.", - "Workspace_and_user_settings": "Workspace and user settings", + "Workspace_and_user_preferences": "Workspace and user preferences", "Sidebar_Sections_Order": "Sidebar sections order", "Sidebar_Sections_Order_Description": "Select the categories in your preferred order", "Incoming_Calls": "Incoming calls", diff --git a/packages/i18n/src/locales/es.i18n.json b/packages/i18n/src/locales/es.i18n.json index 8871569d02be1..96d76a326479d 100644 --- a/packages/i18n/src/locales/es.i18n.json +++ b/packages/i18n/src/locales/es.i18n.json @@ -2866,7 +2866,6 @@ "PID": "PID", "Page_URL": "URL de página", "Page_title": "Título de página", - "Pages": "Páginas", "Paid_Apps": "Aplicaciones de pago", "Parent_channel_doesnt_exist": "El Channel no existe.", "Participants": "Participantes", diff --git a/packages/i18n/src/locales/fi.i18n.json b/packages/i18n/src/locales/fi.i18n.json index 9131ab922c6aa..2f1726409e649 100644 --- a/packages/i18n/src/locales/fi.i18n.json +++ b/packages/i18n/src/locales/fi.i18n.json @@ -4050,7 +4050,6 @@ "Page_not_found": "Sivua ei löydy", "set-react-when-readonly_description": "Lupa asettaa kyky reagoida viesteihin kanavalla joka on Vain Luku-tilassa", "set-readonly": "Aseta Vain Luku-tila", - "Pages": "Sivut", "set-readonly_description": "Lupa asettaa kanava VainLuku-tilaan", "Settings": "Asetukset", "Settings_updated": "Asetukset päivitetty", diff --git a/packages/i18n/src/locales/fr.i18n.json b/packages/i18n/src/locales/fr.i18n.json index c766001d6f275..9eee83138706e 100644 --- a/packages/i18n/src/locales/fr.i18n.json +++ b/packages/i18n/src/locales/fr.i18n.json @@ -2825,7 +2825,6 @@ "PID": "PID", "Page_URL": "URL de la page", "Page_title": "Titre de la page", - "Pages": "Pages", "Paid_Apps": "Applications payantes", "Parent_channel_doesnt_exist": "Le canal n'existe pas.", "Participants": "Participants", diff --git a/packages/i18n/src/locales/hi-IN.i18n.json b/packages/i18n/src/locales/hi-IN.i18n.json index e598395d668da..4e7e820ba0164 100644 --- a/packages/i18n/src/locales/hi-IN.i18n.json +++ b/packages/i18n/src/locales/hi-IN.i18n.json @@ -4263,7 +4263,6 @@ "Page_not_found": "पृष्ठ नहीं मिला", "set-react-when-readonly_description": "केवल पढ़ने योग्य चैनल में संदेशों पर प्रतिक्रिया करने की क्षमता सेट करने की अनुमति", "set-readonly": "केवल पढ़ने के लिए सेट करें", - "Pages": "पृष्ठों", "set-readonly_description": "किसी चैनल को केवल पढ़ने के लिए चैनल सेट करने की अनुमति", "Settings": "समायोजन", "Settings_updated": "सेटिंग को अद्यतन किया गया है", diff --git a/packages/i18n/src/locales/hu.i18n.json b/packages/i18n/src/locales/hu.i18n.json index 79979192797ca..cd5bd269a8a2d 100644 --- a/packages/i18n/src/locales/hu.i18n.json +++ b/packages/i18n/src/locales/hu.i18n.json @@ -3912,7 +3912,6 @@ "Page_not_found": "Az oldal nem található", "set-react-when-readonly_description": "Jogosultság a csak olvasható csatornában lévő üzenetekre való reagálás képességének beállításához", "set-readonly": "Csak olvasható beállítása", - "Pages": "Oldalak", "set-readonly_description": "Jogosultság egy csatorna csak olvasható csatornára történő beállításához", "Settings": "Beállítások", "Settings_updated": "Beállítások frissítve", diff --git a/packages/i18n/src/locales/ja.i18n.json b/packages/i18n/src/locales/ja.i18n.json index 32b2aacab0c04..a74689f881e8a 100644 --- a/packages/i18n/src/locales/ja.i18n.json +++ b/packages/i18n/src/locales/ja.i18n.json @@ -3554,7 +3554,6 @@ "set-react-when-readonly": "読み取り専用時の応答の設定", "set-react-when-readonly_description": "読み取り専用チャネルのメッセージに応答する機能を設定する権限", "set-readonly": "読み取り専用の設定", - "Pages": "ページ", "set-readonly_description": "チャネルを読み取り専用チャネルに設定する権限", "Settings": "設定", "Settings_updated": "設定を更新しました", diff --git a/packages/i18n/src/locales/nb.i18n.json b/packages/i18n/src/locales/nb.i18n.json index dda09ad8d3dd7..e332454f5628f 100644 --- a/packages/i18n/src/locales/nb.i18n.json +++ b/packages/i18n/src/locales/nb.i18n.json @@ -4618,7 +4618,6 @@ "Page_not_found": "Fant ikke siden", "set-react-when-readonly_description": "Tillatelse til å angi evnen til å reagere på meldinger i en skrivebeskyttet kanal", "set-readonly": "Sett skrivebeskyttet", - "Pages": "Sider", "set-readonly_description": "Tillatelse til å sette en kanal til skrivebeskyttet kanal", "Settings": "Innstillinger", "Parent_channel_or_team": "Foreldrekanal eller team", @@ -6165,7 +6164,6 @@ "You_cant_take_chats_offline": "Du kan ikke ta nye samtaler fordi du er frakoblet", "New_navigation": "Forbedret navigasjonsopplevelse", "New_navigation_description": "Utforsk vår forbedrede navigasjon, designet med ett klart omfang for enkel tilgang til det du trenger. Denne endringen fungerer som grunnlaget for fremtidige fremskritt innen navigasjonsadministrasjon.", - "Workspace_and_user_settings": "Arbeidsområde og brukerinnstillinger", "Sidebar_Sections_Order": "Rekkefølge på sidefeltseksjoner", "Sidebar_Sections_Order_Description": "Velg kategoriene i din foretrukne rekkefølge", "Incoming_Calls": "Innkommende anrop", diff --git a/packages/i18n/src/locales/nl.i18n.json b/packages/i18n/src/locales/nl.i18n.json index d357b71c6c176..f1f8c8cefd0c2 100644 --- a/packages/i18n/src/locales/nl.i18n.json +++ b/packages/i18n/src/locales/nl.i18n.json @@ -3576,7 +3576,6 @@ "set-react-when-readonly": "Stel reageer bij alleen lezen in", "set-react-when-readonly_description": "Toestemming om de mogelijkheid in te stellen om te reageren op berichten in een alleen-lezen kanaal", "set-readonly": "Stel als alleen lezen in", - "Pages": "Pagina's", "set-readonly_description": "Toestemming om een kanaal in te stellen als een alleen-lezen kanaal", "Settings": "Instellingen", "Settings_updated": "Instellingen bijgewerkt", diff --git a/packages/i18n/src/locales/nn.i18n.json b/packages/i18n/src/locales/nn.i18n.json index 14c86c4f6c25c..98835d97e2591 100644 --- a/packages/i18n/src/locales/nn.i18n.json +++ b/packages/i18n/src/locales/nn.i18n.json @@ -4618,7 +4618,6 @@ "Page_not_found": "Fant ikke siden", "set-react-when-readonly_description": "Tillatelse til å angi evnen til å reagere på meldinger i en skrivebeskyttet kanal", "set-readonly": "Still inn ReadOnly", - "Pages": "Sider", "set-readonly_description": "Tillatelse til å angi en kanal for å lese kun kanal", "Settings": "Innstillinger", "Parent_channel_or_team": "Foreldrekanal eller team", @@ -6165,7 +6164,6 @@ "You_cant_take_chats_offline": "Du kan ikke ta nye samtaler fordi du er frakoblet", "New_navigation": "Forbedret navigasjonsopplevelse", "New_navigation_description": "Utforsk vår forbedrede navigasjon, designet med ett klart omfang for enkel tilgang til det du trenger. Denne endringen fungerer som grunnlaget for fremtidige fremskritt innen navigasjonsadministrasjon.", - "Workspace_and_user_settings": "Arbeidsområde og brukerinnstillinger", "Sidebar_Sections_Order": "Rekkefølge på sidefeltseksjoner", "Sidebar_Sections_Order_Description": "Velg kategoriene i din foretrukne rekkefølge", "Incoming_Calls": "Innkommende anrop", diff --git a/packages/i18n/src/locales/pl.i18n.json b/packages/i18n/src/locales/pl.i18n.json index 892961b05ce78..82d9d47d34afe 100644 --- a/packages/i18n/src/locales/pl.i18n.json +++ b/packages/i18n/src/locales/pl.i18n.json @@ -3070,7 +3070,6 @@ "Page_not_exist_or_not_permission": "Strona nie istnieje lub nie masz uprawnień dostępu", "Page_not_found": "Nie znaleziono strony", "Page_title": "Tytuł strony", - "Pages": "Strony", "Paid_Apps": "Aplikacje płatne", "Parent_channel_doesnt_exist": "Channel nie istnieje.", "Participants": "Uczestnicy", diff --git a/packages/i18n/src/locales/pt-BR.i18n.json b/packages/i18n/src/locales/pt-BR.i18n.json index 006928d91cb2f..6ea81f774e4ef 100644 --- a/packages/i18n/src/locales/pt-BR.i18n.json +++ b/packages/i18n/src/locales/pt-BR.i18n.json @@ -2953,7 +2953,6 @@ "PID": "PID", "Page_URL": "URL da página", "Page_title": "Título da página", - "Pages": "Páginas", "Paid_Apps": "Aplicativos pagos", "Parent_channel_doesnt_exist": "Canal não existe.", "Participants": "Participantes", diff --git a/packages/i18n/src/locales/ru.i18n.json b/packages/i18n/src/locales/ru.i18n.json index b7a672c116961..3bdca7393dd22 100644 --- a/packages/i18n/src/locales/ru.i18n.json +++ b/packages/i18n/src/locales/ru.i18n.json @@ -2949,7 +2949,6 @@ "PID": "ИД процесса", "Page_URL": "URL страницы", "Page_title": "Заголовок страницы", - "Pages": "Страницы", "Paid_Apps": "Платные приложения", "Parent_channel_doesnt_exist": "Канал не существует.", "Participants": "Участники", diff --git a/packages/i18n/src/locales/sv.i18n.json b/packages/i18n/src/locales/sv.i18n.json index 6af66935cf7c9..3277f8addcab8 100644 --- a/packages/i18n/src/locales/sv.i18n.json +++ b/packages/i18n/src/locales/sv.i18n.json @@ -4062,7 +4062,6 @@ "Page_not_found": "Sidan hittades inte", "set-react-when-readonly_description": "Tillstånd att ställa in förmågan att reagera på meddelanden i en skrivskyddad kanal", "set-readonly": "Ange skrivskyddat", - "Pages": "Sidor", "set-readonly_description": "Tillstånd att ställa in en kanal för endast läsning", "Settings": "Inställningar", "Settings_updated": "Inställningar uppdaterade",