mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 03:51:36 +03:00
feat: table record group (#8781)
Fix #8401 #8402 This PR is only taking care or displaying properly the record group on the table. Record-reorder within group has also been prepared. Start of collapsible animation has been done, but not working for now. <img width="1381" alt="Screenshot 2024-11-28 at 2 52 07 PM" src="https://github.com/user-attachments/assets/514bb3e6-3475-4c47-a91c-64f7d20bbe73">
This commit is contained in:
parent
05149feb00
commit
a2d55a8694
@ -3,15 +3,18 @@ import {
|
||||
IconChevronLeft,
|
||||
IconSettings,
|
||||
MenuItem,
|
||||
MenuItemSelect,
|
||||
UndecoratedLink,
|
||||
useIcons,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
||||
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { StyledInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect';
|
||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
||||
import { useSearchRecordGroupField } from '@/object-record/object-options-dropdown/hooks/useSearchRecordGroupField';
|
||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||
import { useHandleRecordGroupField } from '@/object-record/record-index/hooks/useHandleRecordGroupField';
|
||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||
@ -23,6 +26,7 @@ import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMe
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
||||
const { getIcon } = useIcons();
|
||||
@ -43,16 +47,22 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
||||
hiddenRecordGroupIdsComponentSelector,
|
||||
);
|
||||
|
||||
const recordGroupFieldMetadataItem = useRecoilComponentValueV2(
|
||||
recordGroupFieldMetadataComponentState,
|
||||
);
|
||||
|
||||
const {
|
||||
recordGroupFieldSearchInput,
|
||||
setRecordGroupFieldSearchInput,
|
||||
filteredRecordGroupFieldMetadataItems,
|
||||
} = useSearchRecordGroupField();
|
||||
|
||||
const { handleRecordGroupFieldChange, resetRecordGroupField } =
|
||||
useHandleRecordGroupField({
|
||||
viewBarComponentId: recordIndexId,
|
||||
});
|
||||
const {
|
||||
handleRecordGroupFieldChange: setRecordGroupField,
|
||||
resetRecordGroupField,
|
||||
} = useHandleRecordGroupField({
|
||||
viewBarComponentId: recordIndexId,
|
||||
});
|
||||
|
||||
const newFieldSettingsUrl = getSettingsPagePath(
|
||||
SettingsPath.ObjectNewFieldSelect,
|
||||
@ -66,6 +76,18 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
||||
navigationMemorizedUrlState,
|
||||
);
|
||||
|
||||
const handleResetRecordGroupField = () => {
|
||||
resetRecordGroupField();
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const handleRecordGroupFieldChange = (
|
||||
fieldMetadataItem: FieldMetadataItem,
|
||||
) => {
|
||||
setRecordGroupField(fieldMetadataItem);
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
currentContentId === 'hiddenRecordGroups' &&
|
||||
@ -90,13 +112,16 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
||||
onChange={(event) => setRecordGroupFieldSearchInput(event.target.value)}
|
||||
/>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem text="None" onClick={resetRecordGroupField} />
|
||||
<MenuItemSelect
|
||||
text="None"
|
||||
selected={!isDefined(recordGroupFieldMetadataItem)}
|
||||
onClick={handleResetRecordGroupField}
|
||||
/>
|
||||
{filteredRecordGroupFieldMetadataItems.map((fieldMetadataItem) => (
|
||||
<MenuItem
|
||||
<MenuItemSelect
|
||||
key={fieldMetadataItem.id}
|
||||
onClick={() => {
|
||||
handleRecordGroupFieldChange(fieldMetadataItem);
|
||||
}}
|
||||
selected={fieldMetadataItem.id === recordGroupFieldMetadataItem?.id}
|
||||
onClick={() => handleRecordGroupFieldChange(fieldMetadataItem)}
|
||||
LeftIcon={getIcon(fieldMetadataItem.icon)}
|
||||
text={fieldMetadataItem.label}
|
||||
/>
|
||||
|
@ -16,8 +16,8 @@ import { RecordBoardComponentInstanceContext } from '@/object-record/record-boar
|
||||
import { getDraggedRecordPosition } from '@/object-record/record-board/utils/getDraggedRecordPosition';
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||
@ -69,12 +69,13 @@ export const RecordBoard = () => {
|
||||
visibleRecordGroupIdsComponentSelector,
|
||||
);
|
||||
|
||||
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
);
|
||||
const recordIndexRecordIdsByGroupFamilyState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
);
|
||||
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const recordIndexAllRecordIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
const { resetRecordSelection, setRecordAsSelected } =
|
||||
@ -97,14 +98,14 @@ export const RecordBoard = () => {
|
||||
() => {
|
||||
const allRecordIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRowIdsState,
|
||||
recordIndexAllRecordIdsState,
|
||||
);
|
||||
|
||||
for (const recordId of allRecordIds) {
|
||||
setRecordAsSelected(recordId, true);
|
||||
}
|
||||
},
|
||||
[recordIndexAllRowIdsState, setRecordAsSelected],
|
||||
[recordIndexAllRecordIdsState, setRecordAsSelected],
|
||||
);
|
||||
|
||||
useScopedHotkeys('ctrl+a,meta+a', selectAll, TableHotkeyScope.Table);
|
||||
@ -137,7 +138,7 @@ export const RecordBoard = () => {
|
||||
|
||||
const destinationRecordByGroupIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(destinationRecordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(destinationRecordGroupId),
|
||||
);
|
||||
const otherRecordIdsInDestinationColumn =
|
||||
sourceRecordGroupId === destinationRecordGroupId
|
||||
@ -172,7 +173,7 @@ export const RecordBoard = () => {
|
||||
});
|
||||
},
|
||||
[
|
||||
recordIndexRowIdsByGroupFamilyState,
|
||||
recordIndexRecordIdsByGroupFamilyState,
|
||||
selectFieldMetadataItem,
|
||||
updateOneRecord,
|
||||
],
|
||||
|
@ -3,8 +3,7 @@ import { useRecoilCallback } from 'recoil';
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { sortRecordsByPosition } from '@/object-record/utils/sortRecordsByPosition';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
@ -22,24 +21,15 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
recordBoardId,
|
||||
);
|
||||
const recordIndexRecordIdsByGroupFamilyState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const setRecordIds = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(records: ObjectRecord[]) => {
|
||||
const existingAllRowIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRowIdsState,
|
||||
);
|
||||
|
||||
const recordGroupIds = getSnapshotValue(
|
||||
snapshot,
|
||||
visibleRecordGroupIdsSelector,
|
||||
@ -53,7 +43,7 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
|
||||
|
||||
const existingRecordGroupRowIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(recordGroupId),
|
||||
);
|
||||
|
||||
const recordGroupFieldMetadata = getSnapshotValue(
|
||||
@ -75,32 +65,16 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
|
||||
|
||||
if (!isDeeplyEqual(existingRecordGroupRowIds, recordGroupRowIds)) {
|
||||
set(
|
||||
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(recordGroupId),
|
||||
recordGroupRowIds,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const allRowIds: string[] = [];
|
||||
|
||||
for (const recordGroupId of recordGroupIds) {
|
||||
const tableRowIdsByGroup = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||
);
|
||||
|
||||
allRowIds.push(...tableRowIdsByGroup);
|
||||
}
|
||||
|
||||
if (!isDeeplyEqual(existingAllRowIds, allRowIds)) {
|
||||
set(recordIndexAllRowIdsState, allRowIds);
|
||||
}
|
||||
},
|
||||
[
|
||||
visibleRecordGroupIdsSelector,
|
||||
recordIndexRowIdsByGroupFamilyState,
|
||||
recordIndexRecordIdsByGroupFamilyState,
|
||||
recordGroupFieldMetadataState,
|
||||
recordIndexAllRowIdsState,
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -2,9 +2,7 @@ import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { sortRecordsByPosition } from '@/object-record/utils/sortRecordsByPosition';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
@ -13,36 +11,20 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const useSetRecordIdsForColumn = (recordBoardId?: string) => {
|
||||
const recordGroupIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordGroupIdsComponentState,
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const recordGroupFieldMetadataState = useRecoilComponentCallbackStateV2(
|
||||
recordGroupFieldMetadataComponentState,
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
recordBoardId,
|
||||
);
|
||||
const recordIndexRecordIdsByGroupFamilyState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
recordBoardId,
|
||||
);
|
||||
|
||||
const setRecordIdsForColumn = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(currentRecordGroupId: string, records: ObjectRecord[]) => {
|
||||
const existingAllRowIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRowIdsState,
|
||||
);
|
||||
|
||||
const recordGroupIds = getSnapshotValue(snapshot, recordGroupIdsState);
|
||||
|
||||
const recordGroup = getSnapshotValue(
|
||||
snapshot,
|
||||
recordGroupDefinitionFamilyState(currentRecordGroupId),
|
||||
@ -50,7 +32,7 @@ export const useSetRecordIdsForColumn = (recordBoardId?: string) => {
|
||||
|
||||
const existingRecordGroupRowIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(currentRecordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(currentRecordGroupId),
|
||||
);
|
||||
|
||||
const recordGroupFieldMetadata = getSnapshotValue(
|
||||
@ -72,35 +54,12 @@ export const useSetRecordIdsForColumn = (recordBoardId?: string) => {
|
||||
|
||||
if (!isDeeplyEqual(existingRecordGroupRowIds, recordGroupRowIds)) {
|
||||
set(
|
||||
recordIndexRowIdsByGroupFamilyState(currentRecordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(currentRecordGroupId),
|
||||
recordGroupRowIds,
|
||||
);
|
||||
}
|
||||
|
||||
const allRowIds: string[] = [];
|
||||
|
||||
for (const recordGroupId of recordGroupIds) {
|
||||
const tableRowIdsByGroup =
|
||||
recordGroupId !== currentRecordGroupId
|
||||
? getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||
)
|
||||
: recordGroupRowIds;
|
||||
|
||||
allRowIds.push(...tableRowIdsByGroup);
|
||||
}
|
||||
|
||||
if (!isDeeplyEqual(existingAllRowIds, allRowIds)) {
|
||||
set(recordIndexAllRowIdsState, allRowIds);
|
||||
}
|
||||
},
|
||||
[
|
||||
recordGroupIdsState,
|
||||
recordIndexRowIdsByGroupFamilyState,
|
||||
recordGroupFieldMetadataState,
|
||||
recordIndexAllRowIdsState,
|
||||
],
|
||||
[recordIndexRecordIdsByGroupFamilyState, recordGroupFieldMetadataState],
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -4,7 +4,7 @@ import { Droppable } from '@hello-pangea/dnd';
|
||||
import { RecordBoardColumnCardsContainer } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer';
|
||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
@ -31,8 +31,8 @@ export const RecordBoardColumn = ({
|
||||
recordGroupDefinitionFamilyState(recordBoardColumnId),
|
||||
);
|
||||
|
||||
const recordRowIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
const recordIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
recordBoardColumnId,
|
||||
);
|
||||
|
||||
@ -44,9 +44,9 @@ export const RecordBoardColumn = ({
|
||||
<RecordBoardColumnContext.Provider
|
||||
value={{
|
||||
columnDefinition: recordGroupDefinition,
|
||||
recordCount: recordRowIdsByGroup.length,
|
||||
recordCount: recordIdsByGroup.length,
|
||||
columnId: recordBoardColumnId,
|
||||
recordIds: recordRowIdsByGroup,
|
||||
recordIds: recordIdsByGroup,
|
||||
}}
|
||||
>
|
||||
<Droppable droppableId={recordBoardColumnId}>
|
||||
@ -54,7 +54,7 @@ export const RecordBoardColumn = ({
|
||||
<StyledColumn>
|
||||
<RecordBoardColumnCardsContainer
|
||||
droppableProvided={droppableProvided}
|
||||
recordIds={recordRowIdsByGroup}
|
||||
recordIds={recordIdsByGroup}
|
||||
/>
|
||||
</StyledColumn>
|
||||
)}
|
||||
|
@ -3,7 +3,7 @@ import { isDefined } from 'twenty-ui';
|
||||
import { RecordBoardColumnHeader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeader';
|
||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
@ -18,8 +18,8 @@ export const RecordBoardColumnHeaderWrapper = ({
|
||||
recordGroupDefinitionFamilyState(columnId),
|
||||
);
|
||||
|
||||
const recordRowIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
const recordIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
columnId,
|
||||
);
|
||||
|
||||
@ -32,8 +32,8 @@ export const RecordBoardColumnHeaderWrapper = ({
|
||||
value={{
|
||||
columnId,
|
||||
columnDefinition: recordGroupDefinition,
|
||||
recordCount: recordRowIdsByGroup.length,
|
||||
recordIds: recordRowIdsByGroup,
|
||||
recordCount: recordIdsByGroup.length,
|
||||
recordIds: recordIdsByGroup,
|
||||
}}
|
||||
>
|
||||
<RecordBoardColumnHeader />
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
|
||||
export const recordBoardSelectedRecordIdsComponentSelector =
|
||||
@ -10,11 +10,15 @@ export const recordBoardSelectedRecordIdsComponentSelector =
|
||||
get:
|
||||
({ instanceId }) =>
|
||||
({ get }) => {
|
||||
const allRowIds = get(
|
||||
recordIndexAllRowIdsComponentState.atomFamily({ instanceId }),
|
||||
const allRecordIds = get(
|
||||
// TODO: This selector use a context different from the one used in the snippet
|
||||
// its working for now as the instanceId is the same but we should change this
|
||||
recordIndexAllRecordIdsComponentSelector.selectorFamily({
|
||||
instanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
return allRowIds.filter(
|
||||
return allRecordIds.filter(
|
||||
(recordId) =>
|
||||
get(
|
||||
isRecordBoardCardSelectedComponentFamilyState.atomFamily({
|
||||
|
@ -2,7 +2,7 @@ import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/s
|
||||
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||
import { recordIndexRecordGroupHideComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupHideComponentState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useSaveCurrentViewGroups } from '@/views/hooks/useSaveCurrentViewGroups';
|
||||
@ -22,10 +22,11 @@ export const useRecordGroupVisibility = ({
|
||||
recordGroupIdsComponentState,
|
||||
);
|
||||
|
||||
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
viewBarId,
|
||||
);
|
||||
const recordIndexRecordIdsByGroupFamilyState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
viewBarId,
|
||||
);
|
||||
|
||||
const objectOptionsDropdownRecordGroupHideState =
|
||||
useRecoilComponentCallbackStateV2(recordIndexRecordGroupHideComponentState);
|
||||
@ -79,7 +80,7 @@ export const useRecordGroupVisibility = ({
|
||||
|
||||
const recordGroupRowIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(recordGroupId),
|
||||
);
|
||||
|
||||
if (recordGroupRowIds.length > 0) {
|
||||
@ -107,7 +108,7 @@ export const useRecordGroupVisibility = ({
|
||||
recordIndexRecordGroupIdsState,
|
||||
objectOptionsDropdownRecordGroupHideState,
|
||||
saveViewGroups,
|
||||
recordIndexRowIdsByGroupFamilyState,
|
||||
recordIndexRecordIdsByGroupFamilyState,
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -8,7 +8,6 @@ import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const useSetRecordGroup = (viewId?: string) => {
|
||||
const { objectMetadataItem } = useContext(RecordIndexRootPropsContext);
|
||||
@ -26,28 +25,23 @@ export const useSetRecordGroup = (viewId?: string) => {
|
||||
return useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(recordGroups: RecordGroupDefinition[]) => {
|
||||
if (recordGroups.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentRecordGroupId = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRecordGroupIdsState,
|
||||
);
|
||||
const fieldMetadataId = recordGroups[0].fieldMetadataId;
|
||||
const fieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) => field.id === fieldMetadataId,
|
||||
);
|
||||
const fieldMetadataId = recordGroups?.[0]?.fieldMetadataId;
|
||||
const fieldMetadata = fieldMetadataId
|
||||
? objectMetadataItem.fields.find(
|
||||
(field) => field.id === fieldMetadataId,
|
||||
)
|
||||
: undefined;
|
||||
const currentFieldMetadata = getSnapshotValue(
|
||||
snapshot,
|
||||
recordGroupFieldMetadataState,
|
||||
);
|
||||
|
||||
// Set the field metadata linked to the record groups
|
||||
if (
|
||||
isDefined(fieldMetadata) &&
|
||||
!isDeeplyEqual(fieldMetadata, currentFieldMetadata)
|
||||
) {
|
||||
if (!isDeeplyEqual(fieldMetadata, currentFieldMetadata)) {
|
||||
set(recordGroupFieldMetadataState, fieldMetadata);
|
||||
}
|
||||
|
||||
@ -67,6 +61,16 @@ export const useSetRecordGroup = (viewId?: string) => {
|
||||
|
||||
const recordGroupIds = recordGroups.map(({ id }) => id);
|
||||
|
||||
// Get ids that has been removed between the current and new record groups
|
||||
const removedRecordGroupIds = currentRecordGroupId.filter(
|
||||
(id) => !recordGroupIds.includes(id),
|
||||
);
|
||||
|
||||
// Remove the record groups that has been removed
|
||||
removedRecordGroupIds.forEach((id) => {
|
||||
set(recordGroupDefinitionFamilyState(id), undefined);
|
||||
});
|
||||
|
||||
if (isDeeplyEqual(currentRecordGroupId, recordGroupIds)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const hiddenRecordGroupIdsComponentSelector = createComponentSelectorV2<
|
||||
string[]
|
||||
RecordGroupDefinition['id'][]
|
||||
>({
|
||||
key: 'hiddenRecordGroupIdsComponentSelector',
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
|
@ -10,7 +10,7 @@ import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewCompon
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const visibleRecordGroupIdsComponentSelector = createComponentSelectorV2<
|
||||
string[]
|
||||
RecordGroupDefinition['id'][]
|
||||
>({
|
||||
key: 'visibleRecordGroupIdsComponentSelector',
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
|
@ -6,7 +6,7 @@ export const sortRecordGroupDefinitions = (
|
||||
recordGroupSort: RecordGroupSort,
|
||||
) => {
|
||||
const visibleRecordGroups = recordGroupDefinitions.filter(
|
||||
(boardGroup) => boardGroup.isVisible,
|
||||
(recordGroup) => recordGroup.isVisible,
|
||||
);
|
||||
|
||||
const compareAlphabetical = (a: string, b: string, reverse = false) => {
|
||||
|
@ -61,6 +61,10 @@ export const useFindManyParams = (
|
||||
);
|
||||
}
|
||||
|
||||
if (!isDefined(currentRecordGroupDefinition.value)) {
|
||||
return { [fieldMetadataItem.name]: { is: 'NULL' } };
|
||||
}
|
||||
|
||||
return {
|
||||
[fieldMetadataItem.name]: {
|
||||
eq: currentRecordGroupDefinition.value,
|
||||
@ -68,8 +72,6 @@ export const useFindManyParams = (
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Handle case when value is nullable
|
||||
|
||||
return {};
|
||||
}, [objectMetadataItem.fields, currentRecordGroupDefinition]);
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
|
||||
export const recordIndexAllRowIdsComponentState = createComponentStateV2<
|
||||
string[]
|
||||
>({
|
||||
key: 'recordIndexAllRowIdsComponentState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
});
|
@ -2,9 +2,9 @@ import { RecordGroupDefinition } from '@/object-record/record-group/types/Record
|
||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
|
||||
export const recordIndexRowIdsByGroupComponentFamilyState =
|
||||
export const recordIndexRecordIdsByGroupComponentFamilyState =
|
||||
createComponentFamilyStateV2<string[], RecordGroupDefinition['id']>({
|
||||
key: 'recordIndexRowIdsByGroupComponentFamilyState',
|
||||
key: 'recordIndexRecordIdsByGroupComponentFamilyState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
});
|
@ -0,0 +1,59 @@
|
||||
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
|
||||
/**
|
||||
* Do not use this key outside of this file.
|
||||
* This is a temporary key to store the record ids for the default record group.
|
||||
*/
|
||||
const defaultFamilyKey = 'record-group-default-id';
|
||||
|
||||
export const recordIndexAllRecordIdsComponentSelector =
|
||||
createComponentSelectorV2<ObjectRecord['id'][]>({
|
||||
key: 'recordIndexAllRecordIdsComponentSelector',
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
get:
|
||||
({ instanceId }) =>
|
||||
({ get }) => {
|
||||
const recordGroupIds = get(
|
||||
recordGroupIdsComponentState.atomFamily({
|
||||
instanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
if (recordGroupIds.length === 0) {
|
||||
return get(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState.atomFamily({
|
||||
instanceId,
|
||||
familyKey: defaultFamilyKey,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return recordGroupIds.reduce<ObjectRecord['id'][]>(
|
||||
(acc, recordGroupId) => {
|
||||
const rowIds = get(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState.atomFamily({
|
||||
instanceId,
|
||||
familyKey: recordGroupId,
|
||||
}),
|
||||
);
|
||||
|
||||
return [...acc, ...rowIds];
|
||||
},
|
||||
[],
|
||||
);
|
||||
},
|
||||
set:
|
||||
({ instanceId }) =>
|
||||
({ set }, recordIds) =>
|
||||
set(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState.atomFamily({
|
||||
instanceId,
|
||||
familyKey: defaultFamilyKey,
|
||||
}),
|
||||
recordIds,
|
||||
),
|
||||
});
|
@ -4,7 +4,7 @@ import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
|
||||
export const recordIndexRecordGroupIsDraggableSortComponentSelector =
|
||||
createComponentSelectorV2({
|
||||
createComponentSelectorV2<boolean>({
|
||||
key: 'recordIndexRecordGroupIsDraggableSortComponentSelector',
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
get:
|
||||
|
@ -2,7 +2,7 @@ import styled from '@emotion/styled';
|
||||
import { isNonEmptyString, isNull } from '@sniptt/guards';
|
||||
|
||||
import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
||||
import { RecordTableStickyEffect } from '@/object-record/record-table/components/RecordTableStickyEffect';
|
||||
@ -53,8 +53,8 @@ export const RecordTable = ({
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
@ -70,7 +70,7 @@ export const RecordTable = ({
|
||||
|
||||
const recordTableIsEmpty =
|
||||
!isRecordTableInitialLoading &&
|
||||
allRowIds.length === 0 &&
|
||||
allRecordIds.length === 0 &&
|
||||
isNull(pendingRecordId);
|
||||
|
||||
const { resetTableRowSelection, setRowSelected } = useRecordTable({
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableBodyFetchMoreLoader } from '@/object-record/record-table/record-table-body/components/RecordTableBodyFetchMoreLoader';
|
||||
import { RecordTableRow } from '@/object-record/record-table/record-table-row/components/RecordTableRow';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const RecordTableNoRecordGroupRows = () => {
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{allRowIds.map((recordId, rowIndex) => {
|
||||
{allRecordIds.map((recordId, rowIndex) => {
|
||||
return (
|
||||
<RecordTableRow
|
||||
key={recordId}
|
||||
|
@ -1,37 +1,52 @@
|
||||
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableRow } from '@/object-record/record-table/record-table-row/components/RecordTableRow';
|
||||
import { isRecordGroupTableSectionToggledComponentState } from '@/object-record/record-table/record-table-section/states/isRecordGroupTableSectionToggledComponentState';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useMemo } from 'react';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const RecordTableRecordGroupRows = () => {
|
||||
const recordGroupId = useCurrentRecordGroupId();
|
||||
const currentRecordGroupId = useCurrentRecordGroupId();
|
||||
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
const recordGroupRowIds = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
recordGroupId,
|
||||
const recordIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
currentRecordGroupId,
|
||||
);
|
||||
|
||||
const isRecordGroupTableSectionToggled = useRecoilComponentFamilyValueV2(
|
||||
isRecordGroupTableSectionToggledComponentState,
|
||||
currentRecordGroupId,
|
||||
);
|
||||
|
||||
const rowIndexMap = useMemo(
|
||||
() => new Map(allRowIds.map((id, index) => [id, index])),
|
||||
[allRowIds],
|
||||
() => new Map(allRecordIds.map((recordId, index) => [recordId, index])),
|
||||
[allRecordIds],
|
||||
);
|
||||
|
||||
return recordGroupRowIds.map((recordId) => {
|
||||
const rowIndex = rowIndexMap.get(recordId);
|
||||
return (
|
||||
isRecordGroupTableSectionToggled &&
|
||||
recordIdsByGroup.map((recordId) => {
|
||||
const rowIndex = rowIndexMap.get(recordId);
|
||||
|
||||
if (!rowIndex) {
|
||||
throw new Error(`Row index for record id ${recordId} not found`);
|
||||
}
|
||||
if (!isDefined(rowIndex)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RecordTableRow key={recordId} recordId={recordId} rowIndex={rowIndex} />
|
||||
);
|
||||
});
|
||||
return (
|
||||
<RecordTableRow
|
||||
key={recordId}
|
||||
recordId={recordId}
|
||||
rowIndex={rowIndex}
|
||||
isPendingRow={!isRecordGroupTableSectionToggled}
|
||||
/>
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { isNull } from '@sniptt/guards';
|
||||
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableEmptyState } from '@/object-record/record-table/empty-state/components/RecordTableEmptyState';
|
||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
|
||||
@ -20,8 +20,8 @@ export const RecordTableEmptyHandler = ({
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
@ -32,7 +32,7 @@ export const RecordTableEmptyHandler = ({
|
||||
|
||||
const recordTableIsEmpty =
|
||||
!isRecordTableInitialLoading &&
|
||||
allRowIds.length === 0 &&
|
||||
allRecordIds.length === 0 &&
|
||||
isNull(pendingRecordId);
|
||||
|
||||
if (recordTableIsEmpty) {
|
||||
|
@ -2,7 +2,7 @@ import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
@ -18,8 +18,8 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const recordIndexAllRecordIdsSelector = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
recordTableIdFromContext,
|
||||
);
|
||||
|
||||
@ -43,10 +43,13 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
||||
return useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
() => {
|
||||
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||
const allRecordIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
);
|
||||
|
||||
for (const rowId of allRowIds) {
|
||||
set(isRowSelectedFamilyState(rowId), false);
|
||||
for (const recordId of allRecordIds) {
|
||||
set(isRowSelectedFamilyState(recordId), false);
|
||||
}
|
||||
|
||||
set(hasUserSelectedAllRowsState, false);
|
||||
@ -54,7 +57,7 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
||||
set(isActionMenuDropdownOpenState, false);
|
||||
},
|
||||
[
|
||||
recordIndexAllRowIdsState,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
hasUserSelectedAllRowsState,
|
||||
isActionMenuDropdownOpenState,
|
||||
isRowSelectedFamilyState,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { allRowsSelectedStatusComponentSelector } from '@/object-record/record-table/states/selectors/allRowsSelectedStatusComponentSelector';
|
||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||
@ -15,8 +15,8 @@ export const useSelectAllRows = (recordTableId?: string) => {
|
||||
isRowSelectedComponentFamilyState,
|
||||
recordTableId,
|
||||
);
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const recordIndexAllRecordIdsSelector = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
@ -28,24 +28,22 @@ export const useSelectAllRows = (recordTableId?: string) => {
|
||||
allRowsSelectedStatusSelector,
|
||||
);
|
||||
|
||||
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||
const allRecordIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
);
|
||||
|
||||
if (
|
||||
allRowsSelectedStatus === 'none' ||
|
||||
allRowsSelectedStatus === 'some'
|
||||
) {
|
||||
for (const rowId of allRowIds) {
|
||||
set(isRowSelectedFamilyState(rowId), true);
|
||||
}
|
||||
} else {
|
||||
for (const rowId of allRowIds) {
|
||||
set(isRowSelectedFamilyState(rowId), false);
|
||||
}
|
||||
for (const recordId of allRecordIds) {
|
||||
const isSelected =
|
||||
allRowsSelectedStatus === 'none' ||
|
||||
allRowsSelectedStatus === 'some';
|
||||
|
||||
set(isRowSelectedFamilyState(recordId), isSelected);
|
||||
}
|
||||
},
|
||||
[
|
||||
allRowsSelectedStatusSelector,
|
||||
recordIndexAllRowIdsState,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
isRowSelectedFamilyState,
|
||||
],
|
||||
);
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
@ -21,26 +20,26 @@ export const useSetRecordTableData = ({
|
||||
recordTableId,
|
||||
onEntityCountChange,
|
||||
}: useSetRecordTableDataProps) => {
|
||||
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexRowIdsByGroupComponentFamilyState,
|
||||
recordTableId,
|
||||
);
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const recordIndexRecordIdsByGroupFamilyState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const recordIndexAllRecordIdsSelector = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const isRowSelectedFamilyState = useRecoilComponentCallbackStateV2(
|
||||
isRowSelectedComponentFamilyState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const hasUserSelectedAllRowsState = useRecoilComponentCallbackStateV2(
|
||||
hasUserSelectedAllRowsComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
const recordIndexRecordGroupIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordGroupIdsComponentState,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
@ -67,8 +66,8 @@ export const useSetRecordTableData = ({
|
||||
const currentRowIds = getSnapshotValue(
|
||||
snapshot,
|
||||
currentRecordGroupId
|
||||
? recordIndexRowIdsByGroupFamilyState(currentRecordGroupId)
|
||||
: recordIndexAllRowIdsState,
|
||||
? recordIndexRecordIdsByGroupFamilyState(currentRecordGroupId)
|
||||
: recordIndexAllRecordIdsSelector,
|
||||
);
|
||||
|
||||
const hasUserSelectedAllRows = getSnapshotValue(
|
||||
@ -76,11 +75,6 @@ export const useSetRecordTableData = ({
|
||||
hasUserSelectedAllRowsState,
|
||||
);
|
||||
|
||||
const recordGroupIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRecordGroupIdsState,
|
||||
);
|
||||
|
||||
const recordIds = records.map((record) => record.id);
|
||||
|
||||
if (!isDeeplyEqual(currentRowIds, recordIds)) {
|
||||
@ -91,39 +85,21 @@ export const useSetRecordTableData = ({
|
||||
}
|
||||
|
||||
if (isDefined(currentRecordGroupId)) {
|
||||
// TODO: Hack to store all ids in the same order as the record group definitions
|
||||
// Should be replaced by something more efficient
|
||||
const allRowIds: string[] = [];
|
||||
|
||||
set(
|
||||
recordIndexRowIdsByGroupFamilyState(currentRecordGroupId),
|
||||
recordIndexRecordIdsByGroupFamilyState(currentRecordGroupId),
|
||||
recordIds,
|
||||
);
|
||||
|
||||
for (const recordGroupId of recordGroupIds) {
|
||||
const tableRowIdsByGroup =
|
||||
recordGroupId !== currentRecordGroupId
|
||||
? getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||
)
|
||||
: recordIds;
|
||||
|
||||
allRowIds.push(...tableRowIdsByGroup);
|
||||
}
|
||||
set(recordIndexAllRowIdsState, allRowIds);
|
||||
} else {
|
||||
set(recordIndexAllRowIdsState, recordIds);
|
||||
set(recordIndexAllRecordIdsSelector, recordIds);
|
||||
}
|
||||
|
||||
onEntityCountChange(totalCount);
|
||||
}
|
||||
},
|
||||
[
|
||||
recordIndexRowIdsByGroupFamilyState,
|
||||
recordIndexAllRowIdsState,
|
||||
recordIndexRecordIdsByGroupFamilyState,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
hasUserSelectedAllRowsState,
|
||||
recordIndexRecordGroupIdsState,
|
||||
onEntityCountChange,
|
||||
isRowSelectedFamilyState,
|
||||
],
|
||||
|
@ -3,7 +3,7 @@ import { useRecoilCallback } from 'recoil';
|
||||
import { MoveFocusDirection } from '@/object-record/record-table/types/MoveFocusDirection';
|
||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { numberOfTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/numberOfTableColumnsComponentSelector';
|
||||
import { softFocusPositionComponentState } from '@/object-record/record-table/states/softFocusPositionComponentState';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
@ -17,8 +17,8 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const recordIndexAllRecordIdsSelector = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
recordTableId,
|
||||
);
|
||||
|
||||
@ -47,7 +47,10 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
const moveDown = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() => {
|
||||
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||
const allRecordIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
);
|
||||
const softFocusPosition = getSnapshotValue(
|
||||
snapshot,
|
||||
softFocusPositionState,
|
||||
@ -55,8 +58,8 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
|
||||
let newRowIndex = softFocusPosition.row + 1;
|
||||
|
||||
if (newRowIndex >= allRowIds.length) {
|
||||
newRowIndex = allRowIds.length - 1;
|
||||
if (newRowIndex >= allRecordIds.length) {
|
||||
newRowIndex = allRecordIds.length - 1;
|
||||
}
|
||||
|
||||
setSoftFocusPosition({
|
||||
@ -64,7 +67,11 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
row: newRowIndex,
|
||||
});
|
||||
},
|
||||
[recordIndexAllRowIdsState, setSoftFocusPosition, softFocusPositionState],
|
||||
[
|
||||
recordIndexAllRecordIdsSelector,
|
||||
setSoftFocusPosition,
|
||||
softFocusPositionState,
|
||||
],
|
||||
);
|
||||
|
||||
const numberOfTableColumnsSelector = useRecoilComponentCallbackStateV2(
|
||||
@ -75,7 +82,10 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
const moveRight = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() => {
|
||||
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||
const allRecordIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
);
|
||||
const softFocusPosition = getSnapshotValue(
|
||||
snapshot,
|
||||
softFocusPositionState,
|
||||
@ -91,11 +101,11 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
|
||||
const isLastRowAndLastColumn =
|
||||
currentColumnIndex === numberOfTableColumns - 1 &&
|
||||
currentRowIndex === allRowIds.length - 1;
|
||||
currentRowIndex === allRecordIds.length - 1;
|
||||
|
||||
const isLastColumnButNotLastRow =
|
||||
currentColumnIndex === numberOfTableColumns - 1 &&
|
||||
currentRowIndex !== allRowIds.length - 1;
|
||||
currentRowIndex !== allRecordIds.length - 1;
|
||||
|
||||
const isNotLastColumn = currentColumnIndex !== numberOfTableColumns - 1;
|
||||
|
||||
@ -116,7 +126,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
||||
}
|
||||
},
|
||||
[
|
||||
recordIndexAllRowIdsState,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
softFocusPositionState,
|
||||
numberOfTableColumnsSelector,
|
||||
setSoftFocusPosition,
|
||||
|
@ -0,0 +1,50 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { MOBILE_VIEWPORT } from 'twenty-ui';
|
||||
|
||||
const StyledTbody = styled.tbody`
|
||||
&.first-columns-sticky {
|
||||
td:nth-of-type(1) {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
td:nth-of-type(2) {
|
||||
position: sticky;
|
||||
left: 11px;
|
||||
z-index: 5;
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
td:nth-of-type(3) {
|
||||
position: sticky;
|
||||
left: 43px;
|
||||
z-index: 5;
|
||||
transition: 0.3s ease;
|
||||
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
& [data-testid='editable-cell-display-mode'] {
|
||||
[data-testid='tooltip'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-testid='chip'] {
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
height: calc(100% + 2px);
|
||||
width: 4px;
|
||||
right: 0px;
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.light};
|
||||
clip-path: inset(0px -4px 0px 0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const RecordTableBody = StyledTbody;
|
@ -3,7 +3,7 @@ import { ReactNode, useContext } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableContext } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useComputeNewRowPosition } from '@/object-record/record-table/hooks/useComputeNewRowPosition';
|
||||
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
||||
@ -11,7 +11,7 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const RecordTableBodyDragDropContext = ({
|
||||
export const RecordTableBodyDragDropContextProvider = ({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
@ -22,8 +22,8 @@ export const RecordTableBodyDragDropContext = ({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
const { currentViewWithCombinedFiltersAndSorts } =
|
||||
@ -43,7 +43,7 @@ export const RecordTableBodyDragDropContext = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const computeResult = computeNewRowPosition(result, allRowIds);
|
||||
const computeResult = computeNewRowPosition(result, allRecordIds);
|
||||
|
||||
if (!isDefined(computeResult)) {
|
||||
return;
|
@ -1,80 +1,36 @@
|
||||
import { Theme } from '@emotion/react';
|
||||
import { RecordTableBody } from '@/object-record/record-table/record-table-body/components/RecordTableBody';
|
||||
import { Droppable } from '@hello-pangea/dnd';
|
||||
import { styled } from '@linaria/react';
|
||||
import { ReactNode, useContext, useState } from 'react';
|
||||
import { MOBILE_VIEWPORT, ThemeContext } from 'twenty-ui';
|
||||
import { ReactNode, useState } from 'react';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
const StyledTbody = styled.tbody<{
|
||||
theme: Theme;
|
||||
}>`
|
||||
&.first-columns-sticky {
|
||||
td:nth-of-type(1) {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
td:nth-of-type(2) {
|
||||
position: sticky;
|
||||
left: 11px;
|
||||
z-index: 5;
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
td:nth-of-type(3) {
|
||||
position: sticky;
|
||||
left: 43px;
|
||||
z-index: 5;
|
||||
transition: 0.3s ease;
|
||||
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
& [data-testid='editable-cell-display-mode'] {
|
||||
[data-testid='tooltip'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-testid='chip'] {
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
height: calc(100% + 2px);
|
||||
width: 4px;
|
||||
right: 0px;
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.light};
|
||||
clip-path: inset(0px -4px 0px 0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
type RecordTableBodyDroppableProps = {
|
||||
children: ReactNode;
|
||||
recordGroupId?: string;
|
||||
isDropDisabled?: boolean;
|
||||
};
|
||||
|
||||
export const RecordTableBodyDroppable = ({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) => {
|
||||
recordGroupId,
|
||||
isDropDisabled,
|
||||
}: RecordTableBodyDroppableProps) => {
|
||||
const [v4Persistable] = useState(v4());
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<Droppable droppableId={v4Persistable}>
|
||||
<Droppable
|
||||
droppableId={recordGroupId ?? v4Persistable}
|
||||
isDropDisabled={isDropDisabled}
|
||||
>
|
||||
{(provided) => (
|
||||
<StyledTbody
|
||||
id="record-table-body"
|
||||
theme={theme}
|
||||
<RecordTableBody
|
||||
id={`record-table-body${recordGroupId ? `-${recordGroupId}` : ''}`}
|
||||
ref={provided.innerRef}
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{children}
|
||||
{provided.placeholder}
|
||||
</StyledTbody>
|
||||
</RecordTableBody>
|
||||
)}
|
||||
</Droppable>
|
||||
);
|
||||
|
@ -0,0 +1,106 @@
|
||||
import { DragDropContext, DropResult } from '@hello-pangea/dnd';
|
||||
import { ReactNode, useContext } from 'react';
|
||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableContext } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useComputeNewRowPosition } from '@/object-record/record-table/hooks/useComputeNewRowPosition';
|
||||
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const RecordTableBodyRecordGroupDragDropContextProvider = ({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}) => {
|
||||
const { objectNameSingular, recordTableId, objectMetadataItem } =
|
||||
useContext(RecordTableContext);
|
||||
|
||||
const { updateOneRecord: updateOneRow } = useUpdateOneRecord({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const recordIndexAllRecordIdsSelector = useRecoilComponentCallbackStateV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
const { currentViewWithCombinedFiltersAndSorts } =
|
||||
useGetCurrentView(recordTableId);
|
||||
|
||||
const viewSorts = currentViewWithCombinedFiltersAndSorts?.viewSorts || [];
|
||||
|
||||
const setIsRemoveSortingModalOpenState = useSetRecoilState(
|
||||
isRemoveSortingModalOpenState,
|
||||
);
|
||||
|
||||
const computeNewRowPosition = useComputeNewRowPosition();
|
||||
|
||||
const handleDragEnd = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(result: DropResult) => {
|
||||
const tableAllRecordIds = getSnapshotValue(
|
||||
snapshot,
|
||||
recordIndexAllRecordIdsSelector,
|
||||
);
|
||||
|
||||
const recordGroupId = result.destination?.droppableId;
|
||||
|
||||
if (!isDefined(recordGroupId)) {
|
||||
throw new Error('Record group id is not defined');
|
||||
}
|
||||
|
||||
const recordGroup = getSnapshotValue(
|
||||
snapshot,
|
||||
recordGroupDefinitionFamilyState(recordGroupId),
|
||||
);
|
||||
|
||||
if (!isDefined(recordGroup)) {
|
||||
throw new Error('Record group is not defined');
|
||||
}
|
||||
|
||||
const fieldMetadata = objectMetadataItem.fields.find(
|
||||
(field) => field.id === recordGroup.fieldMetadataId,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadata)) {
|
||||
throw new Error('Field metadata is not defined');
|
||||
}
|
||||
|
||||
if (viewSorts.length > 0) {
|
||||
setIsRemoveSortingModalOpenState(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const computeResult = computeNewRowPosition(result, tableAllRecordIds);
|
||||
|
||||
if (!isDefined(computeResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateOneRow({
|
||||
idToUpdate: computeResult.draggedRecordId,
|
||||
updateOneRecordInput: {
|
||||
position: computeResult.newPosition,
|
||||
[fieldMetadata.name]: recordGroup.value,
|
||||
},
|
||||
});
|
||||
},
|
||||
[
|
||||
recordIndexAllRecordIdsSelector,
|
||||
objectMetadataItem.fields,
|
||||
viewSorts.length,
|
||||
computeNewRowPosition,
|
||||
updateOneRow,
|
||||
setIsRemoveSortingModalOpenState,
|
||||
],
|
||||
);
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={handleDragEnd}>{children}</DragDropContext>
|
||||
);
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableNoRecordGroupRows } from '@/object-record/record-table/components/RecordTableNoRecordGroupRows';
|
||||
import { RecordTableBodyDragDropContext } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDragDropContext';
|
||||
import { RecordTableBodyDragDropContextProvider } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDragDropContextProvider';
|
||||
import { RecordTableBodyDroppable } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDroppable';
|
||||
import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading';
|
||||
import { RecordTablePendingRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRow';
|
||||
@ -8,24 +8,24 @@ import { isRecordTableInitialLoadingComponentState } from '@/object-record/recor
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const RecordTableNoRecordGroupBody = () => {
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
const isRecordTableInitialLoading = useRecoilComponentValueV2(
|
||||
isRecordTableInitialLoadingComponentState,
|
||||
);
|
||||
|
||||
if (isRecordTableInitialLoading && allRowIds.length === 0) {
|
||||
if (isRecordTableInitialLoading && allRecordIds.length === 0) {
|
||||
return <RecordTableBodyLoading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<RecordTableBodyDragDropContext>
|
||||
<RecordTableBodyDragDropContextProvider>
|
||||
<RecordTableBodyDroppable>
|
||||
<RecordTablePendingRow />
|
||||
<RecordTableNoRecordGroupRows />
|
||||
</RecordTableBodyDroppable>
|
||||
</RecordTableBodyDragDropContext>
|
||||
</RecordTableBodyDragDropContextProvider>
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,18 @@
|
||||
import { RecordGroupContext } from '@/object-record/record-group/states/context/RecordGroupContext';
|
||||
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableRecordGroupRows } from '@/object-record/record-table/components/RecordTableRecordGroupRows';
|
||||
import { RecordTableBodyDragDropContext } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDragDropContext';
|
||||
import { RecordTableBodyDroppable } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDroppable';
|
||||
import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading';
|
||||
import { RecordTableBodyRecordGroupDragDropContextProvider } from '@/object-record/record-table/record-table-body/components/RecordTableBodyRecordGroupDragDropContextProvider';
|
||||
import { RecordTablePendingRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRow';
|
||||
import { RecordTableRecordGroupSection } from '@/object-record/record-table/record-table-section/components/RecordTableRecordGroupSection';
|
||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
|
||||
export const RecordTableRecordGroupsBody = () => {
|
||||
const allRowIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRowIdsComponentState,
|
||||
const allRecordIds = useRecoilComponentValueV2(
|
||||
recordIndexAllRecordIdsComponentSelector,
|
||||
);
|
||||
|
||||
const isRecordTableInitialLoading = useRecoilComponentValueV2(
|
||||
@ -22,23 +23,26 @@ export const RecordTableRecordGroupsBody = () => {
|
||||
visibleRecordGroupIdsComponentSelector,
|
||||
);
|
||||
|
||||
if (isRecordTableInitialLoading && allRowIds.length === 0) {
|
||||
if (isRecordTableInitialLoading && allRecordIds.length === 0) {
|
||||
return <RecordTableBodyLoading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<RecordTableBodyDragDropContext>
|
||||
<RecordTableBodyDroppable>
|
||||
<RecordTableBodyRecordGroupDragDropContextProvider>
|
||||
<RecordTableBodyDroppable isDropDisabled>
|
||||
<RecordTablePendingRow />
|
||||
{visibleRecordGroupIds.map((recordGroupId) => (
|
||||
<RecordGroupContext.Provider
|
||||
key={recordGroupId}
|
||||
value={{ recordGroupId }}
|
||||
>
|
||||
<RecordTableRecordGroupRows />
|
||||
</RecordGroupContext.Provider>
|
||||
))}
|
||||
</RecordTableBodyDroppable>
|
||||
</RecordTableBodyDragDropContext>
|
||||
{visibleRecordGroupIds.map((recordGroupId) => (
|
||||
<RecordGroupContext.Provider
|
||||
key={recordGroupId}
|
||||
value={{ recordGroupId }}
|
||||
>
|
||||
<RecordTableBodyDroppable recordGroupId={recordGroupId}>
|
||||
<RecordTableRecordGroupSection />
|
||||
<RecordTableRecordGroupRows />
|
||||
</RecordTableBodyDroppable>
|
||||
</RecordGroupContext.Provider>
|
||||
))}
|
||||
</RecordTableBodyRecordGroupDragDropContextProvider>
|
||||
);
|
||||
};
|
||||
|
@ -4,12 +4,14 @@ import { RecoilRoot } from 'recoil';
|
||||
import { createState } from 'twenty-ui';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { textfieldDefinition } from '@/object-record/record-field/__mocks__/fieldDefinitions';
|
||||
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
||||
import { useUpsertRecord } from '@/object-record/record-table/record-table-cell/hooks/useUpsertRecord';
|
||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||
|
||||
const draftValue = 'updated Name';
|
||||
@ -62,22 +64,26 @@ const Wrapper = ({
|
||||
snapshot.set(draftValueState, draftValueMockedValue);
|
||||
}}
|
||||
>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recordId: 'recordId',
|
||||
fieldDefinition: {
|
||||
...textfieldDefinition,
|
||||
metadata: {
|
||||
...textfieldDefinition.metadata,
|
||||
objectMetadataNameSingular: CoreObjectNameSingular.Person,
|
||||
},
|
||||
},
|
||||
hotkeyScope: TableHotkeyScope.Table,
|
||||
isLabelIdentifier: false,
|
||||
}}
|
||||
<ViewComponentInstanceContext.Provider
|
||||
value={{ instanceId: CoreObjectNamePlural.Person }}
|
||||
>
|
||||
{children}
|
||||
</FieldContext.Provider>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recordId: 'recordId',
|
||||
fieldDefinition: {
|
||||
...textfieldDefinition,
|
||||
metadata: {
|
||||
...textfieldDefinition.metadata,
|
||||
objectMetadataNameSingular: CoreObjectNameSingular.Person,
|
||||
},
|
||||
},
|
||||
hotkeyScope: TableHotkeyScope.Table,
|
||||
isLabelIdentifier: false,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</FieldContext.Provider>
|
||||
</ViewComponentInstanceContext.Provider>
|
||||
</RecoilRoot>
|
||||
);
|
||||
|
||||
|
@ -4,10 +4,12 @@ import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadat
|
||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { recordFieldInputDraftValueComponentSelector } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueComponentSelector';
|
||||
import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector';
|
||||
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
|
||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { extractComponentSelector } from '@/ui/utilities/state/component-state/utils/extractComponentSelector';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
@ -18,8 +20,13 @@ export const useUpsertRecord = ({
|
||||
objectNameSingular: string;
|
||||
recordTableId: string;
|
||||
}) => {
|
||||
const hasRecordGroups = useRecoilComponentValueV2(
|
||||
hasRecordGroupsComponentSelector,
|
||||
);
|
||||
|
||||
const { createOneRecord } = useCreateOneRecord({
|
||||
objectNameSingular,
|
||||
shouldMatchRootQueryFilter: hasRecordGroups,
|
||||
});
|
||||
|
||||
const recordTablePendingRecordIdState = useRecoilComponentCallbackStateV2(
|
||||
|
@ -14,17 +14,19 @@ import { RecordTableWithWrappersScrollWrapperContext } from '@/ui/utilities/scro
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
type RecordTableRowWrapperProps = {
|
||||
recordId: string;
|
||||
rowIndex: number;
|
||||
isPendingRow?: boolean;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export const RecordTableRowWrapper = ({
|
||||
recordId,
|
||||
rowIndex,
|
||||
isPendingRow,
|
||||
children,
|
||||
}: {
|
||||
recordId: string;
|
||||
rowIndex: number;
|
||||
isPendingRow?: boolean;
|
||||
children: ReactNode;
|
||||
}) => {
|
||||
}: RecordTableRowWrapperProps) => {
|
||||
const trRef = useRef<HTMLTableRowElement>(null);
|
||||
|
||||
const { objectMetadataItem } = useContext(RecordTableContext);
|
||||
|
@ -0,0 +1,115 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useCallback } from 'react';
|
||||
import { IconChevronUp, isDefined, Tag } from 'twenty-ui';
|
||||
|
||||
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
||||
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||
import { RecordGroupDefinitionType } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||
import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState';
|
||||
import { isRecordGroupTableSectionToggledComponentState } from '@/object-record/record-table/record-table-section/states/isRecordGroupTableSectionToggledComponentState';
|
||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
||||
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
const StyledTrContainer = styled.tr`
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const StyledChevronContainer = styled.td`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
color: ${({ theme }) => theme.font.color.secondary};
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
`;
|
||||
|
||||
const StyledTotalRow = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
margin-left: ${({ theme }) => theme.spacing(2)};
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
`;
|
||||
|
||||
const StyledRecordGroupSection = styled.td`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
padding-bottom: 6px;
|
||||
padding-top: 6px;
|
||||
`;
|
||||
|
||||
const StyledEmptyTd = styled.td`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
`;
|
||||
|
||||
export const RecordTableRecordGroupSection = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
const currentRecordGroupId = useCurrentRecordGroupId();
|
||||
|
||||
const visibleColumns = useRecoilComponentValueV2(
|
||||
visibleTableColumnsComponentSelector,
|
||||
);
|
||||
|
||||
const recordIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||
recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
currentRecordGroupId,
|
||||
);
|
||||
|
||||
const [
|
||||
isRecordGroupTableSectionToggled,
|
||||
setIsRecordGroupTableSectionToggled,
|
||||
] = useRecoilComponentFamilyStateV2(
|
||||
isRecordGroupTableSectionToggledComponentState,
|
||||
currentRecordGroupId,
|
||||
);
|
||||
|
||||
const recordGroup = useRecoilValue(
|
||||
recordGroupDefinitionFamilyState(currentRecordGroupId),
|
||||
);
|
||||
|
||||
const handleDropdownToggle = useCallback(() => {
|
||||
setIsRecordGroupTableSectionToggled((prevState) => !prevState);
|
||||
}, [setIsRecordGroupTableSectionToggled]);
|
||||
|
||||
if (!isDefined(recordGroup)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledTrContainer onClick={handleDropdownToggle}>
|
||||
<td aria-hidden></td>
|
||||
<StyledChevronContainer>
|
||||
<motion.span
|
||||
animate={{ rotate: isRecordGroupTableSectionToggled ? 180 : 0 }}
|
||||
transition={{ duration: theme.animation.duration.normal }}
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
}}
|
||||
>
|
||||
<IconChevronUp size={theme.icon.size.md} />
|
||||
</motion.span>
|
||||
</StyledChevronContainer>
|
||||
<StyledRecordGroupSection colSpan={visibleColumns.length}>
|
||||
<Tag
|
||||
variant={
|
||||
recordGroup.type !== RecordGroupDefinitionType.NoValue
|
||||
? 'solid'
|
||||
: 'outline'
|
||||
}
|
||||
color={
|
||||
recordGroup.type !== RecordGroupDefinitionType.NoValue
|
||||
? recordGroup.color
|
||||
: 'transparent'
|
||||
}
|
||||
text={recordGroup.title}
|
||||
weight="medium"
|
||||
/>
|
||||
<StyledTotalRow>{recordIdsByGroup.length}</StyledTotalRow>
|
||||
</StyledRecordGroupSection>
|
||||
<StyledEmptyTd></StyledEmptyTd>
|
||||
<StyledEmptyTd></StyledEmptyTd>
|
||||
</StyledTrContainer>
|
||||
);
|
||||
};
|
@ -0,0 +1,10 @@
|
||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||
|
||||
export const isRecordGroupTableSectionToggledComponentState =
|
||||
createComponentFamilyStateV2<boolean, RecordGroupDefinition['id']>({
|
||||
key: 'isRecordGroupTableSectionToggledComponentState',
|
||||
defaultValue: true,
|
||||
componentInstanceContext: ViewComponentInstanceContext,
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
import { selectedRowIdsComponentSelector } from '@/object-record/record-table/states/selectors/selectedRowIdsComponentSelector';
|
||||
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
import { AllRowsSelectedStatus } from '../../types/AllRowSelectedStatus';
|
||||
@ -12,9 +12,9 @@ export const allRowsSelectedStatusComponentSelector =
|
||||
get:
|
||||
({ instanceId }) =>
|
||||
({ get }) => {
|
||||
const allRowIds = get(
|
||||
const allRecordIds = get(
|
||||
// TODO: Working because instanceId is the same, but we're not in the same context, should be changed !
|
||||
recordIndexAllRowIdsComponentState.atomFamily({
|
||||
recordIndexAllRecordIdsComponentSelector.selectorFamily({
|
||||
instanceId,
|
||||
}),
|
||||
);
|
||||
@ -30,7 +30,7 @@ export const allRowsSelectedStatusComponentSelector =
|
||||
const allRowsSelectedStatus =
|
||||
numberOfSelectedRows === 0
|
||||
? 'none'
|
||||
: selectedRowIds.length === allRowIds.length
|
||||
: selectedRowIds.length === allRecordIds.length
|
||||
? 'all'
|
||||
: 'some';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
@ -11,19 +11,19 @@ export const selectedRowIdsComponentSelector = createComponentSelectorV2<
|
||||
get:
|
||||
({ instanceId }) =>
|
||||
({ get }) => {
|
||||
const allRowIds = get(
|
||||
const allRecordIds = get(
|
||||
// TODO: Working because instanceId is the same, but we're not in the same context, should be changed !
|
||||
recordIndexAllRowIdsComponentState.atomFamily({
|
||||
recordIndexAllRecordIdsComponentSelector.selectorFamily({
|
||||
instanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
return allRowIds.filter(
|
||||
(rowId) =>
|
||||
return allRecordIds.filter(
|
||||
(recordId) =>
|
||||
get(
|
||||
isRowSelectedComponentFamilyState.atomFamily({
|
||||
instanceId,
|
||||
familyKey: rowId,
|
||||
familyKey: recordId,
|
||||
}),
|
||||
) === true,
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
@ -11,19 +11,19 @@ export const unselectedRowIdsComponentSelector = createComponentSelectorV2<
|
||||
get:
|
||||
({ instanceId }) =>
|
||||
({ get }) => {
|
||||
const rowIds = get(
|
||||
const allRecordIds = get(
|
||||
// TODO: Working because instanceId is the same, but we're not in the same context, should be changed !
|
||||
recordIndexAllRowIdsComponentState.atomFamily({
|
||||
recordIndexAllRecordIdsComponentSelector.selectorFamily({
|
||||
instanceId,
|
||||
}),
|
||||
);
|
||||
|
||||
return rowIds.filter(
|
||||
(rowId) =>
|
||||
return allRecordIds.filter(
|
||||
(recordId) =>
|
||||
get(
|
||||
isRowSelectedComponentFamilyState.atomFamily({
|
||||
instanceId,
|
||||
familyKey: rowId,
|
||||
familyKey: recordId,
|
||||
}),
|
||||
) === false,
|
||||
);
|
||||
|
@ -14,6 +14,7 @@ import { isDefined } from 'twenty-ui';
|
||||
export function createComponentSelectorV2<ValueType>(options: {
|
||||
key: string;
|
||||
get: SelectorGetter<ValueType, ComponentStateKeyV2>;
|
||||
set?: never;
|
||||
componentInstanceContext: ComponentInstanceStateContext<any> | null;
|
||||
}): ComponentReadOnlySelectorV2<ValueType>;
|
||||
|
||||
|
@ -38,7 +38,7 @@ export const StyledMenuItemSelect = styled(StyledMenuItemBase)<{
|
||||
`;
|
||||
|
||||
type MenuItemSelectProps = {
|
||||
LeftIcon: IconComponent | null | undefined;
|
||||
LeftIcon?: IconComponent | null | undefined;
|
||||
selected: boolean;
|
||||
text: string;
|
||||
className?: string;
|
||||
|
Loading…
Reference in New Issue
Block a user