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:
@@ -27,7 +27,7 @@ Having a list that is draggable will be useful, not only in dropdown.
|
||||
|
||||
Create a folder @/ui/draggable-list with a DraggableList component
|
||||
This component should take as prop: itemsComponents, onDragEnd((previousIndex, nextIndex) => {})
|
||||
Use this component in ViewFieldsVisibilityDropdownSection (move the logic from ViewFieldsVisibilityDropdownSection to DraggableList) by passing a list of DraggableMenuItems
|
||||
Use this component in ObjectOptionsDropdownHiddenFieldsContent (move the logic from ObjectOptionsDropdownHiddenFieldsContent to DraggableList) by passing a list of DraggableMenuItems
|
||||
Add a storybook test on this list (we don't know how to actually test the draggable behavior, but we can at least make sure the component renders correctly a list of items)
|
||||
```
|
||||
|
||||
|
||||
+3
-49
@@ -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
-39
@@ -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}
|
||||
|
||||
+2
-2
@@ -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 = !(
|
||||
|
||||
+4
-1
@@ -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) =>
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
import { type DropResult, type ResponderProvided } from '@hello-pangea/dnd';
|
||||
|
||||
import { useActiveFieldMetadataItems } from '@/object-metadata/hooks/useActiveFieldMetadataItems';
|
||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
||||
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
|
||||
import { currentRecordFieldsComponentState } from '@/object-record/record-field/states/currentRecordFieldsComponentState';
|
||||
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
|
||||
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { useContext } from 'react';
|
||||
import { IconEye, useIcons } from 'twenty-ui/display';
|
||||
import { MenuItemDraggable } from 'twenty-ui/navigation';
|
||||
|
||||
export const ViewFieldsHiddenDropdownSection = () => {
|
||||
const { viewType, objectMetadataItem, recordIndexId } = useContext(
|
||||
ObjectOptionsDropdownContext,
|
||||
);
|
||||
|
||||
const { handleReorderColumns, handleColumnVisibilityChange } =
|
||||
useObjectOptionsForTable(recordIndexId, objectMetadataItem.id);
|
||||
|
||||
const { handleReorderBoardFields, handleBoardFieldVisibilityChange } =
|
||||
useObjectOptionsForBoard({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
recordBoardId: recordIndexId,
|
||||
viewBarId: recordIndexId,
|
||||
});
|
||||
|
||||
const handleReorderFields =
|
||||
viewType === ViewType.Kanban
|
||||
? handleReorderBoardFields
|
||||
: handleReorderColumns;
|
||||
|
||||
const handleChangeFieldVisibility =
|
||||
viewType === ViewType.Kanban
|
||||
? handleBoardFieldVisibilityChange
|
||||
: handleColumnVisibilityChange;
|
||||
|
||||
const handleDragEnd = (result: DropResult, provided: ResponderProvided) => {
|
||||
handleReorderFields(result, provided);
|
||||
};
|
||||
|
||||
const currentRecordFields = useRecoilComponentValue(
|
||||
currentRecordFieldsComponentState,
|
||||
);
|
||||
|
||||
const visibleRecordFields = currentRecordFields.filter(
|
||||
(recordFieldToFilter) => recordFieldToFilter.isVisible === true,
|
||||
);
|
||||
|
||||
const { activeFieldMetadataItems } = useActiveFieldMetadataItems({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const availableFieldMetadataItemsToShow = activeFieldMetadataItems.filter(
|
||||
(fieldMetadataItemToFilter) =>
|
||||
!visibleRecordFields
|
||||
.map((recordField) => recordField.fieldMetadataItemId)
|
||||
.includes(fieldMetadataItemToFilter.id),
|
||||
);
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenuItemsContainer>
|
||||
{availableFieldMetadataItemsToShow.length > 0 && (
|
||||
<DraggableList
|
||||
onDragEnd={handleDragEnd}
|
||||
draggableItems={
|
||||
<>
|
||||
{availableFieldMetadataItemsToShow.map(
|
||||
(fieldMetadataItem, index) => {
|
||||
const fieldIndex = index;
|
||||
|
||||
return (
|
||||
<DraggableItem
|
||||
key={fieldMetadataItem.id}
|
||||
draggableId={fieldMetadataItem.id}
|
||||
index={fieldIndex + 1}
|
||||
itemComponent={
|
||||
<MenuItemDraggable
|
||||
key={fieldMetadataItem.id}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
iconButtons={[
|
||||
{
|
||||
Icon: IconEye,
|
||||
onClick: () =>
|
||||
handleChangeFieldVisibility({
|
||||
fieldMetadataId: fieldMetadataItem.id,
|
||||
isVisible: false,
|
||||
}),
|
||||
},
|
||||
]}
|
||||
text={fieldMetadataItem.label}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
import {
|
||||
type DropResult,
|
||||
type OnDragEndResponder,
|
||||
type ResponderProvided,
|
||||
} from '@hello-pangea/dnd';
|
||||
import { useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { type ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
|
||||
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { StyledDropdownMenuSubheader } from '@/ui/layout/dropdown/components/StyledDropdownMenuSubheader';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
AppTooltip,
|
||||
IconEye,
|
||||
IconEyeOff,
|
||||
IconInfoCircle,
|
||||
useIcons,
|
||||
} from 'twenty-ui/display';
|
||||
import { MenuItemDraggable } from 'twenty-ui/navigation';
|
||||
import { groupArrayItemsBy } from '~/utils/array/groupArrayItemsBy';
|
||||
|
||||
type ViewFieldsVisibilityDropdownSectionProps = {
|
||||
fields: Omit<ColumnDefinition<FieldMetadata>, 'size'>[];
|
||||
isDraggable: boolean;
|
||||
onDragEnd?: OnDragEndResponder;
|
||||
onVisibilityChange: (
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => void;
|
||||
title: string;
|
||||
showSubheader: boolean;
|
||||
showDragGrip: boolean;
|
||||
};
|
||||
|
||||
export const ViewFieldsVisibilityDropdownSection = ({
|
||||
fields,
|
||||
isDraggable,
|
||||
onDragEnd,
|
||||
onVisibilityChange,
|
||||
title,
|
||||
showSubheader = true,
|
||||
showDragGrip,
|
||||
}: ViewFieldsVisibilityDropdownSectionProps) => {
|
||||
const handleOnDrag = (result: DropResult, provided: ResponderProvided) => {
|
||||
onDragEnd?.(result, provided);
|
||||
};
|
||||
|
||||
const [openToolTipIndex, setOpenToolTipIndex] = useState<number>();
|
||||
|
||||
const handleInfoButtonClick = (index: number) => {
|
||||
setOpenToolTipIndex(index === openToolTipIndex ? undefined : index);
|
||||
};
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const getIconButtons = (
|
||||
index: number,
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => {
|
||||
const iconButtons = [
|
||||
field.infoTooltipContent
|
||||
? {
|
||||
Icon: IconInfoCircle,
|
||||
onClick: () => handleInfoButtonClick(index),
|
||||
isActive: openToolTipIndex === index,
|
||||
}
|
||||
: null,
|
||||
field.isLabelIdentifier
|
||||
? null
|
||||
: {
|
||||
Icon: field.isVisible ? IconEyeOff : IconEye,
|
||||
onClick: () => onVisibilityChange(field),
|
||||
},
|
||||
].filter(isDefined);
|
||||
|
||||
return iconButtons.length ? iconButtons : undefined;
|
||||
};
|
||||
|
||||
const { nonDraggableItems = [], draggableItems = [] } = isDraggable
|
||||
? groupArrayItemsBy(fields, ({ isLabelIdentifier }) =>
|
||||
isLabelIdentifier ? 'nonDraggableItems' : 'draggableItems',
|
||||
)
|
||||
: { nonDraggableItems: fields, draggableItems: [] };
|
||||
|
||||
return (
|
||||
<>
|
||||
{showSubheader && (
|
||||
<StyledDropdownMenuSubheader>{title}</StyledDropdownMenuSubheader>
|
||||
)}
|
||||
<DropdownMenuItemsContainer>
|
||||
{nonDraggableItems.map((field, fieldIndex) => (
|
||||
<MenuItemDraggable
|
||||
key={field.fieldMetadataId}
|
||||
LeftIcon={getIcon(field.iconName)}
|
||||
iconButtons={getIconButtons(fieldIndex, field)}
|
||||
isTooltipOpen={openToolTipIndex === fieldIndex}
|
||||
text={field.label}
|
||||
className={`${title}-fixed-item-tooltip-anchor-${fieldIndex}`}
|
||||
accent={showDragGrip ? 'placeholder' : 'default'}
|
||||
showGrip={showDragGrip}
|
||||
isDragDisabled
|
||||
/>
|
||||
))}
|
||||
{!!draggableItems.length && (
|
||||
<DraggableList
|
||||
onDragEnd={handleOnDrag}
|
||||
draggableItems={
|
||||
<>
|
||||
{draggableItems.map((field, index) => {
|
||||
const fieldIndex = index + nonDraggableItems.length;
|
||||
|
||||
return (
|
||||
<DraggableItem
|
||||
key={field.fieldMetadataId}
|
||||
draggableId={field.fieldMetadataId}
|
||||
index={fieldIndex + 1}
|
||||
itemComponent={
|
||||
<MenuItemDraggable
|
||||
key={field.fieldMetadataId}
|
||||
LeftIcon={getIcon(field.iconName)}
|
||||
iconButtons={getIconButtons(fieldIndex, field)}
|
||||
isTooltipOpen={openToolTipIndex === fieldIndex}
|
||||
text={field.label}
|
||||
className={`${title}-draggable-item-tooltip-anchor-${fieldIndex}`}
|
||||
showGrip
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
{isDefined(openToolTipIndex) &&
|
||||
createPortal(
|
||||
<AppTooltip
|
||||
anchorSelect={`.${title}-${
|
||||
isDraggable ? 'draggable' : 'fixed'
|
||||
}-item-tooltip-anchor-${openToolTipIndex}`}
|
||||
place="left"
|
||||
content={fields[openToolTipIndex].infoTooltipContent}
|
||||
hidden={false}
|
||||
/>,
|
||||
document.body,
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
import { type DropResult, type ResponderProvided } from '@hello-pangea/dnd';
|
||||
|
||||
import { useGetFieldMetadataItemById } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||
import { useObjectOptionsForTable } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForTable';
|
||||
import { ObjectOptionsDropdownContext } from '@/object-record/object-options-dropdown/states/contexts/ObjectOptionsDropdownContext';
|
||||
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
|
||||
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconEyeOff, useIcons } from 'twenty-ui/display';
|
||||
import { MenuItemDraggable } from 'twenty-ui/navigation';
|
||||
import { sortByProperty } from '~/utils/array/sortByProperty';
|
||||
|
||||
export const ViewFieldsVisibleDropdownSection = () => {
|
||||
const { viewType, objectMetadataItem, recordIndexId } = useContext(
|
||||
ObjectOptionsDropdownContext,
|
||||
);
|
||||
|
||||
const {
|
||||
handleReorderColumns,
|
||||
handleColumnVisibilityChange,
|
||||
visibleTableColumns,
|
||||
} = useObjectOptionsForTable(recordIndexId, objectMetadataItem.id);
|
||||
|
||||
const {
|
||||
handleReorderBoardFields,
|
||||
handleBoardFieldVisibilityChange,
|
||||
visibleBoardFields,
|
||||
} = useObjectOptionsForBoard({
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
recordBoardId: recordIndexId,
|
||||
viewBarId: recordIndexId,
|
||||
});
|
||||
|
||||
const visibleRecordFields =
|
||||
viewType === ViewType.Kanban ? visibleBoardFields : visibleTableColumns;
|
||||
|
||||
const { getFieldMetadataItemById } = useGetFieldMetadataItemById();
|
||||
|
||||
const handleReorderFields =
|
||||
viewType === ViewType.Kanban
|
||||
? handleReorderBoardFields
|
||||
: handleReorderColumns;
|
||||
|
||||
const handleChangeFieldVisibility =
|
||||
viewType === ViewType.Kanban
|
||||
? handleBoardFieldVisibilityChange
|
||||
: handleColumnVisibilityChange;
|
||||
|
||||
const handleDragEnd = (result: DropResult, provided: ResponderProvided) => {
|
||||
handleReorderFields(result, provided);
|
||||
};
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const fieldMetadataItemLabelIdentifier =
|
||||
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
|
||||
|
||||
const nonDraggableRecordField = visibleRecordFields.find(
|
||||
(recordFieldToFilter) =>
|
||||
recordFieldToFilter.fieldMetadataId ===
|
||||
fieldMetadataItemLabelIdentifier?.id,
|
||||
);
|
||||
|
||||
const draggableRecordFields = visibleRecordFields
|
||||
.filter(
|
||||
(recordFieldToFilter) =>
|
||||
recordFieldToFilter.fieldMetadataId !==
|
||||
nonDraggableRecordField?.fieldMetadataId,
|
||||
)
|
||||
.sort(sortByProperty('position'));
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenuItemsContainer>
|
||||
{fieldMetadataItemLabelIdentifier && (
|
||||
<MenuItemDraggable
|
||||
LeftIcon={getIcon(fieldMetadataItemLabelIdentifier.icon)}
|
||||
text={fieldMetadataItemLabelIdentifier.label}
|
||||
accent={'placeholder'}
|
||||
showGrip={true}
|
||||
isDragDisabled
|
||||
/>
|
||||
)}
|
||||
{draggableRecordFields.length > 0 && (
|
||||
<DraggableList
|
||||
onDragEnd={handleDragEnd}
|
||||
draggableItems={
|
||||
<>
|
||||
{draggableRecordFields.map((recordField, index) => {
|
||||
const fieldIndex =
|
||||
index +
|
||||
(isDefined(fieldMetadataItemLabelIdentifier) ? 1 : 0);
|
||||
|
||||
const fieldMetadataItem = getFieldMetadataItemById(
|
||||
recordField.fieldMetadataId,
|
||||
);
|
||||
|
||||
return (
|
||||
<DraggableItem
|
||||
key={recordField.fieldMetadataId}
|
||||
draggableId={recordField.fieldMetadataId}
|
||||
index={fieldIndex + 1}
|
||||
itemComponent={
|
||||
<MenuItemDraggable
|
||||
key={recordField.fieldMetadataId}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
iconButtons={[
|
||||
{
|
||||
Icon: IconEyeOff,
|
||||
onClick: () =>
|
||||
handleChangeFieldVisibility({
|
||||
fieldMetadataId: recordField.fieldMetadataId,
|
||||
isVisible: recordField.isVisible,
|
||||
}),
|
||||
},
|
||||
]}
|
||||
text={fieldMetadataItem.label}
|
||||
showGrip
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user