Board compact view and Company Picker for opportunity special case (#3713)

* Re-enabled board compact mode

* Add specific case for opportunity to display company picker

* Add infinite scroll

* Remove useEffect

* Fix

* Fix
This commit is contained in:
Charles Bochet 2024-01-31 11:37:03 +01:00 committed by GitHub
parent 29339ef99a
commit c8e4d0ab9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 291 additions and 46 deletions

View File

@ -3,6 +3,8 @@ import { isFirstRecordBoardColumnFamilyStateScopeMap } from '@/object-record/rec
import { isLastRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isLastRecordBoardColumnFamilyStateScopeMap';
import { isRecordBoardCardSelectedFamilyStateScopeMap } from '@/object-record/record-board/states/isRecordBoardCardSelectedFamilyStateScopeMap';
import { isRecordBoardCompactModeActiveStateScopeMap } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveStateScopeMap';
import { isRecordBoardFetchingRecordsStateScopeMap } from '@/object-record/record-board/states/isRecordBoardFetchingRecordsStateScopeMap';
import { onRecordBoardFetchMoreVisibilityChangeStateScopeMap } from '@/object-record/record-board/states/onRecordBoardFetchMoreVisibilityChangeStateScopeMap';
import { recordBoardColumnIdsStateScopeMap } from '@/object-record/record-board/states/recordBoardColumnIdsStateScopeMap';
import { recordBoardFieldDefinitionsStateScopeMap } from '@/object-record/record-board/states/recordBoardFieldDefinitionsStateScopeMap';
import { recordBoardFiltersStateScopeMap } from '@/object-record/record-board/states/recordBoardFiltersStateScopeMap';
@ -30,6 +32,10 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
recordBoardObjectSingularNameStateScopeMap,
scopeId,
),
getIsFetchingRecordState: getState(
isRecordBoardFetchingRecordsStateScopeMap,
scopeId,
),
getColumnIdsState: getState(recordBoardColumnIdsStateScopeMap, scopeId),
isFirstColumnFamilyState: getFamilyState(
isFirstRecordBoardColumnFamilyStateScopeMap,
@ -72,5 +78,10 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
isRecordBoardCompactModeActiveStateScopeMap,
scopeId,
),
getOnFetchMoreVisibilityChangeState: getState(
onRecordBoardFetchMoreVisibilityChangeStateScopeMap,
scopeId,
),
};
};

View File

@ -10,6 +10,8 @@ export const useRecordBoard = (recordBoardId?: string) => {
getFieldDefinitionsState,
getObjectSingularNameState,
getSelectedRecordIdsSelector,
getIsCompactModeActiveState,
getOnFetchMoreVisibilityChangeState,
} = useRecordBoardStates(recordBoardId);
const { setColumns } = useSetRecordBoardColumns(recordBoardId);
@ -24,5 +26,7 @@ export const useRecordBoard = (recordBoardId?: string) => {
setFieldDefinitions,
setObjectSingularName,
getSelectedRecordIdsSelector,
getIsCompactModeActiveState,
getOnFetchMoreVisibilityChangeState,
};
};

View File

