Files
twenty/packages/twenty-front/src/modules/command-menu/pages/navigation-menu-item/components/CommandMenuNewSidebarItemViewPickerSubView.tsx
T
Abdul Rahman 3fb2352c78 Navbar customization followup (#17848)
Addresses review comments from the [first navbar customization
PR](https://github.com/twentyhq/twenty/pull/17728)

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
2026-02-12 02:35:43 +00:00

134 lines
5.2 KiB
TypeScript

import { useLingui } from '@lingui/react/macro';
import { useState } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useIcons } from 'twenty-ui/display';
import { CommandGroup } from '@/command-menu/components/CommandGroup';
import { CommandMenuAddToNavDroppable } from '@/command-menu/components/CommandMenuAddToNavDroppable';
import { CommandMenuItemWithAddToNavigationDrag } from '@/command-menu/components/CommandMenuItemWithAddToNavigationDrag';
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandMenuSubViewWithSearch';
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { useFilteredPickerItems } from '@/command-menu/hooks/useFilteredPickerItems';
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
import { useAddViewToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft';
import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft';
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { type View } from '@/views/types/View';
import { ViewKey } from '@/views/types/ViewKey';
type CommandMenuNewSidebarItemViewPickerSubViewProps = {
selectedObjectMetadataIdForView: string;
onBack: () => void;
};
export const CommandMenuNewSidebarItemViewPickerSubView = ({
selectedObjectMetadataIdForView,
onBack,
}: CommandMenuNewSidebarItemViewPickerSubViewProps) => {
const { t } = useLingui();
const { getIcon } = useIcons();
const [searchValue, setSearchValue] = useState('');
const { closeCommandMenu } = useCommandMenu();
const { addViewToDraft } = useAddViewToNavigationMenuDraft();
const { currentDraft } = useDraftNavigationMenuItems();
const addMenuItemInsertionContext = useRecoilValue(
addMenuItemInsertionContextState,
);
const setAddMenuItemInsertionContext = useSetRecoilState(
addMenuItemInsertionContextState,
);
const { objectMetadataItems } = useObjectMetadataItems();
const { views } = useNavigationMenuObjectMetadataFromDraft(currentDraft);
const viewsForSelectedObject = views
.filter(
(view) =>
view.objectMetadataId === selectedObjectMetadataIdForView &&
view.key !== ViewKey.Index,
)
.sort((a, b) => a.position - b.position);
const selectedObjectMetadataItem = objectMetadataItems.find(
(item) => item.id === selectedObjectMetadataIdForView,
);
const backBarTitle =
selectedObjectMetadataItem?.labelPlural ?? t`Pick a view`;
const {
filteredItems: filteredViews,
selectableItemIds,
isEmpty,
hasSearchQuery,
} = useFilteredPickerItems({
items: viewsForSelectedObject,
searchQuery: searchValue,
getSearchableValues: (view) => [view.name],
});
const noResultsText = hasSearchQuery
? t`No results found`
: t`No custom views available`;
const handleSelectView = (view: View) => {
addViewToDraft(
view.id,
currentDraft,
addMenuItemInsertionContext?.targetFolderId ?? null,
addMenuItemInsertionContext?.targetIndex,
);
setAddMenuItemInsertionContext(null);
closeCommandMenu();
};
return (
<CommandMenuSubViewWithSearch
backBarTitle={backBarTitle}
onBack={onBack}
searchPlaceholder={t`Search a view...`}
searchValue={searchValue}
onSearchChange={setSearchValue}
>
<CommandMenuAddToNavDroppable>
{({ innerRef, droppableProps, placeholder }) => (
<CommandMenuList
commandGroups={[]}
selectableItemIds={selectableItemIds}
noResults={isEmpty}
noResultsText={noResultsText}
>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<div ref={innerRef} {...droppableProps}>
<CommandGroup heading={t`Views`}>
{filteredViews.map((view, index) => (
<SelectableListItem
key={view.id}
itemId={view.id}
onEnter={() => handleSelectView(view)}
>
<CommandMenuItemWithAddToNavigationDrag
icon={getIcon(view.icon)}
label={view.name}
id={view.id}
onClick={() => handleSelectView(view)}
dragIndex={index}
payload={{
type: NavigationMenuItemType.VIEW,
viewId: view.id,
label: view.name,
}}
/>
</SelectableListItem>
))}
</CommandGroup>
{placeholder}
</div>
</CommandMenuList>
)}
</CommandMenuAddToNavDroppable>
</CommandMenuSubViewWithSearch>
);
};