[feature]:Improved Options Menu for Default View (#13427)

**Feature** - Improved Options Menu for Default View

**Closes** - #13306

**Description** 

This PR fixes the feature request of Better Options in the Default View.
Added the option of Create a Custom View in the Options, this helps user
create custom views.


**Working Demo** 


https://github.com/user-attachments/assets/32a3f264-c4a0-42aa-9257-56a407ea3c6e

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Priyansh Verma
2025-08-20 18:09:22 +02:00
committed by GitHub
co-authored by Lucas Bordeau
parent f72c3d73bf
commit ff3f1d945c
7 changed files with 425 additions and 212 deletions
@@ -0,0 +1,239 @@
import { ObjectOptionsDropdownMenuViewName } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName';
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { useDeleteViewFromCurrentState } from '@/views/view-picker/hooks/useDeleteViewFromCurrentState';
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import { capitalize, isDefined } from 'twenty-shared/utils';
import {
AppTooltip,
IconCopy,
IconLayoutList,
IconListDetails,
IconTrash,
} from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
interface ObjectOptionsDropdownCustomViewProps {
onBackToDefault?: () => void;
}
export const ObjectOptionsDropdownCustomView = ({
onBackToDefault,
}: ObjectOptionsDropdownCustomViewProps) => {
const { t } = useLingui();
const { recordIndexId, objectMetadataItem, onContentChange, closeDropdown } =
useObjectOptionsDropdown();
const { currentView } = useGetCurrentViewOnly();
const customViewData = currentView
? {
...currentView,
key: ViewKey.Custom,
name: currentView.name || 'Custom View',
}
: null;
const recordGroupFieldMetadata = useRecoilComponentValue(
recordGroupFieldMetadataComponentState,
);
const isDefaultView = currentView?.key === ViewKey.Index;
const { visibleBoardFields } = useObjectOptionsForBoard({
objectNameSingular: objectMetadataItem.nameSingular,
recordBoardId: recordIndexId,
viewBarId: recordIndexId,
});
const { deleteViewFromCurrentState } = useDeleteViewFromCurrentState();
const setViewPickerReferenceViewId = useSetRecoilComponentState(
viewPickerReferenceViewIdComponentState,
);
const handleDelete = () => {
if (!customViewData?.id) {
return;
}
setViewPickerReferenceViewId(customViewData?.id);
deleteViewFromCurrentState();
closeDropdown();
onBackToDefault?.();
};
const theme = useTheme();
const { enqueueSuccessSnackBar } = useSnackBar();
const selectableItemIdArray = [
'Layout',
'Fields',
'Group',
'Copy link to view',
'Delete view',
];
const selectedItemId = useRecoilComponentValue(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
if (!customViewData) {
return null;
}
return (
<DropdownContent>
<ObjectOptionsDropdownMenuViewName currentView={customViewData} />
<DropdownMenuSeparator />
<SelectableList
selectableListInstanceId={OBJECT_OPTIONS_DROPDOWN_ID}
focusId={OBJECT_OPTIONS_DROPDOWN_ID}
selectableItemIdArray={selectableItemIdArray}
>
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Layout"
onEnter={() => onContentChange('layout')}
>
<MenuItem
focused={selectedItemId === 'Layout'}
onClick={() => onContentChange('layout')}
LeftIcon={viewTypeIconMapping(
customViewData?.type ?? ViewType.Table,
)}
text={t`Layout`}
contextualText={`${capitalize(customViewData?.type ?? '')}`}
hasSubMenu
/>
</SelectableListItem>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Fields"
onEnter={() => onContentChange('fields')}
>
<MenuItem
focused={selectedItemId === 'Fields'}
onClick={() => onContentChange('fields')}
LeftIcon={IconListDetails}
text={t`Fields`}
contextualText={`${visibleBoardFields.length} shown`}
hasSubMenu
/>
</SelectableListItem>
<div id="group-by-menu-item">
<SelectableListItem
itemId="Group"
onEnter={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
>
<MenuItem
focused={selectedItemId === 'Group'}
onClick={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
LeftIcon={IconLayoutList}
text={t`Group`}
contextualText={
isDefaultView
? t`Not available on Default View`
: recordGroupFieldMetadata?.label
}
hasSubMenu
disabled={isDefaultView}
/>
</SelectableListItem>
</div>
{isDefaultView && (
<AppTooltip
anchorSelect={`#group-by-menu-item`}
content={t`Not available on Default View`}
noArrow
place="bottom"
width="100%"
/>
)}
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Copy link to view"
onEnter={() => {
const currentUrl = window.location.href;
navigator.clipboard.writeText(currentUrl);
enqueueSuccessSnackBar({
message: t`Link copied to clipboard`,
options: {
icon: <IconCopy size={theme.icon.size.md} />,
duration: 2000,
},
});
}}
>
<MenuItem
focused={selectedItemId === 'Copy link to view'}
onClick={() => {
const currentUrl = window.location.href;
navigator.clipboard.writeText(currentUrl);
enqueueSuccessSnackBar({
message: t`Link copied to clipboard`,
options: {
icon: <IconCopy size={theme.icon.size.md} />,
duration: 2000,
},
});
}}
LeftIcon={IconCopy}
text={t`Copy link to view`}
/>
</SelectableListItem>
<div id="delete-view-menu-item">
<SelectableListItem
itemId="Delete view"
onEnter={() => handleDelete()}
>
<MenuItem
focused={selectedItemId === 'Delete view'}
onClick={() => handleDelete()}
LeftIcon={IconTrash}
text={t`Delete view`}
disabled={isDefaultView}
/>
</SelectableListItem>
</div>
{isDefaultView && (
<AppTooltip
anchorSelect={`#delete-view-menu-item`}
content={t`Not available on Default View`}
noArrow
place="bottom"
width="100%"
/>
)}
</DropdownMenuItemsContainer>
</SelectableList>
</DropdownContent>
);
};
@@ -0,0 +1,128 @@
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useOpenCreateViewDropdown } from '@/views/hooks/useOpenCreateViewDropown';
import { useLingui } from '@lingui/react/macro';
import {
IconCopy,
IconLayout,
IconListDetails,
IconLock,
useIcons,
} from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
export const ObjectOptionsDropdownDefaultView = () => {
const { t } = useLingui();
const { recordIndexId, objectMetadataItem, onContentChange } =
useObjectOptionsDropdown();
const { currentView } = useGetCurrentViewOnly();
const { visibleBoardFields } = useObjectOptionsForBoard({
objectNameSingular: objectMetadataItem.nameSingular,
recordBoardId: recordIndexId,
viewBarId: recordIndexId,
});
const selectableItemIdArray = [
'Fields',
'Copy link to view',
'Create custom view',
];
const selectedItemId = useRecoilComponentValue(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
const { openCreateViewDropdown } = useOpenCreateViewDropdown(recordIndexId);
const { closeDropdown } = useCloseDropdown();
const handleCreateCustomView = () => {
closeDropdown(OBJECT_OPTIONS_DROPDOWN_ID);
openCreateViewDropdown(currentView);
};
const { copyToClipboard } = useCopyToClipboard();
const { getIcon } = useIcons();
const MainIcon = getIcon(currentView?.icon);
return (
<DropdownContent>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
text={t`Default View`}
LeftIcon={MainIcon}
RightIcon={IconLock}
disabled={true}
/>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<SelectableList
selectableListInstanceId={OBJECT_OPTIONS_DROPDOWN_ID}
focusId={OBJECT_OPTIONS_DROPDOWN_ID}
selectableItemIdArray={selectableItemIdArray}
>
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Fields"
onEnter={() => onContentChange('fields')}
>
<MenuItem
focused={selectedItemId === 'Fields'}
onClick={() => onContentChange('fields')}
LeftIcon={IconListDetails}
text={t`Fields`}
contextualText={`${visibleBoardFields.length} shown`}
hasSubMenu
/>
</SelectableListItem>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Copy link to view"
onEnter={() => {
const currentUrl = window.location.href;
copyToClipboard(currentUrl, t`Link copied to clipboard`);
}}
>
<MenuItem
focused={selectedItemId === 'Copy link to view'}
onClick={() => {
const currentUrl = window.location.href;
copyToClipboard(currentUrl, t`Link copied to clipboard`);
}}
LeftIcon={IconCopy}
text={t`Copy link to view`}
/>
</SelectableListItem>
<SelectableListItem
itemId="Create custom view"
onEnter={handleCreateCustomView}
>
<MenuItem
focused={selectedItemId === 'Create custom view'}
onClick={handleCreateCustomView}
LeftIcon={IconLayout}
text={t`Create custom view`}
/>
</SelectableListItem>
</DropdownMenuItemsContainer>
</SelectableList>
</DropdownContent>
);
};
@@ -1,208 +1,16 @@
import { ObjectOptionsDropdownMenuViewName } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName';
import { OBJECT_OPTIONS_DROPDOWN_ID } from '@/object-record/object-options-dropdown/constants/ObjectOptionsDropdownId';
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { ObjectOptionsDropdownCustomView } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView';
import { ObjectOptionsDropdownDefaultView } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
import { useDeleteViewFromCurrentState } from '@/views/view-picker/hooks/useDeleteViewFromCurrentState';
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
import { useLingui } from '@lingui/react/macro';
import { capitalize, isDefined } from 'twenty-shared/utils';
import {
AppTooltip,
IconCopy,
IconLayoutList,
IconListDetails,
IconTrash,
} from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
import { ViewKey } from '@/views/types/ViewKey';
export const ObjectOptionsDropdownMenuContent = () => {
const { t } = useLingui();
const { recordIndexId, objectMetadataItem, onContentChange, closeDropdown } =
useObjectOptionsDropdown();
const { currentView } = useGetCurrentViewOnly();
const recordGroupFieldMetadata = useRecoilComponentValue(
recordGroupFieldMetadataComponentState,
);
const isDefaultView = currentView?.key === ViewKey.Index;
const isGroupByEnabled =
(isDefined(currentView?.viewGroups) && currentView.viewGroups.length > 0) ||
currentView?.key !== 'INDEX';
if (isDefaultView) {
return <ObjectOptionsDropdownDefaultView />;
}
const { visibleBoardFields } = useObjectOptionsForBoard({
objectNameSingular: objectMetadataItem.nameSingular,
recordBoardId: recordIndexId,
viewBarId: recordIndexId,
});
const { deleteViewFromCurrentState } = useDeleteViewFromCurrentState();
const setViewPickerReferenceViewId = useSetRecoilComponentState(
viewPickerReferenceViewIdComponentState,
);
const handleDelete = () => {
if (!currentView?.id) {
return;
}
setViewPickerReferenceViewId(currentView?.id);
deleteViewFromCurrentState();
closeDropdown();
};
const isDefaultView = currentView?.key === 'INDEX';
const selectableItemIdArray = [
'Layout',
'Fields',
...(isDefaultView ? [] : ['Group']),
'Copy link to view',
...(isDefaultView ? [] : ['Delete view']),
];
const selectedItemId = useRecoilComponentValue(
selectedItemIdComponentState,
OBJECT_OPTIONS_DROPDOWN_ID,
);
const { copyToClipboard } = useCopyToClipboard();
return (
<DropdownContent>
{currentView && (
<ObjectOptionsDropdownMenuViewName currentView={currentView} />
)}
<DropdownMenuSeparator />
<SelectableList
selectableListInstanceId={OBJECT_OPTIONS_DROPDOWN_ID}
focusId={OBJECT_OPTIONS_DROPDOWN_ID}
selectableItemIdArray={selectableItemIdArray}
>
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Layout"
onEnter={() => onContentChange('layout')}
>
<MenuItem
focused={selectedItemId === 'Layout'}
onClick={() => onContentChange('layout')}
LeftIcon={viewTypeIconMapping(
currentView?.type ?? ViewType.Table,
)}
text={t`Layout`}
contextualText={`${capitalize(currentView?.type ?? '')}`}
hasSubMenu
/>
</SelectableListItem>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Fields"
onEnter={() => onContentChange('fields')}
>
<MenuItem
focused={selectedItemId === 'Fields'}
onClick={() => onContentChange('fields')}
LeftIcon={IconListDetails}
text={t`Fields`}
contextualText={`${visibleBoardFields.length} shown`}
hasSubMenu
/>
</SelectableListItem>
<div id="group-by-menu-item">
<SelectableListItem
itemId="Group"
onEnter={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
>
<MenuItem
focused={selectedItemId === 'Group'}
onClick={() =>
isDefined(recordGroupFieldMetadata)
? onContentChange('recordGroups')
: onContentChange('recordGroupFields')
}
LeftIcon={IconLayoutList}
text={t`Group`}
contextualText={
isDefaultView
? t`Not available on Default View`
: recordGroupFieldMetadata?.label
}
hasSubMenu
disabled={isDefaultView}
/>
</SelectableListItem>
</div>
{!isGroupByEnabled && (
<AppTooltip
anchorSelect={`#group-by-menu-item`}
content={t`Not available on Default View`}
noArrow
place="bottom"
width="100%"
/>
)}
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<SelectableListItem
itemId="Copy link to view"
onEnter={() => {
const currentUrl = window.location.href;
copyToClipboard(currentUrl, t`Link copied to clipboard`);
}}
>
<MenuItem
focused={selectedItemId === 'Copy link to view'}
onClick={() => {
const currentUrl = window.location.href;
copyToClipboard(currentUrl, t`Link copied to clipboard`);
}}
LeftIcon={IconCopy}
text={t`Copy link to view`}
/>
</SelectableListItem>
<div id="delete-view-menu-item">
<SelectableListItem
itemId="Delete view"
onEnter={() => handleDelete()}
>
<MenuItem
focused={selectedItemId === 'Delete view'}
onClick={() => handleDelete()}
LeftIcon={IconTrash}
text={t`Delete view`}
disabled={currentView?.key === 'INDEX'}
/>
</SelectableListItem>
</div>
{currentView?.key === 'INDEX' && (
<AppTooltip
anchorSelect={`#delete-view-menu-item`}
content={t`Not available on Default View`}
noArrow
place="bottom"
width="100%"
/>
)}
</DropdownMenuItemsContainer>
</SelectableList>
</DropdownContent>
);
return <ObjectOptionsDropdownCustomView />;
};
@@ -1,5 +1,3 @@
import { Key } from 'ts-key-enum';
import { useUpdateObjectViewOptions } from '@/object-record/object-options-dropdown/hooks/useUpdateObjectViewOptions';
import { IconPicker } from '@/ui/input/components/IconPicker';
import { TextInput } from '@/ui/input/components/TextInput';
@@ -16,7 +14,8 @@ import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { Key } from 'ts-key-enum';
import { OverflowingTextWithTooltip, useIcons } from 'twenty-ui/display';
import { useDebouncedCallback } from 'use-debounce';
@@ -43,6 +42,7 @@ const StyledMenuIconContainer = styled.div`
justify-content: center;
width: ${({ theme }) => theme.spacing(6)};
`;
const StyledMainText = styled.div`
color: ${({ theme }) => theme.font.color.primary};
flex-shrink: 0;
@@ -75,6 +75,8 @@ export const ObjectOptionsDropdownMenuViewName = ({
const { updateViewFromCurrentState } = useUpdateViewFromCurrentState();
const [viewName, setViewName] = useState(currentView?.name);
const inputRef = useRef<HTMLInputElement>(null);
useHotkeysOnFocusedElement({
keys: [Key.Enter],
callback: async () => {
@@ -102,23 +104,28 @@ export const ObjectOptionsDropdownMenuViewName = ({
setViewPickerSelectedIcon(currentView.icon);
}, [currentView.icon, setViewPickerSelectedIcon]);
useEffect(() => {
if (currentView?.key !== 'INDEX' && inputRef.current !== null) {
inputRef.current.focus();
}
}, [currentView?.key]);
const theme = useTheme();
const { getIcon } = useIcons();
const MainIcon = getIcon(currentView?.icon);
return (
<>
{currentView?.key === 'INDEX' && (
{currentView?.key === 'INDEX' ? (
<StyledMenuTitleContainer>
<StyledMenuIconContainer>
<MainIcon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />
</StyledMenuIconContainer>
<StyledMainText>
<OverflowingTextWithTooltip text={currentView?.name} />
<OverflowingTextWithTooltip text={currentView.name} />
</StyledMainText>
</StyledMenuTitleContainer>
)}
{currentView?.key !== 'INDEX' && (
) : (
<DropdownMenuItemsContainer>
<StyledDropdownMenuIconAndNameContainer>
<IconPicker
@@ -0,0 +1,31 @@
import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { type View } from '@/views/types/View';
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
import { isDefined } from 'twenty-shared/utils';
export const useOpenCreateViewDropdown = (viewBardId?: string) => {
const setViewPickerReferenceViewId = useSetRecoilComponentState(
viewPickerReferenceViewIdComponentState,
viewBardId,
);
const { setViewPickerMode } = useViewPickerMode(viewBardId);
const { openDropdown } = useOpenDropdown();
const openCreateViewDropdown = (referenceView: View | undefined) => {
if (isDefined(referenceView?.id)) {
setViewPickerReferenceViewId(referenceView.id);
setViewPickerMode('create-empty');
openDropdown({
dropdownComponentInstanceIdFromProps: VIEW_PICKER_DROPDOWN_ID,
});
}
};
return { openCreateViewDropdown };
};
@@ -1,3 +1,4 @@
export enum ViewKey {
Index = 'INDEX',
Custom = 'CUSTOM',
}
@@ -13,6 +13,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { useChangeView } from '@/views/hooks/useChangeView';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useOpenCreateViewDropdown } from '@/views/hooks/useOpenCreateViewDropown';
import { useUpdateView } from '@/views/hooks/useUpdateView';
import { ViewPickerOptionDropdown } from '@/views/view-picker/components/ViewPickerOptionDropdown';
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
@@ -20,7 +21,6 @@ import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
import { useLingui } from '@lingui/react/macro';
import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { IconPlus } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { moveArrayItem } from '~/utils/array/moveArrayItem';
@@ -58,11 +58,10 @@ export const ViewPickerListContent = () => {
closeDropdown(VIEW_PICKER_DROPDOWN_ID);
};
const { openCreateViewDropdown } = useOpenCreateViewDropdown();
const handleAddViewButtonClick = () => {
if (isDefined(currentView?.id)) {
setViewPickerReferenceViewId(currentView.id);
setViewPickerMode('create-empty');
}
openCreateViewDropdown(currentView);
};
const handleEditViewButtonClick = (