feat: display record identifier field as first column in table (#3788)
* feat: display record identifier field as first column in table & forbid hiding and moving record identifier column Closes #3303 * refactor: add availableTableColumnKeysSelectorScopeMap * feat: show plus icon button for label identifier column and dropdown menu for other columns * fix: use label identifier field value in RecordShowPage title * refactor: remove availableColumnKeys selector * refactor: review - compute label identifier logic in mapViewFieldsToColumnDefinitions + remove selectors * fix: several fixes * fix: fix board fields isVisible * fix: fix board fields reordering * fix: more board fields fixes * fix: fix hiddenTableColumnsSelectorScopeMap
This commit is contained in:
@ -19,26 +19,25 @@ import { StyledDropdownMenuSubheader } from '@/ui/layout/dropdown/components/Sty
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { MenuItemDraggable } from '@/ui/navigation/menu-item/components/MenuItemDraggable';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { groupArrayItemsBy } from '~/utils/array/groupArrayItemsBy';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
type ViewFieldsVisibilityDropdownSectionProps = {
|
||||
fields: Omit<ColumnDefinition<FieldMetadata>, 'size'>[];
|
||||
isDraggable: boolean;
|
||||
onDragEnd?: OnDragEndResponder;
|
||||
onVisibilityChange: (
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => void;
|
||||
title: string;
|
||||
isVisible: boolean;
|
||||
isDraggable: boolean;
|
||||
onDragEnd?: OnDragEndResponder;
|
||||
};
|
||||
|
||||
export const ViewFieldsVisibilityDropdownSection = ({
|
||||
fields,
|
||||
onVisibilityChange,
|
||||
title,
|
||||
isVisible,
|
||||
isDraggable,
|
||||
onDragEnd,
|
||||
onVisibilityChange,
|
||||
title,
|
||||
}: ViewFieldsVisibilityDropdownSectionProps) => {
|
||||
const handleOnDrag = (result: DropResult, provided: ResponderProvided) => {
|
||||
onDragEnd?.(result, provided);
|
||||
@ -47,8 +46,7 @@ export const ViewFieldsVisibilityDropdownSection = ({
|
||||
const [openToolTipIndex, setOpenToolTipIndex] = useState<number>();
|
||||
|
||||
const handleInfoButtonClick = (index: number) => {
|
||||
if (index === openToolTipIndex) setOpenToolTipIndex(undefined);
|
||||
else setOpenToolTipIndex(index);
|
||||
setOpenToolTipIndex(index === openToolTipIndex ? undefined : index);
|
||||
};
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
@ -57,27 +55,23 @@ export const ViewFieldsVisibilityDropdownSection = ({
|
||||
index: number,
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => {
|
||||
if (field.infoTooltipContent) {
|
||||
return [
|
||||
{
|
||||
Icon: IconInfoCircle,
|
||||
onClick: () => handleInfoButtonClick(index),
|
||||
isActive: openToolTipIndex === index,
|
||||
},
|
||||
{
|
||||
Icon: field.isVisible ? IconMinus : IconPlus,
|
||||
onClick: () => onVisibilityChange(field),
|
||||
},
|
||||
];
|
||||
}
|
||||
if (!field.infoTooltipContent) {
|
||||
return [
|
||||
{
|
||||
Icon: isVisible ? IconMinus : IconPlus,
|
||||
onClick: () => onVisibilityChange(field),
|
||||
},
|
||||
];
|
||||
}
|
||||
const iconButtons = [
|
||||
field.infoTooltipContent
|
||||
? {
|
||||
Icon: IconInfoCircle,
|
||||
onClick: () => handleInfoButtonClick(index),
|
||||
isActive: openToolTipIndex === index,
|
||||
}
|
||||
: null,
|
||||
field.isLabelIdentifier
|
||||
? null
|
||||
: {
|
||||
Icon: field.isVisible ? IconMinus : IconPlus,
|
||||
onClick: () => onVisibilityChange(field),
|
||||
},
|
||||
].filter(isDefined);
|
||||
|
||||
return iconButtons.length ? iconButtons : undefined;
|
||||
};
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
@ -89,50 +83,55 @@ export const ViewFieldsVisibilityDropdownSection = ({
|
||||
},
|
||||
});
|
||||
|
||||
const { nonDraggableItems = [], draggableItems = [] } = isDraggable
|
||||
? groupArrayItemsBy(fields, ({ isLabelIdentifier }) =>
|
||||
isLabelIdentifier ? 'nonDraggableItems' : 'draggableItems',
|
||||
)
|
||||
: { nonDraggableItems: fields, draggableItems: [] };
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<StyledDropdownMenuSubheader>{title}</StyledDropdownMenuSubheader>
|
||||
<DropdownMenuItemsContainer>
|
||||
{isDraggable ? (
|
||||
{nonDraggableItems.map((field, fieldIndex) => (
|
||||
<MenuItem
|
||||
key={field.fieldMetadataId}
|
||||
LeftIcon={getIcon(field.iconName)}
|
||||
iconButtons={getIconButtons(fieldIndex, field)}
|
||||
isTooltipOpen={openToolTipIndex === fieldIndex}
|
||||
text={field.label}
|
||||
className={`${title}-fixed-item-tooltip-anchor-${fieldIndex}`}
|
||||
/>
|
||||
))}
|
||||
{!!draggableItems.length && (
|
||||
<DraggableList
|
||||
onDragEnd={handleOnDrag}
|
||||
draggableItems={
|
||||
<>
|
||||
{[...fields]
|
||||
.sort((a, b) => a.position - b.position)
|
||||
.map((field, index) => (
|
||||
{draggableItems.map((field, index) => {
|
||||
const fieldIndex = index + nonDraggableItems.length;
|
||||
|
||||
return (
|
||||
<DraggableItem
|
||||
key={field.fieldMetadataId}
|
||||
draggableId={field.fieldMetadataId}
|
||||
index={index + 1}
|
||||
index={fieldIndex + 1}
|
||||
itemComponent={
|
||||
<MenuItemDraggable
|
||||
key={field.fieldMetadataId}
|
||||
LeftIcon={getIcon(field.iconName)}
|
||||
iconButtons={getIconButtons(index + 1, field)}
|
||||
isTooltipOpen={openToolTipIndex === index + 1}
|
||||
iconButtons={getIconButtons(fieldIndex, field)}
|
||||
isTooltipOpen={openToolTipIndex === fieldIndex}
|
||||
text={field.label}
|
||||
className={`${title}-draggable-item-tooltip-anchor-${
|
||||
index + 1
|
||||
}`}
|
||||
className={`${title}-draggable-item-tooltip-anchor-${fieldIndex}`}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
fields.map((field, index) => (
|
||||
<MenuItem
|
||||
key={field.fieldMetadataId}
|
||||
LeftIcon={getIcon(field.iconName)}
|
||||
iconButtons={getIconButtons(index, field)}
|
||||
isTooltipOpen={openToolTipIndex === index}
|
||||
text={field.label}
|
||||
className={`${title}-fixed-item-tooltip-anchor-${index}`}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
{isDefined(openToolTipIndex) &&
|
||||
|
||||
Reference in New Issue
Block a user