Prepare field option dropdown for RecordField usage (#13935)

This PR prepares and simplify option dropdown for using record fields.

I had a problem while trying to use currentRecordFields directly with
ordering so I stayed with the actual column definition system.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Lucas Bordeau
2025-08-18 10:34:12 +02:00
committed by GitHub
parent 2894d6f7c2
commit c342ece2ee
8 changed files with 262 additions and 245 deletions
@@ -1,55 +1,17 @@
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { ViewType } from '@/views/types/ViewType';
import { ViewFieldsVisibleDropdownSection } from '@/views/components/ViewFieldsVisibleDropdownSection';
import { useLingui } from '@lingui/react/macro';
import { IconChevronLeft, IconEyeOff } from 'twenty-ui/display';
import { MenuItemNavigate } from 'twenty-ui/navigation';
export const ObjectOptionsDropdownFieldsContent = () => {
const { t } = useLingui();
const {
viewType,
recordIndexId,
objectMetadataItem,
onContentChange,
resetContent,
} = useObjectOptionsDropdown();
const {
handleColumnVisibilityChange,
handleReorderColumns,
visibleTableColumns,
} = useObjectOptionsForTable(recordIndexId, objectMetadataItem.id);
const {
visibleBoardFields,
handleReorderBoardFields,
handleBoardFieldVisibilityChange,
} = useObjectOptionsForBoard({
objectNameSingular: objectMetadataItem.nameSingular,
recordBoardId: recordIndexId,
viewBarId: recordIndexId,
});
const visibleRecordFields =
viewType === ViewType.Kanban ? visibleBoardFields : visibleTableColumns;
const handleReorderFields =
viewType === ViewType.Kanban
? handleReorderBoardFields
: handleReorderColumns;
const handleChangeFieldVisibility =
viewType === ViewType.Kanban
? handleBoardFieldVisibilityChange
: handleColumnVisibilityChange;
const { onContentChange, resetContent } = useObjectOptionsDropdown();
return (
<DropdownContent>
@@ -63,15 +25,7 @@ export const ObjectOptionsDropdownFieldsContent = () => {
>
{t`Fields`}
</DropdownMenuHeader>
<ViewFieldsVisibilityDropdownSection
title={t`Visible`}
fields={visibleRecordFields}
isDraggable
onDragEnd={handleReorderFields}
onVisibilityChange={handleChangeFieldVisibility}
showSubheader={false}
showDragGrip={true}
/>
<ViewFieldsVisibleDropdownSection />
<DropdownMenuSeparator />
<DropdownMenuItemsContainer scrollable={false}>
<MenuItemNavigate
@@ -4,8 +4,6 @@ import { useSetRecoilState } from 'recoil';
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
import { useObjectOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsDropdown';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
import { SettingsPath } from '@/types/SettingsPath';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
@@ -13,8 +11,7 @@ import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { ViewType } from '@/views/types/ViewType';
import { ViewFieldsHiddenDropdownSection } from '@/views/components/ViewFieldsHiddenDropdownSection';
import { useLingui } from '@lingui/react/macro';
import { IconChevronLeft, IconSettings } from 'twenty-ui/display';
import { MenuItem, UndecoratedLink } from 'twenty-ui/navigation';
@@ -22,13 +19,8 @@ import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
export const ObjectOptionsDropdownHiddenFieldsContent = () => {
const { t } = useLingui();
const {
viewType,
recordIndexId,
objectMetadataItem,
onContentChange,
closeDropdown,
} = useObjectOptionsDropdown();
const { objectMetadataItem, onContentChange, closeDropdown } =
useObjectOptionsDropdown();
const { objectNamePlural } = useObjectNamePluralFromSingular({
objectNameSingular: objectMetadataItem.nameSingular,
@@ -38,24 +30,6 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
objectNamePlural,
});
const { handleColumnVisibilityChange, hiddenTableColumns } =
useObjectOptionsForTable(recordIndexId, objectMetadataItem.id);
const { hiddenBoardFields, handleBoardFieldVisibilityChange } =
useObjectOptionsForBoard({
objectNameSingular: objectMetadataItem.nameSingular,
recordBoardId: recordIndexId,
viewBarId: recordIndexId,
});
const hiddenRecordFields =
viewType === ViewType.Kanban ? hiddenBoardFields : hiddenTableColumns;
const handleChangeFieldVisibility =
viewType === ViewType.Kanban
? handleBoardFieldVisibilityChange
: handleColumnVisibilityChange;
const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState(
navigationMemorizedUrlState,
@@ -73,16 +47,7 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
>
{t`Hidden Fields`}
</DropdownMenuHeader>
{hiddenRecordFields.length > 0 && (
<ViewFieldsVisibilityDropdownSection
title={t`Hidden`}
fields={hiddenRecordFields}
isDraggable={false}
onVisibilityChange={handleChangeFieldVisibility}
showSubheader={false}
showDragGrip={false}
/>
)}
<ViewFieldsHiddenDropdownSection />
<DropdownMenuSeparator />
<UndecoratedLink
to={settingsUrl}
@@ -119,9 +119,9 @@ export const useObjectOptionsForBoard = ({
// Let's refactor this as we introduce the new viewBar
const handleBoardFieldVisibilityChange = useCallback(
async (
updatedFieldDefinition: Omit<
updatedFieldDefinition: Pick<
ColumnDefinition<FieldMetadata>,
'size' | 'position'
'fieldMetadataId' | 'isVisible'
>,
) => {
const isNewViewField = !(
@@ -49,7 +49,10 @@ export const useTableColumns = ({
const handleColumnVisibilityChange = useCallback(
async (
viewField: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
viewField: Pick<
ColumnDefinition<FieldMetadata>,
'fieldMetadataId' | 'isVisible'
>,
) => {
const shouldShowColumn = !visibleTableColumns.some(
(visibleColumn) =>