@ -1,4 +1,5 @@
import { ReactNode, useContext, useState } from 'react';
import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
@ -20,6 +21,7 @@ import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut';
import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper';
const StyledBoardCard = styled.div<{ selected: boolean }>`
background-color: ${({ theme, selected }) =>
@ -119,22 +121,26 @@ const StyledCompactIconContainer = styled.div`
align-items: center;
display: flex;
justify-content: center;
margin-left: ${({ theme }) => theme.spacing(1)};
`;
const StyledRecordInlineCellPlaceholder = styled.div`
height: 24px;
`;
export const RecordBoardCard = () => {
const { recordId } = useContext(RecordBoardCardContext);
const { updateOneRecord } = useContext(RecordBoardContext);
const { updateOneRecord, objectMetadataItem } =
useContext(RecordBoardContext);
const {
getObjectSingularNameState,
getIsCompactModeActiveState,
isRecordBoardCardSelectedFamilyState,
getVisibleFieldDefinitionsState,
} = useRecordBoardStates();
const isCompactModeActive = useRecoilValue(getIsCompactModeActiveState());
const objectNameSingular = useRecoilValue(getObjectSingularNameState());
const [isCardInCompactMode, setIsCardInCompactMode] =
useState(isCompactModeActive);
const [isCardInCompactMode, setIsCardInCompactMode] = useState(true);
const [isCurrentCardSelected, setIsCurrentCardSelected] = useRecoilState(
isRecordBoardCardSelectedFamilyState(recordId),
@ -190,13 +196,21 @@ export const RecordBoardCard = () => {
return [updateEntity, { loading: false }];
};
if (!objectNameSingular || !record) {
const scrollWrapperRef = useContext(ScrollWrapperContext);
const { ref: cardRef, inView } = useInView({
root: scrollWrapperRef.current,
rootMargin: '1000px',
});
if (!record) {
return null;
}
return (
<StyledBoardCardWrapper onContextMenu={handleContextMenu}>
<StyledBoardCard
ref={cardRef}
selected={isCurrentCardSelected}
onMouseLeave={onMouseLeaveBoard}
onClick={() => {
@ -204,7 +218,10 @@ export const RecordBoardCard = () => {
}}
>
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
<RecordChip objectNameSingular={objectNameSingular} record={record} />
<RecordChip
objectNameSingular={objectMetadataItem.nameSingular}
record={record}
/>
{isCompactModeActive && (
<StyledCompactIconContainer className="compact-icon-container">
<LightIconButton
@ -226,7 +243,10 @@ export const RecordBoardCard = () => {
</StyledCheckboxContainer>
</StyledBoardCardHeader>
<StyledBoardCardBody>
<AnimatedEaseInOut isOpen={!isCardInCompactMode} initial={false}>
<AnimatedEaseInOut
isOpen={!isCardInCompactMode || !isCompactModeActive}
initial={false}
>
{visibleBoardCardFieldDefinitions.map((fieldDefinition) => (
<PreventSelectOnClickContainer
key={fieldDefinition.fieldMetadataId}
@ -249,7 +269,11 @@ export const RecordBoardCard = () => {
hotkeyScope: InlineCellHotkeyScope.InlineCell,
}}
>
<RecordInlineCell />
{inView ? (
<RecordInlineCell />
) : (
<StyledRecordInlineCellPlaceholder />
)}
</FieldContext.Provider>
</PreventSelectOnClickContainer>
))}

View File

@ -2,14 +2,14 @@ import React, { useContext } from 'react';
import styled from '@emotion/styled';
import { Draggable, DroppableProvided } from '@hello-pangea/dnd';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { RecordBoardColumnCardsMemo } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsMemo';
import { RecordBoardColumnFetchMoreLoader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader';
import { RecordBoardColumnNewButton } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnNewButton';
import { RecordBoardColumnNewOpportunityButton } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnNewOpportunityButton';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
const StyledPlaceholder = styled.div`
min-height: 1px;
`;
const StyledColumnCardsContainer = styled.div`
display: flex;
flex: 1;
@ -30,6 +30,7 @@ export const RecordBoardColumnCardsContainer = ({
droppableProvided,
}: RecordBoardColumnCardsContainerProps) => {
const { columnDefinition } = useContext(RecordBoardColumnContext);
const { objectMetadataItem } = useContext(RecordBoardContext);
return (
<StyledColumnCardsContainer
@ -38,7 +39,7 @@ export const RecordBoardColumnCardsContainer = ({
{...droppableProvided?.droppableProps}
>
<RecordBoardColumnCardsMemo recordIds={recordIds} />
<StyledPlaceholder>{droppableProvided?.placeholder}</StyledPlaceholder>
<RecordBoardColumnFetchMoreLoader />
<Draggable
draggableId={`new-${columnDefinition.id}`}
index={recordIds.length}
@ -51,7 +52,12 @@ export const RecordBoardColumnCardsContainer = ({
{...draggableProvided?.draggableProps}
>
<StyledNewButtonContainer>
<RecordBoardColumnNewButton />
{objectMetadataItem.nameSingular ===
CoreObjectNameSingular.Opportunity ? (
<RecordBoardColumnNewOpportunityButton />
) : (
<RecordBoardColumnNewButton />
)}
</StyledNewButtonContainer>
</div>
)}

View File

@ -0,0 +1,36 @@
import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
import { grayScale } from '@/ui/theme/constants/colors';
const StyledText = styled.div`
align-items: center;
box-shadow: none;
color: ${grayScale.gray40};
display: flex;
height: 32px;
margin-left: ${({ theme }) => theme.spacing(8)};
padding-left: ${({ theme }) => theme.spacing(2)};
`;
export const RecordBoardColumnFetchMoreLoader = () => {
const { getIsFetchingRecordState, getOnFetchMoreVisibilityChangeState } =
useRecordBoardStates();
const isFetchingRecords = useRecoilValue(getIsFetchingRecordState());
const onFetchMoreVisibilityChange = useRecoilValue(
getOnFetchMoreVisibilityChangeState(),
);
const { ref } = useInView({
onChange: onFetchMoreVisibilityChange,
});
return (
<div ref={ref}>
{isFetchingRecords && <StyledText>Loading more...</StyledText>}
</div>
);
};

View File

@ -0,0 +1,90 @@
import { useCallback, useContext, useState } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { SingleEntitySelect } from '@/object-record/relation-picker/components/SingleEntitySelect';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { IconPlus } from '@/ui/display/icon';
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
const StyledButton = styled.button`
align-items: center;
align-self: baseline;
background-color: ${({ theme }) => theme.background.primary};
border: none;
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.tertiary};
cursor: pointer;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
padding: ${({ theme }) => theme.spacing(1)};
&:hover {
background-color: ${({ theme }) => theme.background.tertiary};
}
`;
export const RecordBoardColumnNewOpportunityButton = () => {
const [isCreatingCard, setIsCreatingCard] = useState(false);
const theme = useTheme();
const { columnDefinition } = useContext(RecordBoardColumnContext);
const { createOneRecord, selectFieldMetadataItem } =
useContext(RecordBoardContext);
const {
goBackToPreviousHotkeyScope,
setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope();
const handleEntitySelect = (company?: EntityForSelect) => {
setIsCreatingCard(false);
goBackToPreviousHotkeyScope();
if (!company) {
return;
}
createOneRecord({
name: company.name,
companyId: company.id,
[selectFieldMetadataItem.name]: columnDefinition.value,
});
};
const handleNewClick = useCallback(() => {
setIsCreatingCard(true);
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
}, [setIsCreatingCard, setHotkeyScopeAndMemorizePreviousScope]);
const handleCancel = () => {
goBackToPreviousHotkeyScope();
setIsCreatingCard(false);
};
return (
<>
{isCreatingCard ? (
<SingleEntitySelect
disableBackgroundBlur
onCancel={handleCancel}
onEntitySelected={handleEntitySelect}
relationObjectNameSingular={CoreObjectNameSingular.Company}
relationPickerScopeId="relation-picker"
selectedRelationRecordIds={[]}
/>
) : (
<StyledButton onClick={handleNewClick}>
<IconPlus size={theme.icon.size.md} />
New
</StyledButton>
)}
</>
);
};

View File

@ -0,0 +1,7 @@
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const isRecordBoardFetchingRecordsStateScopeMap =
createStateScopeMap<boolean>({
key: 'isRecordBoardFetchingRecordsStateScopeMap',
defaultValue: false,
});

View File

@ -0,0 +1,7 @@
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const onRecordBoardFetchMoreVisibilityChangeStateScopeMap =
createStateScopeMap<(visbility: boolean) => void>({
key: 'onRecordBoardFetchMoreVisibilityChangeStateScopeMap',
defaultValue: () => {},
});

View File

@ -4,6 +4,7 @@ import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldIn
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFieldCurrency';
import { isFieldCurrencyValue } from '@/object-record/record-field/types/guards/isFieldCurrencyValue';
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
import { computeEmptyDraftValue } from '@/object-record/record-field/utils/computeEmptyDraftValue';
import { isFieldValueEmpty } from '@/object-record/record-field/utils/isFieldValueEmpty';
@ -21,18 +22,20 @@ export const computeDraftValueFromFieldValue = <FieldValue>({
// than the intputDraftValue type as string can be typed anywhere
if (isFieldCurrency(fieldDefinition)) {
if (isFieldValueEmpty({ fieldValue, fieldDefinition })) {
if (
isFieldValueEmpty({ fieldValue, fieldDefinition }) ||
!isFieldCurrencyValue(fieldValue)
) {
return computeEmptyDraftValue<FieldValue>({ fieldDefinition });
}
if (isFieldCurrencyValue(fieldValue)) {
return {
amount: fieldValue?.amountMicros
? fieldValue.amountMicros / 1000000
: '',
currenyCode: CurrencyCode.USD,
} as unknown as FieldInputDraftValue<FieldValue>;
}
return {
amount: fieldValue?.amountMicros ? fieldValue.amountMicros / 1000000 : '',
currenyCode: CurrencyCode.USD,
} as unknown as FieldInputDraftValue<FieldValue>;
}
if (isFieldRelation(fieldDefinition)) {
return computeEmptyDraftValue<FieldValue>({ fieldDefinition });
}
return fieldValue as FieldInputDraftValue<FieldValue>;

View File

@ -8,6 +8,7 @@ import { isFieldEmail } from '@/object-record/record-field/types/guards/isFieldE
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
import { isFieldLink } from '@/object-record/record-field/types/guards/isFieldLink';
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
import { isFieldRelationValue } from '@/object-record/record-field/types/guards/isFieldRelationValue';
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
import { isFieldUuid } from '@/object-record/record-field/types/guards/isFieldUuid';
@ -24,7 +25,8 @@ export const computeEmptyDraftValue = <FieldValue>({
isFieldText(fieldDefinition) ||
isFieldDateTime(fieldDefinition) ||
isFieldNumber(fieldDefinition) ||
isFieldEmail(fieldDefinition)
isFieldEmail(fieldDefinition) ||
isFieldRelationValue(fieldDefinition)
) {
return '' as FieldInputDraftValue<FieldValue>;
}

View File

@ -1,4 +1,4 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
@ -19,7 +19,9 @@ export const RecordIndexBoardContainer = ({
recordBoardId,
objectNameSingular,
}: RecordIndexBoardContainerProps) => {
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
const { objectMetadataItem } = useObjectMetadataItemOnly({
objectNameSingular,
});
const selectFieldMetadataItem = objectMetadataItem.fields.find(
(field) => field.type === FieldMetadataType.Select,

View File

@ -1,8 +1,8 @@
import { useCallback, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
import { useRecordActionBar } from '@/object-record/record-action-bar/hooks/useRecordActionBar';
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
@ -21,11 +21,35 @@ export const RecordIndexBoardContainerEffect = ({
recordBoardId,
viewBarId,
}: RecordIndexBoardContainerEffectProps) => {
const { objectMetadataItem } = useObjectMetadataItem({
const { objectMetadataItem } = useObjectMetadataItemOnly({
objectNameSingular,
});
useLoadRecordIndexBoard({ objectNameSingular, recordBoardId, viewBarId });
const {
setColumns,
setObjectSingularName,
getSelectedRecordIdsSelector,
setFieldDefinitions,
getOnFetchMoreVisibilityChangeState,
} = useRecordBoard(recordBoardId);
const { fetchMoreRecords, loading } = useLoadRecordIndexBoard({
objectNameSingular,
recordBoardId,
viewBarId,
});
const setOnFetchMoreVisibilityChange = useSetRecoilState(
getOnFetchMoreVisibilityChangeState(),
);
useEffect(() => {
setOnFetchMoreVisibilityChange(() => () => {
if (!loading) {
fetchMoreRecords?.();
}
});
}, [fetchMoreRecords, loading, setOnFetchMoreVisibilityChange]);
const navigate = useNavigate();
@ -33,12 +57,6 @@ export const RecordIndexBoardContainerEffect = ({
navigate(`/settings/objects/${objectMetadataItem.namePlural}`);
}, [navigate, objectMetadataItem.namePlural]);
const {
setColumns,
setObjectSingularName,
getSelectedRecordIdsSelector,
setFieldDefinitions,
} = useRecordBoard(recordBoardId);
const { resetRecordSelection } = useRecordBoardSelection(recordBoardId);
useEffect(() => {

View File

@ -7,13 +7,19 @@ import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/opti
import { useRecordIndexOptionsForTable } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForTable';
import { useRecordIndexOptionsImport } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsImport';
import { TableOptionsHotkeyScope } from '@/object-record/record-table/types/TableOptionsHotkeyScope';
import { IconChevronLeft, IconFileImport, IconTag } from '@/ui/display/icon';
import {
IconBaselineDensitySmall,
IconChevronLeft,
IconFileImport,
IconTag,
} from '@/ui/display/icon';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemToggle';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
@ -86,8 +92,11 @@ export const RecordIndexOptionsDropdownContent = ({
hiddenBoardFields,
handleReorderBoardFields,
handleBoardFieldVisibilityChange,
isCompactModeActive,
setIsCompactModeActive,
} = useRecordIndexOptionsForBoard({
objectNameSingular,
recordBoardId: recordIndexId,
viewBarId: recordIndexId,
});
@ -170,6 +179,20 @@ export const RecordIndexOptionsDropdownContent = ({
)}
</>
)}
{viewType === ViewType.Kanban && (
<>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer>
<MenuItemToggle
LeftIcon={IconBaselineDensitySmall}
onToggleChange={setIsCompactModeActive}
toggled={isCompactModeActive}
text="Compact view"
toggleSize="small"
/>
</DropdownMenuItemsContainer>
</>
)}
</>
);
};

View File

@ -5,32 +5,48 @@ import { useRecoilState } from 'recoil';
import { mapBoardFieldDefinitionsToViewFields } from '@/companies/utils/mapBoardFieldDefinitionsToViewFields';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
import { useViewFields } from '@/views/hooks/internal/useViewFields';
type useRecordIndexOptionsForBoardParams = {
objectNameSingular: string;
recordBoardId: string;
viewBarId: string;
};
export const useRecordIndexOptionsForBoard = ({
objectNameSingular,
recordBoardId,
viewBarId,
}: useRecordIndexOptionsForBoardParams) => {
const [recordIndexFieldDefinitions, setRecordIndexFieldDefinitions] =
useRecoilState(recordIndexFieldDefinitionsState);
const { persistViewFields } = useViewFields(viewBarId);
const { getIsCompactModeActiveState } = useRecordBoard(recordBoardId);
const [isCompactModeActive, setIsCompactModeActive] = useRecoilState(
getIsCompactModeActiveState(),
);
const { objectMetadataItem } = useObjectMetadataItemOnly({
objectNameSingular,
});
const { columnDefinitions } =
const { columnDefinitions: availableColumnDefinitions } =
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
// Todo replace this with label identifier logic
const columnDefinitions = availableColumnDefinitions
.filter(
(columnDefinition) => columnDefinition.metadata.fieldName !== 'name',
)
.filter(filterAvailableTableColumns);
const visibleBoardFields = useMemo(
() =>
columnDefinitions.filter((columnDefinition) => {
@ -152,5 +168,7 @@ export const useRecordIndexOptionsForBoard = ({
handleBoardFieldVisibilityChange,
visibleBoardFields,
hiddenBoardFields,
isCompactModeActive,
setIsCompactModeActive,
};
};

View File

@ -5,8 +5,6 @@ import { useRecoilValue } from 'recoil';
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
import { actionBarOpenState } from '../states/actionBarIsOpenState';
import { ActionBarItem } from './ActionBarItem';
const StyledContainerActionBar = styled.div`
@ -30,12 +28,11 @@ const StyledContainerActionBar = styled.div`
`;
export const ActionBar = () => {
const actionBarOpen = useRecoilValue(actionBarOpenState);
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
const actionBarEntries = useRecoilValue(actionBarEntriesState);
const wrapperRef = useRef<HTMLDivElement>(null);
if (!actionBarOpen || contextMenuIsOpen) {
if (contextMenuIsOpen) {
return null;
}

View File

@ -4,7 +4,6 @@ import { useRecoilValue, useSetRecoilState } from 'recoil';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { actionBarOpenState } from '@/ui/navigation/action-bar/states/actionBarIsOpenState';
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
@ -42,14 +41,12 @@ export const ContextMenu = () => {
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
const contextMenuEntries = useRecoilValue(contextMenuEntriesState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
const wrapperRef = useRef<HTMLDivElement>(null);
useListenClickOutside({
refs: [wrapperRef],
callback: () => {
setContextMenuOpenState(false);
setActionBarOpenState(true);
},
});