diff --git a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx index 8904961754..af2561a004 100644 --- a/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx +++ b/packages/twenty-front/src/modules/favorites/components/CurrentWorkspaceMemberFavorites.tsx @@ -21,16 +21,18 @@ import { NavigationDrawerInput } from '@/ui/navigation/navigation-drawer/compone import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerItemsCollapsableContainer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemsCollapsableContainer'; import { NavigationDrawerSubItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSubItem'; +import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState'; import { getNavigationSubItemLeftAdornment } from '@/ui/navigation/navigation-drawer/utils/getNavigationSubItemLeftAdornment'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import { Droppable } from '@hello-pangea/dnd'; import { useContext, useState } from 'react'; import { createPortal } from 'react-dom'; import { useLocation } from 'react-router-dom'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; import { IconFolder, IconFolderOpen, IconHeartOff } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; import { AnimatedExpandableContainer } from 'twenty-ui/layout'; +import { useIsMobile } from 'twenty-ui/utilities'; type CurrentWorkspaceMemberFavoritesProps = { folder: { @@ -56,19 +58,30 @@ export const CurrentWorkspaceMemberFavorites = ({ ); const { openModal } = useModal(); + const isMobile = useIsMobile(); + const [openFavoriteFolderIds, setOpenFavoriteFolderIds] = useRecoilState( openFavoriteFolderIdsState, ); + + const setCurrentFolderId = useSetRecoilState(currentFavoriteFolderIdState); + const isOpen = openFavoriteFolderIds.includes(folder.folderId); const handleToggle = () => { - setOpenFavoriteFolderIds((currentOpenFolders) => { - if (isOpen) { - return currentOpenFolders.filter((id) => id !== folder.folderId); - } else { - return [...currentOpenFolders, folder.folderId]; - } - }); + if (isMobile) { + setCurrentFolderId((prev) => + prev === folder.folderId ? null : folder.folderId, + ); + } else { + setOpenFavoriteFolderIds((currentOpenFolders) => { + if (isOpen) { + return currentOpenFolders.filter((id) => id !== folder.folderId); + } else { + return [...currentOpenFolders, folder.folderId]; + } + }); + } }; const { renameFavoriteFolder } = useRenameFavoriteFolder(); @@ -173,6 +186,7 @@ export const CurrentWorkspaceMemberFavorites = ({ className="navigation-drawer-item" isRightOptionsDropdownOpen={isDropdownOpenComponent} triggerEvent="CLICK" + preventCollapseOnMobile={isMobile} /> )} diff --git a/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx b/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx new file mode 100644 index 0000000000..3c0d6c7c54 --- /dev/null +++ b/packages/twenty-front/src/modules/favorites/components/FavoritesBackButton.tsx @@ -0,0 +1,56 @@ +import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState'; +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; +import { useSetRecoilState } from 'recoil'; +import { IconX } from 'twenty-ui/display'; + +const StyledBackButton = styled.button` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing(2)}; + padding-left: ${({ theme }) => theme.spacing(1)}; + padding-right: ${({ theme }) => theme.spacing(0.5)}; + padding-top: ${({ theme }) => theme.spacing(1)}; + padding-bottom: ${({ theme }) => theme.spacing(1)}; + width: 100%; + background: transparent; + border: none; + color: ${({ theme }) => theme.font.color.secondary}; + font-weight: ${({ theme }) => theme.font.weight.medium}; + font-family: ${({ theme }) => theme.font.family}; + cursor: pointer; + text-align: left; + + &:hover { + background: ${({ theme }) => theme.background.transparent.light}; + border-radius: ${({ theme }) => theme.border.radius.sm}; + } +`; + +type FavoritesBackButtonProps = { + folderName: string; +}; + +export const FavoritesBackButton = ({ + folderName, +}: FavoritesBackButtonProps) => { + const theme = useTheme(); + const setCurrentFolderId = useSetRecoilState(currentFavoriteFolderIdState); + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + setCurrentFolderId(null); + }; + + return ( + + + {folderName} + + ); +}; diff --git a/packages/twenty-front/src/modules/favorites/components/FavoritesFolderContent.tsx b/packages/twenty-front/src/modules/favorites/components/FavoritesFolderContent.tsx new file mode 100644 index 0000000000..d07c73d3e3 --- /dev/null +++ b/packages/twenty-front/src/modules/favorites/components/FavoritesFolderContent.tsx @@ -0,0 +1,74 @@ +import { FavoriteIcon } from '@/favorites/components/FavoriteIcon'; +import { FavoritesBackButton } from '@/favorites/components/FavoritesBackButton'; +import { FavoritesDragProvider } from '@/favorites/components/FavoritesDragProvider'; +import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite'; +import { getFavoriteSecondaryLabel } from '@/favorites/utils/getFavoriteSecondaryLabel'; +import { type ProcessedFavorite } from '@/favorites/utils/sortFavorites'; +import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; +import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem'; +import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import { Droppable } from '@hello-pangea/dnd'; +import { useRecoilValue } from 'recoil'; +import { IconHeartOff } from 'twenty-ui/display'; +import { LightIconButton } from 'twenty-ui/input'; + +type FavoritesFolderContentProps = { + folderId: string; + folderName: string; + favorites: ProcessedFavorite[]; +}; + +export const FavoritesFolderContent = ({ + folderName, + folderId, + favorites, +}: FavoritesFolderContentProps) => { + const objectMetadataItems = useRecoilValue(objectMetadataItemsState); + const { deleteFavorite } = useDeleteFavorite(); + + return ( + <> + + + + {(provided) => ( + + {favorites.map((favorite, index) => ( + } + rightOptions={ + deleteFavorite(favorite.id)} + accent="tertiary" + /> + } + triggerEvent="CLICK" + to={favorite.link} + /> + } + /> + ))} + {provided.placeholder} + + )} + + + > + ); +}; diff --git a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx index 92f8460901..3ec988e5f4 100644 --- a/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx +++ b/packages/twenty-front/src/modules/navigation/components/MainNavigationDrawer.tsx @@ -1,15 +1,23 @@ import { useRecoilValue } from 'recoil'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; +import { FavoritesFolderContent } from '@/favorites/components/FavoritesFolderContent'; +import { useFavoritesByFolder } from '@/favorites/hooks/useFavoritesByFolder'; import { MainNavigationDrawerFixedItems } from '@/navigation/components/MainNavigationDrawerFixedItems'; import { MainNavigationDrawerScrollableItems } from '@/navigation/components/MainNavigationDrawerScrollableItems'; import { SupportDropdown } from '@/support/components/SupportDropdown'; import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer'; import { NavigationDrawerFixedContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerFixedContent'; import { NavigationDrawerScrollableContent } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerScrollableContent'; +import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState'; export const MainNavigationDrawer = ({ className }: { className?: string }) => { const currentWorkspace = useRecoilValue(currentWorkspaceState); + const currentFavoriteFolderId = useRecoilValue(currentFavoriteFolderIdState); + const { favoritesByFolder } = useFavoritesByFolder(); + const openedFolder = favoritesByFolder.find( + (f) => f.folderId === currentFavoriteFolderId, + ); return ( { - + {currentFavoriteFolderId && openedFolder ? ( + + ) : ( + + )} diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx index eb493f584c..6e92b78ea1 100644 --- a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx @@ -51,6 +51,7 @@ export type NavigationDrawerItemProps = { isRightOptionsDropdownOpen?: boolean; triggerEvent?: TriggerEventType; mouseUpNavigation?: boolean; + preventCollapseOnMobile?: boolean; }; type StyledItemProps = Pick< @@ -267,6 +268,7 @@ export const NavigationDrawerItem = ({ isRightOptionsDropdownOpen, triggerEvent, mouseUpNavigation = false, + preventCollapseOnMobile = false, }: NavigationDrawerItemProps) => { const theme = useTheme(); const isMobile = useIsMobile(); @@ -282,7 +284,7 @@ export const NavigationDrawerItem = ({ ); const handleMobileNavigation = () => { - if (isMobile) { + if (isMobile && !preventCollapseOnMobile) { setIsNavigationDrawerExpanded(false); } }; diff --git a/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState.ts b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState.ts new file mode 100644 index 0000000000..79c5a59b78 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState.ts @@ -0,0 +1,6 @@ +import { atom } from 'recoil'; + +export const currentFavoriteFolderIdState = atom({ + key: 'currentFavoriteFolderIdState', + default: null, +});