feat: record board component state refactor (#8779)
Fix #8758 This PR is migrating the recoil component state from v1 to v2 for board. It also now share some states and logics between board and table, further can be done later. Lastly this PR fix an issue since the PR #8613 that was treating no-value as a normal record-group.
This commit is contained in:
@ -10,46 +10,50 @@ import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObje
|
|||||||
|
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
||||||
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
|
||||||
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
||||||
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
|
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
|
export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
|
||||||
const {
|
const {
|
||||||
currentContentId,
|
currentContentId,
|
||||||
viewType,
|
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
onContentChange,
|
onContentChange,
|
||||||
closeDropdown,
|
closeDropdown,
|
||||||
} = useOptionsDropdown();
|
} = useOptionsDropdown();
|
||||||
|
|
||||||
const { objectNamePlural } = useObjectNamePluralFromSingular({
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
recordGroupFieldMetadataComponentState,
|
||||||
});
|
);
|
||||||
|
|
||||||
const { hiddenRecordGroups, viewGroupFieldMetadataItem } = useRecordGroups({
|
const hiddenRecordGroupIds = useRecoilComponentValueV2(
|
||||||
|
hiddenRecordGroupIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { objectNamePlural } = useObjectNamePluralFromSingular({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleVisibilityChange: handleRecordGroupVisibilityChange } =
|
const { handleVisibilityChange: handleRecordGroupVisibilityChange } =
|
||||||
useRecordGroupVisibility({
|
useRecordGroupVisibility({
|
||||||
viewBarId: recordIndexId,
|
viewBarId: recordIndexId,
|
||||||
viewType,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const viewGroupSettingsUrl = getSettingsPagePath(
|
const viewGroupSettingsUrl = getSettingsPagePath(
|
||||||
SettingsPath.ObjectFieldEdit,
|
SettingsPath.ObjectFieldEdit,
|
||||||
{
|
{
|
||||||
objectSlug: objectNamePlural,
|
objectSlug: objectNamePlural,
|
||||||
fieldSlug: viewGroupFieldMetadataItem?.name ?? '',
|
fieldSlug: recordGroupFieldMetadata?.name ?? '',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -61,11 +65,11 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
currentContentId === 'hiddenRecordGroups' &&
|
currentContentId === 'hiddenRecordGroups' &&
|
||||||
hiddenRecordGroups.length === 0
|
hiddenRecordGroupIds.length === 0
|
||||||
) {
|
) {
|
||||||
onContentChange('recordGroups');
|
onContentChange('recordGroups');
|
||||||
}
|
}
|
||||||
}, [hiddenRecordGroups, currentContentId, onContentChange]);
|
}, [hiddenRecordGroupIds, currentContentId, onContentChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -74,13 +78,13 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
|
|||||||
StartIcon={IconChevronLeft}
|
StartIcon={IconChevronLeft}
|
||||||
onClick={() => onContentChange('recordGroups')}
|
onClick={() => onContentChange('recordGroups')}
|
||||||
>
|
>
|
||||||
Hidden {viewGroupFieldMetadataItem?.label}
|
Hidden {recordGroupFieldMetadata?.label}
|
||||||
</DropdownMenuHeader>
|
</DropdownMenuHeader>
|
||||||
</DropdownMenuItemsContainer>
|
</DropdownMenuItemsContainer>
|
||||||
|
|
||||||
<RecordGroupsVisibilityDropdownSection
|
<RecordGroupsVisibilityDropdownSection
|
||||||
title={`Hidden ${viewGroupFieldMetadataItem?.label}`}
|
title={`Hidden ${recordGroupFieldMetadata?.label}`}
|
||||||
recordGroups={hiddenRecordGroups}
|
recordGroupIds={hiddenRecordGroupIds}
|
||||||
onVisibilityChange={handleRecordGroupVisibilityChange}
|
onVisibilityChange={handleRecordGroupVisibilityChange}
|
||||||
isDraggable={false}
|
isDraggable={false}
|
||||||
showSubheader={false}
|
showSubheader={false}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/h
|
|||||||
|
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import {
|
import {
|
||||||
displayedExportProgress,
|
displayedExportProgress,
|
||||||
useExportRecords,
|
useExportRecords,
|
||||||
@ -26,6 +26,7 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu
|
|||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||||
|
|
||||||
@ -44,6 +45,10 @@ export const ObjectOptionsDropdownMenuContent = () => {
|
|||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
|
recordGroupFieldMetadataComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Escape],
|
[Key.Escape],
|
||||||
() => {
|
() => {
|
||||||
@ -64,10 +69,6 @@ export const ObjectOptionsDropdownMenuContent = () => {
|
|||||||
viewBarId: recordIndexId,
|
viewBarId: recordIndexId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { viewGroupFieldMetadataItem } = useRecordGroups({
|
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { openObjectRecordsSpreasheetImportDialog } =
|
const { openObjectRecordsSpreasheetImportDialog } =
|
||||||
useOpenObjectRecordsSpreadsheetImportDialog(
|
useOpenObjectRecordsSpreadsheetImportDialog(
|
||||||
objectMetadataItem.nameSingular,
|
objectMetadataItem.nameSingular,
|
||||||
@ -113,7 +114,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
|
|||||||
onClick={() => onContentChange('recordGroups')}
|
onClick={() => onContentChange('recordGroups')}
|
||||||
LeftIcon={IconLayoutList}
|
LeftIcon={IconLayoutList}
|
||||||
text="Group by"
|
text="Group by"
|
||||||
contextualText={viewGroupFieldMetadataItem?.label}
|
contextualText={recordGroupFieldMetadata?.label}
|
||||||
hasSubMenu
|
hasSubMenu
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObje
|
|||||||
import { StyledInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect';
|
import { StyledInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect';
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
||||||
import { useSearchRecordGroupField } from '@/object-record/object-options-dropdown/hooks/useSearchRecordGroupField';
|
import { useSearchRecordGroupField } from '@/object-record/object-options-dropdown/hooks/useSearchRecordGroupField';
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||||
import { useHandleRecordGroupField } from '@/object-record/record-index/hooks/useHandleRecordGroupField';
|
import { useHandleRecordGroupField } from '@/object-record/record-index/hooks/useHandleRecordGroupField';
|
||||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
@ -20,6 +20,7 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu
|
|||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
@ -38,9 +39,9 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
|||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { hiddenRecordGroups } = useRecordGroups({
|
const hiddenRecordGroupIds = useRecoilComponentValueV2(
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
hiddenRecordGroupIdsComponentSelector,
|
||||||
});
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
recordGroupFieldSearchInput,
|
recordGroupFieldSearchInput,
|
||||||
@ -68,11 +69,11 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
currentContentId === 'hiddenRecordGroups' &&
|
currentContentId === 'hiddenRecordGroups' &&
|
||||||
hiddenRecordGroups.length === 0
|
hiddenRecordGroupIds.length === 0
|
||||||
) {
|
) {
|
||||||
onContentChange('recordGroups');
|
onContentChange('recordGroups');
|
||||||
}
|
}
|
||||||
}, [hiddenRecordGroups, currentContentId, onContentChange]);
|
}, [hiddenRecordGroupIds, currentContentId, onContentChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -8,24 +8,21 @@ import {
|
|||||||
} from 'twenty-ui';
|
} from 'twenty-ui';
|
||||||
|
|
||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||||
import { RecordGroupSort } from '@/object-record/record-group/types/RecordGroupSort';
|
import { RecordGroupSort } from '@/object-record/record-group/types/RecordGroupSort';
|
||||||
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
|
|
||||||
export const ObjectOptionsDropdownRecordGroupSortContent = () => {
|
export const ObjectOptionsDropdownRecordGroupSortContent = () => {
|
||||||
const {
|
const { currentContentId, onContentChange, closeDropdown } =
|
||||||
currentContentId,
|
useOptionsDropdown();
|
||||||
objectMetadataItem,
|
|
||||||
onContentChange,
|
|
||||||
closeDropdown,
|
|
||||||
} = useOptionsDropdown();
|
|
||||||
|
|
||||||
const { hiddenRecordGroups } = useRecordGroups({
|
const hiddenRecordGroupIds = useRecoilComponentValueV2(
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
hiddenRecordGroupIdsComponentSelector,
|
||||||
});
|
);
|
||||||
|
|
||||||
const setRecordGroupSort = useSetRecoilComponentStateV2(
|
const setRecordGroupSort = useSetRecoilComponentStateV2(
|
||||||
recordIndexRecordGroupSortComponentState,
|
recordIndexRecordGroupSortComponentState,
|
||||||
@ -39,11 +36,11 @@ export const ObjectOptionsDropdownRecordGroupSortContent = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
currentContentId === 'hiddenRecordGroups' &&
|
currentContentId === 'hiddenRecordGroups' &&
|
||||||
hiddenRecordGroups.length === 0
|
hiddenRecordGroupIds.length === 0
|
||||||
) {
|
) {
|
||||||
onContentChange('recordGroups');
|
onContentChange('recordGroups');
|
||||||
}
|
}
|
||||||
}, [hiddenRecordGroups, currentContentId, onContentChange]);
|
}, [hiddenRecordGroupIds, currentContentId, onContentChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -13,8 +13,10 @@ import {
|
|||||||
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
import { useOptionsDropdown } from '@/object-record/object-options-dropdown/hooks/useOptionsDropdown';
|
||||||
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
import { RecordGroupsVisibilityDropdownSection } from '@/object-record/record-group/components/RecordGroupsVisibilityDropdownSection';
|
||||||
import { useRecordGroupReorder } from '@/object-record/record-group/hooks/useRecordGroupReorder';
|
import { useRecordGroupReorder } from '@/object-record/record-group/hooks/useRecordGroupReorder';
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
|
||||||
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
||||||
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
|
import { hiddenRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/hiddenRecordGroupIdsComponentSelector';
|
||||||
|
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||||
import { recordIndexRecordGroupHideComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupHideComponentState';
|
import { recordIndexRecordGroupHideComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupHideComponentState';
|
||||||
import { recordIndexRecordGroupIsDraggableSortComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexRecordGroupIsDraggableSortComponentSelector';
|
import { recordIndexRecordGroupIsDraggableSortComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexRecordGroupIsDraggableSortComponentSelector';
|
||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
@ -26,22 +28,20 @@ import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
|||||||
export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
||||||
const isViewGroupEnabled = useIsFeatureEnabled('IS_VIEW_GROUPS_ENABLED');
|
const isViewGroupEnabled = useIsFeatureEnabled('IS_VIEW_GROUPS_ENABLED');
|
||||||
|
|
||||||
const {
|
const { currentContentId, recordIndexId, onContentChange, resetContent } =
|
||||||
currentContentId,
|
useOptionsDropdown();
|
||||||
viewType,
|
|
||||||
recordIndexId,
|
|
||||||
objectMetadataItem,
|
|
||||||
onContentChange,
|
|
||||||
resetContent,
|
|
||||||
} = useOptionsDropdown();
|
|
||||||
|
|
||||||
const {
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
hiddenRecordGroups,
|
recordGroupFieldMetadataComponentState,
|
||||||
visibleRecordGroups,
|
);
|
||||||
viewGroupFieldMetadataItem,
|
|
||||||
} = useRecordGroups({
|
const visibleRecordGroupIds = useRecoilComponentValueV2(
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
visibleRecordGroupIdsComponentSelector,
|
||||||
});
|
);
|
||||||
|
|
||||||
|
const hiddenRecordGroupIds = useRecoilComponentValueV2(
|
||||||
|
hiddenRecordGroupIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
const isDragableSortRecordGroup = useRecoilComponentValueV2(
|
const isDragableSortRecordGroup = useRecoilComponentValueV2(
|
||||||
recordIndexRecordGroupIsDraggableSortComponentSelector,
|
recordIndexRecordGroupIsDraggableSortComponentSelector,
|
||||||
@ -56,23 +56,21 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
|||||||
handleHideEmptyRecordGroupChange,
|
handleHideEmptyRecordGroupChange,
|
||||||
} = useRecordGroupVisibility({
|
} = useRecordGroupVisibility({
|
||||||
viewBarId: recordIndexId,
|
viewBarId: recordIndexId,
|
||||||
viewType,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleOrderChange: handleRecordGroupOrderChange } =
|
const { handleOrderChange: handleRecordGroupOrderChange } =
|
||||||
useRecordGroupReorder({
|
useRecordGroupReorder({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
|
||||||
viewBarId: recordIndexId,
|
viewBarId: recordIndexId,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
currentContentId === 'hiddenRecordGroups' &&
|
currentContentId === 'hiddenRecordGroups' &&
|
||||||
hiddenRecordGroups.length === 0
|
hiddenRecordGroupIds.length === 0
|
||||||
) {
|
) {
|
||||||
onContentChange('recordGroups');
|
onContentChange('recordGroups');
|
||||||
}
|
}
|
||||||
}, [hiddenRecordGroups, currentContentId, onContentChange]);
|
}, [hiddenRecordGroupIds, currentContentId, onContentChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -86,9 +84,9 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
|||||||
onClick={() => onContentChange('recordGroupFields')}
|
onClick={() => onContentChange('recordGroupFields')}
|
||||||
LeftIcon={IconLayoutList}
|
LeftIcon={IconLayoutList}
|
||||||
text={
|
text={
|
||||||
!viewGroupFieldMetadataItem
|
!recordGroupFieldMetadata
|
||||||
? 'Group by'
|
? 'Group by'
|
||||||
: `Group by "${viewGroupFieldMetadataItem.label}"`
|
: `Group by "${recordGroupFieldMetadata.label}"`
|
||||||
}
|
}
|
||||||
hasSubMenu
|
hasSubMenu
|
||||||
/>
|
/>
|
||||||
@ -108,12 +106,12 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
|||||||
toggleSize="small"
|
toggleSize="small"
|
||||||
/>
|
/>
|
||||||
</DropdownMenuItemsContainer>
|
</DropdownMenuItemsContainer>
|
||||||
{visibleRecordGroups.length > 0 && (
|
{visibleRecordGroupIds.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<RecordGroupsVisibilityDropdownSection
|
<RecordGroupsVisibilityDropdownSection
|
||||||
title="Visible groups"
|
title="Visible groups"
|
||||||
recordGroups={visibleRecordGroups}
|
recordGroupIds={visibleRecordGroupIds}
|
||||||
onDragEnd={handleRecordGroupOrderChange}
|
onDragEnd={handleRecordGroupOrderChange}
|
||||||
onVisibilityChange={handleRecordGroupVisibilityChange}
|
onVisibilityChange={handleRecordGroupVisibilityChange}
|
||||||
isDraggable={isDragableSortRecordGroup}
|
isDraggable={isDragableSortRecordGroup}
|
||||||
@ -121,14 +119,14 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{hiddenRecordGroups.length > 0 && (
|
{hiddenRecordGroupIds.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
<MenuItemNavigate
|
<MenuItemNavigate
|
||||||
onClick={() => onContentChange('hiddenRecordGroups')}
|
onClick={() => onContentChange('hiddenRecordGroups')}
|
||||||
LeftIcon={IconEyeOff}
|
LeftIcon={IconEyeOff}
|
||||||
text={`Hidden ${viewGroupFieldMetadataItem?.label ?? ''}`}
|
text={`Hidden ${recordGroupFieldMetadata?.label ?? ''}`}
|
||||||
/>
|
/>
|
||||||
</DropdownMenuItemsContainer>
|
</DropdownMenuItemsContainer>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -4,10 +4,11 @@ import { useRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
||||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||||
|
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||||
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
|
import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields';
|
||||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||||
@ -32,11 +33,12 @@ export const useObjectOptionsForBoard = ({
|
|||||||
|
|
||||||
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
|
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
|
||||||
const { updateCurrentView } = useUpdateCurrentView(viewBarId);
|
const { updateCurrentView } = useUpdateCurrentView(viewBarId);
|
||||||
const { isCompactModeActiveState } = useRecordBoard(recordBoardId);
|
|
||||||
|
|
||||||
const [isCompactModeActive, setIsCompactModeActive] = useRecoilState(
|
const [isCompactModeActive, setIsCompactModeActive] =
|
||||||
isCompactModeActiveState,
|
useRecoilComponentStateV2(
|
||||||
);
|
isRecordBoardCompactModeActiveComponentState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { DragDropContext, OnDragEndResponder } from '@hello-pangea/dnd'; // Atlassian dnd does not support StrictMode from RN 18, so we use a fork @hello-pangea/dnd https://github.com/atlassian/react-beautiful-dnd/issues/2350
|
import { DragDropContext, OnDragEndResponder } from '@hello-pangea/dnd'; // Atlassian dnd does not support StrictMode from RN 18, so we use a fork @hello-pangea/dnd https://github.com/atlassian/react-beautiful-dnd/issues/2350
|
||||||
import { useContext, useRef } from 'react';
|
import { useContext, useRef } from 'react';
|
||||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope';
|
import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope';
|
||||||
@ -9,11 +9,15 @@ import { RecordBoardHeader } from '@/object-record/record-board/components/Recor
|
|||||||
import { RecordBoardStickyHeaderEffect } from '@/object-record/record-board/components/RecordBoardStickyHeaderEffect';
|
import { RecordBoardStickyHeaderEffect } from '@/object-record/record-board/components/RecordBoardStickyHeaderEffect';
|
||||||
import { RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-board/constants/RecordBoardClickOutsideListenerId';
|
import { RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-board/constants/RecordBoardClickOutsideListenerId';
|
||||||
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
|
import { useRecordBoardSelection } from '@/object-record/record-board/hooks/useRecordBoardSelection';
|
||||||
import { RecordBoardColumn } from '@/object-record/record-board/record-board-column/components/RecordBoardColumn';
|
import { RecordBoardColumn } from '@/object-record/record-board/record-board-column/components/RecordBoardColumn';
|
||||||
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||||
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
import { getDraggedRecordPosition } from '@/object-record/record-board/utils/getDraggedRecordPosition';
|
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 { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||||
@ -21,6 +25,9 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
|||||||
import { useListenClickOutsideV2 } from '@/ui/utilities/pointer-event/hooks/useListenClickOutsideV2';
|
import { useListenClickOutsideV2 } from '@/ui/utilities/pointer-event/hooks/useListenClickOutsideV2';
|
||||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
import { useScrollRestoration } from '~/hooks/useScrollRestoration';
|
import { useScrollRestoration } from '~/hooks/useScrollRestoration';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -58,14 +65,17 @@ export const RecordBoard = () => {
|
|||||||
useContext(RecordBoardContext);
|
useContext(RecordBoardContext);
|
||||||
const boardRef = useRef<HTMLDivElement>(null);
|
const boardRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const {
|
const visibleRecordGroupIds = useRecoilComponentValueV2(
|
||||||
columnIdsState,
|
visibleRecordGroupIdsComponentSelector,
|
||||||
columnsFamilySelector,
|
);
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
allRecordIdsSelector,
|
|
||||||
} = useRecordBoardStates(recordBoardId);
|
|
||||||
|
|
||||||
const columnIds = useRecoilValue(columnIdsState);
|
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordIndexAllRowIdsComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const { resetRecordSelection, setRecordAsSelected } =
|
const { resetRecordSelection, setRecordAsSelected } =
|
||||||
useRecordBoardSelection(recordBoardId);
|
useRecordBoardSelection(recordBoardId);
|
||||||
@ -85,15 +95,16 @@ export const RecordBoard = () => {
|
|||||||
const selectAll = useRecoilCallback(
|
const selectAll = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
() => {
|
() => {
|
||||||
const allRecordIds = snapshot
|
const allRecordIds = getSnapshotValue(
|
||||||
.getLoadable(allRecordIdsSelector())
|
snapshot,
|
||||||
.getValue();
|
recordIndexAllRowIdsState,
|
||||||
|
);
|
||||||
|
|
||||||
for (const recordId of allRecordIds) {
|
for (const recordId of allRecordIds) {
|
||||||
setRecordAsSelected(recordId, true);
|
setRecordAsSelected(recordId, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[allRecordIdsSelector, setRecordAsSelected],
|
[recordIndexAllRowIdsState, setRecordAsSelected],
|
||||||
);
|
);
|
||||||
|
|
||||||
useScopedHotkeys('ctrl+a,meta+a', selectAll, TableHotkeyScope.Table);
|
useScopedHotkeys('ctrl+a,meta+a', selectAll, TableHotkeyScope.Table);
|
||||||
@ -111,42 +122,40 @@ export const RecordBoard = () => {
|
|||||||
if (!result.destination) return;
|
if (!result.destination) return;
|
||||||
|
|
||||||
const draggedRecordId = result.draggableId;
|
const draggedRecordId = result.draggableId;
|
||||||
const sourceColumnId = result.source.droppableId;
|
const sourceRecordGroupId = result.source.droppableId;
|
||||||
const destinationColumnId = result.destination.droppableId;
|
const destinationRecordGroupId = result.destination.droppableId;
|
||||||
const destinationIndexInColumn = result.destination.index;
|
const destinationIndexInColumn = result.destination.index;
|
||||||
|
|
||||||
if (!destinationColumnId || !selectFieldMetadataItem) return;
|
if (!destinationRecordGroupId || !selectFieldMetadataItem) return;
|
||||||
|
|
||||||
const column = snapshot
|
const recordGroup = getSnapshotValue(
|
||||||
.getLoadable(columnsFamilySelector(destinationColumnId))
|
snapshot,
|
||||||
.getValue();
|
recordGroupDefinitionFamilyState(destinationRecordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
if (!column) return;
|
if (!recordGroup) return;
|
||||||
|
|
||||||
const destinationColumnRecordIds = snapshot
|
const destinationRecordByGroupIds = getSnapshotValue(
|
||||||
.getLoadable(recordIdsByColumnIdFamilyState(destinationColumnId))
|
snapshot,
|
||||||
.getValue();
|
recordIndexRowIdsByGroupFamilyState(destinationRecordGroupId),
|
||||||
const otherRecordsInDestinationColumn =
|
);
|
||||||
sourceColumnId === destinationColumnId
|
const otherRecordIdsInDestinationColumn =
|
||||||
? destinationColumnRecordIds.filter(
|
sourceRecordGroupId === destinationRecordGroupId
|
||||||
|
? destinationRecordByGroupIds.filter(
|
||||||
(recordId) => recordId !== draggedRecordId,
|
(recordId) => recordId !== draggedRecordId,
|
||||||
)
|
)
|
||||||
: destinationColumnRecordIds;
|
: destinationRecordByGroupIds;
|
||||||
|
|
||||||
const recordBeforeId =
|
const recordBeforeId =
|
||||||
otherRecordsInDestinationColumn[destinationIndexInColumn - 1];
|
otherRecordIdsInDestinationColumn[destinationIndexInColumn - 1];
|
||||||
const recordBefore = recordBeforeId
|
const recordBefore = recordBeforeId
|
||||||
? snapshot
|
? getSnapshotValue(snapshot, recordStoreFamilyState(recordBeforeId))
|
||||||
.getLoadable(recordStoreFamilyState(recordBeforeId))
|
|
||||||
.getValue()
|
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const recordAfterId =
|
const recordAfterId =
|
||||||
otherRecordsInDestinationColumn[destinationIndexInColumn];
|
otherRecordIdsInDestinationColumn[destinationIndexInColumn];
|
||||||
const recordAfter = recordAfterId
|
const recordAfter = recordAfterId
|
||||||
? snapshot
|
? getSnapshotValue(snapshot, recordStoreFamilyState(recordAfterId))
|
||||||
.getLoadable(recordStoreFamilyState(recordAfterId))
|
|
||||||
.getValue()
|
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const draggedRecordPosition = getDraggedRecordPosition(
|
const draggedRecordPosition = getDraggedRecordPosition(
|
||||||
@ -157,14 +166,13 @@ export const RecordBoard = () => {
|
|||||||
updateOneRecord({
|
updateOneRecord({
|
||||||
idToUpdate: draggedRecordId,
|
idToUpdate: draggedRecordId,
|
||||||
updateOneRecordInput: {
|
updateOneRecordInput: {
|
||||||
[selectFieldMetadataItem.name]: column.value,
|
[selectFieldMetadataItem.name]: recordGroup.value,
|
||||||
position: draggedRecordPosition,
|
position: draggedRecordPosition,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
columnsFamilySelector,
|
recordIndexRowIdsByGroupFamilyState,
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
selectFieldMetadataItem,
|
selectFieldMetadataItem,
|
||||||
updateOneRecord,
|
updateOneRecord,
|
||||||
],
|
],
|
||||||
@ -182,32 +190,36 @@ export const RecordBoard = () => {
|
|||||||
onColumnsChange={() => {}}
|
onColumnsChange={() => {}}
|
||||||
onFieldsChange={() => {}}
|
onFieldsChange={() => {}}
|
||||||
>
|
>
|
||||||
<ScrollWrapper contextProviderName="recordBoard">
|
<RecordBoardComponentInstanceContext.Provider
|
||||||
<RecordBoardStickyHeaderEffect />
|
value={{ instanceId: recordBoardId }}
|
||||||
<StyledContainerContainer>
|
>
|
||||||
<RecordBoardHeader />
|
<ScrollWrapper contextProviderName="recordBoard">
|
||||||
<StyledBoardContentContainer>
|
<RecordBoardStickyHeaderEffect />
|
||||||
<StyledContainer ref={boardRef}>
|
<StyledContainerContainer>
|
||||||
<DragDropContext onDragEnd={handleDragEnd}>
|
<RecordBoardHeader />
|
||||||
<StyledColumnContainer>
|
<StyledBoardContentContainer>
|
||||||
{columnIds.map((columnId) => (
|
<StyledContainer ref={boardRef}>
|
||||||
<RecordBoardColumn
|
<DragDropContext onDragEnd={handleDragEnd}>
|
||||||
key={columnId}
|
<StyledColumnContainer>
|
||||||
recordBoardColumnId={columnId}
|
{visibleRecordGroupIds.map((recordGroupId) => (
|
||||||
/>
|
<RecordBoardColumn
|
||||||
))}
|
key={recordGroupId}
|
||||||
</StyledColumnContainer>
|
recordBoardColumnId={recordGroupId}
|
||||||
</DragDropContext>
|
/>
|
||||||
</StyledContainer>
|
))}
|
||||||
<RecordBoardScrollRestoreEffect />
|
</StyledColumnContainer>
|
||||||
<DragSelect
|
</DragDropContext>
|
||||||
dragSelectable={boardRef}
|
</StyledContainer>
|
||||||
onDragSelectionStart={resetRecordSelection}
|
<RecordBoardScrollRestoreEffect />
|
||||||
onDragSelectionChange={setRecordAsSelected}
|
<DragSelect
|
||||||
/>
|
dragSelectable={boardRef}
|
||||||
</StyledBoardContentContainer>
|
onDragSelectionStart={resetRecordSelection}
|
||||||
</StyledContainerContainer>
|
onDragSelectionChange={setRecordAsSelected}
|
||||||
</ScrollWrapper>
|
/>
|
||||||
|
</StyledBoardContentContainer>
|
||||||
|
</StyledContainerContainer>
|
||||||
|
</ScrollWrapper>
|
||||||
|
</RecordBoardComponentInstanceContext.Provider>
|
||||||
</RecordBoardScope>
|
</RecordBoardScope>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordBoardColumnHeaderWrapper } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderWrapper';
|
import { RecordBoardColumnHeaderWrapper } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderWrapper';
|
||||||
|
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
const StyledHeaderContainer = styled.div`
|
const StyledHeaderContainer = styled.div`
|
||||||
@ -24,14 +23,17 @@ const StyledHeaderContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const RecordBoardHeader = () => {
|
export const RecordBoardHeader = () => {
|
||||||
const { columnIdsState } = useRecordBoardStates();
|
const visibleRecordGroupIds = useRecoilComponentValueV2(
|
||||||
|
visibleRecordGroupIdsComponentSelector,
|
||||||
const columnIds = useRecoilValue(columnIdsState);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledHeaderContainer id="record-board-header">
|
<StyledHeaderContainer id="record-board-header">
|
||||||
{columnIds.map((columnId) => (
|
{visibleRecordGroupIds.map((recordGroupId) => (
|
||||||
<RecordBoardColumnHeaderWrapper columnId={columnId} key={columnId} />
|
<RecordBoardColumnHeaderWrapper
|
||||||
|
columnId={recordGroupId}
|
||||||
|
key={recordGroupId}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</StyledHeaderContainer>
|
</StyledHeaderContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,103 +0,0 @@
|
|||||||
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
|
|
||||||
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
|
||||||
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
|
||||||
import { isRecordBoardFetchingRecordsByColumnFamilyState } from '@/object-record/record-board/states/isRecordBoardFetchingRecordsByColumnFamilyState';
|
|
||||||
import { isRecordBoardFetchingRecordsComponentState } from '@/object-record/record-board/states/isRecordBoardFetchingRecordsComponentState';
|
|
||||||
import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
|
|
||||||
import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState';
|
|
||||||
import { recordBoardFiltersComponentState } from '@/object-record/record-board/states/recordBoardFiltersComponentState';
|
|
||||||
import { recordBoardKanbanFieldMetadataNameComponentState } from '@/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState';
|
|
||||||
import { recordBoardObjectSingularNameComponentState } from '@/object-record/record-board/states/recordBoardObjectSingularNameComponentState';
|
|
||||||
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
|
||||||
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
|
||||||
import { recordBoardSortsComponentState } from '@/object-record/record-board/states/recordBoardSortsComponentState';
|
|
||||||
import { recordBoardAllRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardAllRecordIdsComponentSelector';
|
|
||||||
import { recordBoardColumnsComponentFamilySelector } from '@/object-record/record-board/states/selectors/recordBoardColumnsComponentFamilySelector';
|
|
||||||
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
|
||||||
import { recordBoardShouldFetchMoreComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector';
|
|
||||||
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
|
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
|
||||||
import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId';
|
|
||||||
import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState';
|
|
||||||
import { extractComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/extractComponentReadOnlySelector';
|
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
|
||||||
|
|
||||||
export const useRecordBoardStates = (recordBoardId?: string) => {
|
|
||||||
const scopeId = useAvailableScopeIdOrThrow(
|
|
||||||
RecordBoardScopeInternalContext,
|
|
||||||
getScopeIdOrUndefinedFromComponentId(recordBoardId),
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scopeId,
|
|
||||||
objectSingularNameState: extractComponentState(
|
|
||||||
recordBoardObjectSingularNameComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
kanbanFieldMetadataNameState: extractComponentState(
|
|
||||||
recordBoardKanbanFieldMetadataNameComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
isFetchingRecordState: extractComponentState(
|
|
||||||
isRecordBoardFetchingRecordsComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
isFetchingRecordsByColumnState: extractComponentFamilyState(
|
|
||||||
isRecordBoardFetchingRecordsByColumnFamilyState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
columnIdsState: extractComponentState(
|
|
||||||
recordBoardColumnIdsComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
columnsFamilySelector: extractComponentFamilyState(
|
|
||||||
recordBoardColumnsComponentFamilySelector,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
|
|
||||||
filtersState: extractComponentState(
|
|
||||||
recordBoardFiltersComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
sortsState: extractComponentState(recordBoardSortsComponentState, scopeId),
|
|
||||||
fieldDefinitionsState: extractComponentState(
|
|
||||||
recordBoardFieldDefinitionsComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
visibleFieldDefinitionsState: extractComponentReadOnlySelector(
|
|
||||||
recordBoardVisibleFieldDefinitionsComponentSelector,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
|
|
||||||
recordIdsByColumnIdFamilyState: extractComponentFamilyState(
|
|
||||||
recordBoardRecordIdsByColumnIdComponentFamilyState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
isRecordBoardCardSelectedFamilyState: extractComponentFamilyState(
|
|
||||||
isRecordBoardCardSelectedComponentFamilyState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
allRecordIdsSelector: extractComponentReadOnlySelector(
|
|
||||||
recordBoardAllRecordIdsComponentSelector,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
selectedRecordIdsSelector: extractComponentReadOnlySelector(
|
|
||||||
recordBoardSelectedRecordIdsComponentSelector,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
|
|
||||||
isCompactModeActiveState: extractComponentState(
|
|
||||||
isRecordBoardCompactModeActiveComponentState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
|
|
||||||
shouldFetchMoreInColumnFamilyState: extractComponentFamilyState(
|
|
||||||
recordBoardShouldFetchMoreInColumnComponentFamilyState,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
shouldFetchMoreSelector: extractComponentReadOnlySelector(
|
|
||||||
recordBoardShouldFetchMoreComponentSelector,
|
|
||||||
scopeId,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
|
||||||
import { sortRecordGroupDefinitions } from '@/object-record/record-group/utils/sortRecordGroupDefinitions';
|
|
||||||
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
|
||||||
|
|
||||||
export const useSetRecordBoardColumns = (recordBoardId?: string) => {
|
|
||||||
const { scopeId, columnIdsState, columnsFamilySelector } =
|
|
||||||
useRecordBoardStates(recordBoardId);
|
|
||||||
|
|
||||||
const recordGroupSort = useRecoilComponentValueV2(
|
|
||||||
recordIndexRecordGroupSortComponentState,
|
|
||||||
recordBoardId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const setColumns = useRecoilCallback(
|
|
||||||
({ set, snapshot }) =>
|
|
||||||
(columns: RecordGroupDefinition[]) => {
|
|
||||||
const currentColumnsIds = snapshot
|
|
||||||
.getLoadable(columnIdsState)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const sortedColumns = sortRecordGroupDefinitions(
|
|
||||||
columns,
|
|
||||||
recordGroupSort,
|
|
||||||
);
|
|
||||||
|
|
||||||
const columnIds = sortedColumns
|
|
||||||
.filter(({ isVisible }) => isVisible)
|
|
||||||
.map(({ id }) => id);
|
|
||||||
|
|
||||||
if (!isDeeplyEqual(currentColumnsIds, columnIds)) {
|
|
||||||
set(columnIdsState, columnIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
columns.forEach((column) => {
|
|
||||||
const currentColumn = snapshot
|
|
||||||
.getLoadable(columnsFamilySelector(column.id))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (isDeeplyEqual(currentColumn, column)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set(columnsFamilySelector(column.id), column);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[columnIdsState, recordGroupSort, columnsFamilySelector],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scopeId,
|
|
||||||
setColumns,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
|
||||||
import { sortRecordsByPosition } from '@/object-record/utils/sortRecordsByPosition';
|
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
|
||||||
|
|
||||||
export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
|
|
||||||
const {
|
|
||||||
scopeId,
|
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
columnsFamilySelector,
|
|
||||||
columnIdsState,
|
|
||||||
kanbanFieldMetadataNameState,
|
|
||||||
} = useRecordBoardStates(recordBoardId);
|
|
||||||
|
|
||||||
const setRecordIds = useRecoilCallback(
|
|
||||||
({ set, snapshot }) =>
|
|
||||||
(records: ObjectRecord[]) => {
|
|
||||||
const columnIds = snapshot.getLoadable(columnIdsState).getValue();
|
|
||||||
|
|
||||||
columnIds.forEach((columnId) => {
|
|
||||||
const column = snapshot
|
|
||||||
.getLoadable(columnsFamilySelector(columnId))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const existingColumnRecordIds = snapshot
|
|
||||||
.getLoadable(recordIdsByColumnIdFamilyState(columnId))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const kanbanFieldMetadataName = snapshot
|
|
||||||
.getLoadable(kanbanFieldMetadataNameState)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (!kanbanFieldMetadataName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const columnRecordIds = records
|
|
||||||
.filter(
|
|
||||||
(record) => record[kanbanFieldMetadataName] === column?.value,
|
|
||||||
)
|
|
||||||
.sort(sortRecordsByPosition)
|
|
||||||
.map((record) => record.id);
|
|
||||||
|
|
||||||
if (!isDeeplyEqual(existingColumnRecordIds, columnRecordIds)) {
|
|
||||||
set(recordIdsByColumnIdFamilyState(columnId), columnRecordIds);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[
|
|
||||||
columnIdsState,
|
|
||||||
columnsFamilySelector,
|
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
kanbanFieldMetadataNameState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scopeId,
|
|
||||||
setRecordIds,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
|
||||||
import { sortRecordsByPosition } from '@/object-record/utils/sortRecordsByPosition';
|
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
|
||||||
|
|
||||||
export const useSetRecordIdsForColumn = (recordBoardId?: string) => {
|
|
||||||
const {
|
|
||||||
scopeId,
|
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
columnsFamilySelector,
|
|
||||||
kanbanFieldMetadataNameState,
|
|
||||||
} = useRecordBoardStates(recordBoardId);
|
|
||||||
|
|
||||||
const setRecordIdsForColumn = useRecoilCallback(
|
|
||||||
({ set, snapshot }) =>
|
|
||||||
(columnId: string, records: ObjectRecord[]) => {
|
|
||||||
const column = snapshot
|
|
||||||
.getLoadable(columnsFamilySelector(columnId))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const existingColumnRecordIds = snapshot
|
|
||||||
.getLoadable(recordIdsByColumnIdFamilyState(columnId))
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const kanbanFieldMetadataName = snapshot
|
|
||||||
.getLoadable(kanbanFieldMetadataNameState)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (!kanbanFieldMetadataName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const columnRecordIds = records
|
|
||||||
.filter((record) => record[kanbanFieldMetadataName] === column?.value)
|
|
||||||
.sort(sortRecordsByPosition)
|
|
||||||
.map((record) => record.id);
|
|
||||||
|
|
||||||
if (!isDeeplyEqual(existingColumnRecordIds, columnRecordIds)) {
|
|
||||||
set(recordIdsByColumnIdFamilyState(columnId), columnRecordIds);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
columnsFamilySelector,
|
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
kanbanFieldMetadataNameState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scopeId,
|
|
||||||
setRecordIdsForColumn,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { useSetRecordBoardColumns } from '@/object-record/record-board/hooks/internal/useSetRecordBoardColumns';
|
|
||||||
import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds';
|
|
||||||
import { useSetRecordIdsForColumn } from '@/object-record/record-board/hooks/internal/useSetRecordIdsForColumn';
|
|
||||||
|
|
||||||
export const useRecordBoard = (recordBoardId?: string) => {
|
|
||||||
const {
|
|
||||||
scopeId,
|
|
||||||
fieldDefinitionsState,
|
|
||||||
objectSingularNameState,
|
|
||||||
selectedRecordIdsSelector,
|
|
||||||
isCompactModeActiveState,
|
|
||||||
kanbanFieldMetadataNameState,
|
|
||||||
shouldFetchMoreSelector,
|
|
||||||
isFetchingRecordsByColumnState,
|
|
||||||
} = useRecordBoardStates(recordBoardId);
|
|
||||||
|
|
||||||
const { setColumns } = useSetRecordBoardColumns(recordBoardId);
|
|
||||||
const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId);
|
|
||||||
const { setRecordIdsForColumn } = useSetRecordIdsForColumn(recordBoardId);
|
|
||||||
|
|
||||||
const setFieldDefinitions = useSetRecoilState(fieldDefinitionsState);
|
|
||||||
const setObjectSingularName = useSetRecoilState(objectSingularNameState);
|
|
||||||
const setKanbanFieldMetadataName = useSetRecoilState(
|
|
||||||
kanbanFieldMetadataNameState,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
scopeId,
|
|
||||||
setColumns,
|
|
||||||
setRecordIds,
|
|
||||||
setFieldDefinitions,
|
|
||||||
setObjectSingularName,
|
|
||||||
setKanbanFieldMetadataName,
|
|
||||||
selectedRecordIdsSelector,
|
|
||||||
isCompactModeActiveState,
|
|
||||||
shouldFetchMoreSelector,
|
|
||||||
setRecordIdsForColumn,
|
|
||||||
isFetchingRecordsByColumnState,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -2,13 +2,25 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
|
|
||||||
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
||||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||||
|
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
|
|
||||||
export const useRecordBoardSelection = (recordBoardId: string) => {
|
export const useRecordBoardSelection = (recordBoardId: string) => {
|
||||||
const { selectedRecordIdsSelector, isRecordBoardCardSelectedFamilyState } =
|
const isRecordBoardCardSelectedFamilyState =
|
||||||
useRecordBoardStates(recordBoardId);
|
useRecoilComponentCallbackStateV2(
|
||||||
|
isRecordBoardCardSelectedComponentFamilyState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordBoardSelectedRecordIdsSelector =
|
||||||
|
useRecoilComponentCallbackStateV2(
|
||||||
|
recordBoardSelectedRecordIdsComponentSelector,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
const isActionMenuDropdownOpenState = extractComponentState(
|
const isActionMenuDropdownOpenState = extractComponentState(
|
||||||
isDropdownOpenComponentState,
|
isDropdownOpenComponentState,
|
||||||
@ -22,9 +34,10 @@ export const useRecordBoardSelection = (recordBoardId: string) => {
|
|||||||
() => {
|
() => {
|
||||||
set(isActionMenuDropdownOpenState, false);
|
set(isActionMenuDropdownOpenState, false);
|
||||||
|
|
||||||
const recordIds = snapshot
|
const recordIds = getSnapshotValue(
|
||||||
.getLoadable(selectedRecordIdsSelector())
|
snapshot,
|
||||||
.getValue();
|
recordBoardSelectedRecordIdsSelector,
|
||||||
|
);
|
||||||
|
|
||||||
for (const recordId of recordIds) {
|
for (const recordId of recordIds) {
|
||||||
set(isRecordBoardCardSelectedFamilyState(recordId), false);
|
set(isRecordBoardCardSelectedFamilyState(recordId), false);
|
||||||
@ -32,7 +45,7 @@ export const useRecordBoardSelection = (recordBoardId: string) => {
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
isActionMenuDropdownOpenState,
|
isActionMenuDropdownOpenState,
|
||||||
selectedRecordIdsSelector,
|
recordBoardSelectedRecordIdsSelector,
|
||||||
isRecordBoardCardSelectedFamilyState,
|
isRecordBoardCardSelectedFamilyState,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,110 @@
|
|||||||
|
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 { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
import { sortRecordsByPosition } from '@/object-record/utils/sortRecordsByPosition';
|
||||||
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
|
export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
|
||||||
|
const visibleRecordGroupIdsSelector = useRecoilComponentCallbackStateV2(
|
||||||
|
visibleRecordGroupIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordGroupFieldMetadataState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordGroupFieldMetadataComponentState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordIndexAllRowIdsComponentState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setRecordIds = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
(records: ObjectRecord[]) => {
|
||||||
|
const existingAllRowIds = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordIndexAllRowIdsState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordGroupIds = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
visibleRecordGroupIdsSelector,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const recordGroupId of recordGroupIds) {
|
||||||
|
const recordGroup = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingRecordGroupRowIds = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordGroupFieldMetadata = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupFieldMetadataState,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordGroupFieldMetadata)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recordGroupRowIds = records
|
||||||
|
.filter(
|
||||||
|
(record) =>
|
||||||
|
record[recordGroupFieldMetadata.name] === recordGroup?.value,
|
||||||
|
)
|
||||||
|
.sort(sortRecordsByPosition)
|
||||||
|
.map((record) => record.id);
|
||||||
|
|
||||||
|
if (!isDeeplyEqual(existingRecordGroupRowIds, recordGroupRowIds)) {
|
||||||
|
set(
|
||||||
|
recordIndexRowIdsByGroupFamilyState(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,
|
||||||
|
recordGroupFieldMetadataState,
|
||||||
|
recordIndexAllRowIdsState,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
setRecordIds,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
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 { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
import { sortRecordsByPosition } from '@/object-record/utils/sortRecordsByPosition';
|
||||||
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
|
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 setRecordIdsForColumn = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
(currentRecordGroupId: string, records: ObjectRecord[]) => {
|
||||||
|
const existingAllRowIds = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordIndexAllRowIdsState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordGroupIds = getSnapshotValue(snapshot, recordGroupIdsState);
|
||||||
|
|
||||||
|
const recordGroup = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupDefinitionFamilyState(currentRecordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingRecordGroupRowIds = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordIndexRowIdsByGroupFamilyState(currentRecordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordGroupFieldMetadata = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupFieldMetadataState,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordGroupFieldMetadata)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recordGroupRowIds = records
|
||||||
|
.filter(
|
||||||
|
(record) =>
|
||||||
|
record[recordGroupFieldMetadata.name] === recordGroup?.value,
|
||||||
|
)
|
||||||
|
.sort(sortRecordsByPosition)
|
||||||
|
.map((record) => record.id);
|
||||||
|
|
||||||
|
if (!isDeeplyEqual(existingRecordGroupRowIds, recordGroupRowIds)) {
|
||||||
|
set(
|
||||||
|
recordIndexRowIdsByGroupFamilyState(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,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
setRecordIdsForColumn,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -3,9 +3,11 @@ import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-me
|
|||||||
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
||||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||||
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
||||||
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
|
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
|
||||||
|
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||||
|
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
||||||
|
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
|
||||||
import {
|
import {
|
||||||
FieldContext,
|
FieldContext,
|
||||||
RecordUpdateHook,
|
RecordUpdateHook,
|
||||||
@ -22,11 +24,13 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
|||||||
import { TextInput } from '@/ui/input/components/TextInput';
|
import { TextInput } from '@/ui/input/components/TextInput';
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts';
|
import { RecordBoardScrollWrapperContext } from '@/ui/utilities/scroll/contexts/ScrollWrapperContexts';
|
||||||
|
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { ReactNode, useContext, useState } from 'react';
|
import { ReactNode, useContext, useState } from 'react';
|
||||||
import { InView, useInView } from 'react-intersection-observer';
|
import { InView, useInView } from 'react-intersection-observer';
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import {
|
import {
|
||||||
AnimatedEaseInOut,
|
AnimatedEaseInOut,
|
||||||
AvatarChipVariant,
|
AvatarChipVariant,
|
||||||
@ -157,27 +161,30 @@ export const RecordBoardCard = ({
|
|||||||
onCreateSuccess?: () => void;
|
onCreateSuccess?: () => void;
|
||||||
position?: 'first' | 'last';
|
position?: 'first' | 'last';
|
||||||
}) => {
|
}) => {
|
||||||
const [newLabelValue, setNewLabelValue] = useState('');
|
|
||||||
const { handleBlur, handleInputEnter } = useAddNewCard();
|
|
||||||
const { recordId } = useContext(RecordBoardCardContext);
|
const { recordId } = useContext(RecordBoardCardContext);
|
||||||
|
|
||||||
|
const [newLabelValue, setNewLabelValue] = useState('');
|
||||||
|
|
||||||
|
const { handleBlur, handleInputEnter } = useAddNewCard();
|
||||||
|
|
||||||
const { updateOneRecord, objectMetadataItem } =
|
const { updateOneRecord, objectMetadataItem } =
|
||||||
useContext(RecordBoardContext);
|
useContext(RecordBoardContext);
|
||||||
const {
|
|
||||||
isCompactModeActiveState,
|
const visibleFieldDefinitions = useRecoilComponentValueV2(
|
||||||
isRecordBoardCardSelectedFamilyState,
|
recordBoardVisibleFieldDefinitionsComponentSelector,
|
||||||
visibleFieldDefinitionsState,
|
);
|
||||||
} = useRecordBoardStates();
|
|
||||||
const isCompactModeActive = useRecoilValue(isCompactModeActiveState);
|
const isCompactModeActive = useRecoilComponentValueV2(
|
||||||
|
isRecordBoardCompactModeActiveComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const [isCardExpanded, setIsCardExpanded] = useState(false);
|
const [isCardExpanded, setIsCardExpanded] = useState(false);
|
||||||
|
|
||||||
const [isCurrentCardSelected, setIsCurrentCardSelected] = useRecoilState(
|
const [isCurrentCardSelected, setIsCurrentCardSelected] =
|
||||||
isRecordBoardCardSelectedFamilyState(recordId),
|
useRecoilComponentFamilyStateV2(
|
||||||
);
|
isRecordBoardCardSelectedComponentFamilyState,
|
||||||
|
recordId,
|
||||||
const visibleFieldDefinitions = useRecoilValue(
|
);
|
||||||
visibleFieldDefinitionsState(),
|
|
||||||
);
|
|
||||||
|
|
||||||
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Droppable } from '@hello-pangea/dnd';
|
import { Droppable } from '@hello-pangea/dnd';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordBoardColumnCardsContainer } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer';
|
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 { 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 { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
const StyledColumn = styled.div`
|
const StyledColumn = styled.div`
|
||||||
background-color: ${({ theme }) => theme.background.primary};
|
background-color: ${({ theme }) => theme.background.primary};
|
||||||
@ -25,27 +27,26 @@ type RecordBoardColumnProps = {
|
|||||||
export const RecordBoardColumn = ({
|
export const RecordBoardColumn = ({
|
||||||
recordBoardColumnId,
|
recordBoardColumnId,
|
||||||
}: RecordBoardColumnProps) => {
|
}: RecordBoardColumnProps) => {
|
||||||
const { columnsFamilySelector, recordIdsByColumnIdFamilyState } =
|
const recordGroupDefinition = useRecoilValue(
|
||||||
useRecordBoardStates();
|
recordGroupDefinitionFamilyState(recordBoardColumnId),
|
||||||
const columnDefinition = useRecoilValue(
|
|
||||||
columnsFamilySelector(recordBoardColumnId),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordIds = useRecoilValue(
|
const recordRowIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||||
recordIdsByColumnIdFamilyState(recordBoardColumnId),
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
|
recordBoardColumnId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!columnDefinition) {
|
if (!recordGroupDefinition) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordBoardColumnContext.Provider
|
<RecordBoardColumnContext.Provider
|
||||||
value={{
|
value={{
|
||||||
columnDefinition: columnDefinition,
|
columnDefinition: recordGroupDefinition,
|
||||||
recordCount: recordIds.length,
|
recordCount: recordRowIdsByGroup.length,
|
||||||
columnId: recordBoardColumnId,
|
columnId: recordBoardColumnId,
|
||||||
recordIds,
|
recordIds: recordRowIdsByGroup,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Droppable droppableId={recordBoardColumnId}>
|
<Droppable droppableId={recordBoardColumnId}>
|
||||||
@ -53,7 +54,7 @@ export const RecordBoardColumn = ({
|
|||||||
<StyledColumn>
|
<StyledColumn>
|
||||||
<RecordBoardColumnCardsContainer
|
<RecordBoardColumnCardsContainer
|
||||||
droppableProvided={droppableProvided}
|
droppableProvided={droppableProvided}
|
||||||
recordIds={recordIds}
|
recordIds={recordRowIdsByGroup}
|
||||||
/>
|
/>
|
||||||
</StyledColumn>
|
</StyledColumn>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { useRecoilValue } from 'recoil';
|
|||||||
|
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordBoardColumnCardContainerSkeletonLoader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader';
|
import { RecordBoardColumnCardContainerSkeletonLoader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader';
|
||||||
import { RecordBoardColumnCardsMemo } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsMemo';
|
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 { RecordBoardColumnFetchMoreLoader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnFetchMoreLoader';
|
||||||
@ -15,7 +14,10 @@ import { RecordBoardColumnNewRecordButton } from '@/object-record/record-board/r
|
|||||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||||
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
|
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
|
||||||
import { getNumberOfCardsPerColumnForSkeletonLoading } from '@/object-record/record-board/record-board-column/utils/getNumberOfCardsPerColumnForSkeletonLoading';
|
import { getNumberOfCardsPerColumnForSkeletonLoading } from '@/object-record/record-board/record-board-column/utils/getNumberOfCardsPerColumnForSkeletonLoading';
|
||||||
|
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
||||||
|
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
|
||||||
import { isRecordIndexBoardColumnLoadingFamilyState } from '@/object-record/states/isRecordBoardColumnLoadingFamilyState';
|
import { isRecordIndexBoardColumnLoadingFamilyState } from '@/object-record/states/isRecordBoardColumnLoadingFamilyState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
const StyledColumnCardsContainer = styled.div`
|
const StyledColumnCardsContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -56,16 +58,16 @@ export const RecordBoardColumnCardsContainer = ({
|
|||||||
isRecordIndexBoardColumnLoadingFamilyState(columnId),
|
isRecordIndexBoardColumnLoadingFamilyState(columnId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { isCompactModeActiveState, visibleFieldDefinitionsState } =
|
const visibleFieldDefinitions = useRecoilComponentValueV2(
|
||||||
useRecordBoardStates();
|
recordBoardVisibleFieldDefinitionsComponentSelector,
|
||||||
|
|
||||||
const visibleFieldDefinitions = useRecoilValue(
|
|
||||||
visibleFieldDefinitionsState(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const numberOfFields = visibleFieldDefinitions.length;
|
const numberOfFields = visibleFieldDefinitions.length;
|
||||||
|
|
||||||
const isCompactModeActive = useRecoilValue(isCompactModeActiveState);
|
const isCompactModeActive = useRecoilComponentValueV2(
|
||||||
|
isRecordBoardCompactModeActiveComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const { isOpportunitiesCompanyFieldDisabled } =
|
const { isOpportunitiesCompanyFieldDisabled } =
|
||||||
useIsOpportunitiesCompanyFieldDisabled();
|
useIsOpportunitiesCompanyFieldDisabled();
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { useRecordGroupActions } from '@/object-record/record-group/hooks/useRec
|
|||||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
|
||||||
import { MenuItem } from 'twenty-ui';
|
import { MenuItem } from 'twenty-ui';
|
||||||
|
|
||||||
const StyledMenuContainer = styled.div`
|
const StyledMenuContainer = styled.div`
|
||||||
@ -26,9 +25,7 @@ export const RecordBoardColumnDropdownMenu = ({
|
|||||||
}: RecordBoardColumnDropdownMenuProps) => {
|
}: RecordBoardColumnDropdownMenuProps) => {
|
||||||
const boardColumnMenuRef = useRef<HTMLDivElement>(null);
|
const boardColumnMenuRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const recordGroupActions = useRecordGroupActions({
|
const recordGroupActions = useRecordGroupActions();
|
||||||
viewType: ViewType.Kanban,
|
|
||||||
});
|
|
||||||
|
|
||||||
const closeMenu = useCallback(() => {
|
const closeMenu = useCallback(() => {
|
||||||
onClose();
|
onClose();
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
import { useContext, useEffect } from 'react';
|
import { useContext, useEffect } from 'react';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
import styled from '@emotion/styled';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
|
||||||
import { GRAY_SCALE } from 'twenty-ui';
|
import { GRAY_SCALE } from 'twenty-ui';
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||||
|
import { isRecordBoardFetchingRecordsByColumnFamilyState } from '@/object-record/record-board/states/isRecordBoardFetchingRecordsByColumnFamilyState';
|
||||||
|
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
||||||
|
import { useSetRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentFamilyStateV2';
|
||||||
|
|
||||||
const StyledText = styled.div`
|
const StyledText = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -19,15 +21,14 @@ const StyledText = styled.div`
|
|||||||
|
|
||||||
export const RecordBoardColumnFetchMoreLoader = () => {
|
export const RecordBoardColumnFetchMoreLoader = () => {
|
||||||
const { columnDefinition } = useContext(RecordBoardColumnContext);
|
const { columnDefinition } = useContext(RecordBoardColumnContext);
|
||||||
const { shouldFetchMoreInColumnFamilyState, isFetchingRecordsByColumnState } =
|
|
||||||
useRecordBoardStates();
|
|
||||||
|
|
||||||
const isFetchingRecord = useRecoilValue(
|
const isFetchingRecord = useRecoilValue(
|
||||||
isFetchingRecordsByColumnState({ columnId: columnDefinition.id }),
|
isRecordBoardFetchingRecordsByColumnFamilyState(columnDefinition.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
const setShouldFetchMore = useSetRecoilState(
|
const setShouldFetchMore = useSetRecoilComponentFamilyStateV2(
|
||||||
shouldFetchMoreInColumnFamilyState(columnDefinition.id),
|
recordBoardShouldFetchMoreInColumnComponentFamilyState,
|
||||||
|
columnDefinition.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { ref, inView } = useInView();
|
const { ref, inView } = useInView();
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { isDefined } from 'twenty-ui';
|
import { isDefined } from 'twenty-ui';
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { RecordBoardColumnHeader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeader';
|
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 { 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 { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
type RecordBoardColumnHeaderWrapperProps = {
|
type RecordBoardColumnHeaderWrapperProps = {
|
||||||
@ -12,14 +14,16 @@ type RecordBoardColumnHeaderWrapperProps = {
|
|||||||
export const RecordBoardColumnHeaderWrapper = ({
|
export const RecordBoardColumnHeaderWrapper = ({
|
||||||
columnId,
|
columnId,
|
||||||
}: RecordBoardColumnHeaderWrapperProps) => {
|
}: RecordBoardColumnHeaderWrapperProps) => {
|
||||||
const { columnsFamilySelector, recordIdsByColumnIdFamilyState } =
|
const recordGroupDefinition = useRecoilValue(
|
||||||
useRecordBoardStates();
|
recordGroupDefinitionFamilyState(columnId),
|
||||||
|
);
|
||||||
|
|
||||||
const columnDefinition = useRecoilValue(columnsFamilySelector(columnId));
|
const recordRowIdsByGroup = useRecoilComponentFamilyValueV2(
|
||||||
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
|
columnId,
|
||||||
|
);
|
||||||
|
|
||||||
const recordIds = useRecoilValue(recordIdsByColumnIdFamilyState(columnId));
|
if (!isDefined(recordGroupDefinition)) {
|
||||||
|
|
||||||
if (!isDefined(columnDefinition)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,9 +31,9 @@ export const RecordBoardColumnHeaderWrapper = ({
|
|||||||
<RecordBoardColumnContext.Provider
|
<RecordBoardColumnContext.Provider
|
||||||
value={{
|
value={{
|
||||||
columnId,
|
columnId,
|
||||||
columnDefinition: columnDefinition,
|
columnDefinition: recordGroupDefinition,
|
||||||
recordCount: recordIds.length,
|
recordCount: recordRowIdsByGroup.length,
|
||||||
recordIds,
|
recordIds: recordRowIdsByGroup,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordBoardColumnHeader />
|
<RecordBoardColumnHeader />
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
|
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
export const useColumnNewCardActions = (columnId: string) => {
|
export const useColumnNewCardActions = (columnId: string) => {
|
||||||
const { visibleFieldDefinitionsState } = useRecordBoardStates();
|
const visibleFieldDefinitions = useRecoilComponentValueV2(
|
||||||
const visibleFieldDefinitions = useRecoilValue(
|
recordBoardVisibleFieldDefinitionsComponentSelector,
|
||||||
visibleFieldDefinitionsState(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const labelIdentifierField = visibleFieldDefinitions.find(
|
const labelIdentifierField = visibleFieldDefinitions.find(
|
||||||
(field) => field.isLabelIdentifier,
|
(field) => field.isLabelIdentifier,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
import { createComponentInstanceContext } from '@/ui/utilities/state/component-state/utils/createComponentInstanceContext';
|
||||||
|
|
||||||
|
export const RecordBoardComponentInstanceContext =
|
||||||
|
createComponentInstanceContext();
|
||||||
@ -1,7 +1,9 @@
|
|||||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
|
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
||||||
|
|
||||||
export const isRecordBoardCardSelectedComponentFamilyState =
|
export const isRecordBoardCardSelectedComponentFamilyState =
|
||||||
createComponentFamilyState<boolean, string>({
|
createComponentFamilyStateV2<boolean, string>({
|
||||||
key: 'isRecordBoardCardSelectedComponentFamilyState',
|
key: 'isRecordBoardCardSelectedComponentFamilyState',
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
|
componentInstanceContext: RecordBoardComponentInstanceContext,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
export const isRecordBoardCompactModeActiveComponentState =
|
export const isRecordBoardCompactModeActiveComponentState =
|
||||||
createComponentState<boolean>({
|
createComponentStateV2<boolean>({
|
||||||
key: 'isRecordBoardCompactModeActiveComponentState',
|
key: 'isRecordBoardCompactModeActiveComponentState',
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
|
componentInstanceContext: RecordBoardComponentInstanceContext,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
|
import { atomFamily } from 'recoil';
|
||||||
|
|
||||||
export const isRecordBoardFetchingRecordsByColumnFamilyState =
|
export const isRecordBoardFetchingRecordsByColumnFamilyState = atomFamily<
|
||||||
createComponentFamilyState<boolean, { columnId: string }>({
|
boolean,
|
||||||
key: 'isRecordBoardFetchingRecordsByColumnFamilyState',
|
RecordGroupDefinition['id']
|
||||||
defaultValue: false,
|
>({
|
||||||
});
|
key: 'isRecordBoardFetchingRecordsByColumnFamilyState',
|
||||||
|
default: false,
|
||||||
|
});
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
|
||||||
|
|
||||||
export const isRecordBoardFetchingRecordsComponentState =
|
|
||||||
createComponentState<boolean>({
|
|
||||||
key: 'isRecordBoardFetchingRecordsComponentState',
|
|
||||||
defaultValue: false,
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
|
||||||
|
|
||||||
export const recordBoardColumnIdsComponentState = createComponentState<
|
|
||||||
string[]
|
|
||||||
>({
|
|
||||||
key: 'recordBoardColumnIdsComponentState',
|
|
||||||
defaultValue: [],
|
|
||||||
});
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
|
||||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
|
||||||
|
|
||||||
export const recordBoardColumnsComponentFamilyState =
|
|
||||||
createComponentFamilyState<RecordGroupDefinition | undefined, string>({
|
|
||||||
key: 'recordBoardColumnsComponentFamilyState',
|
|
||||||
defaultValue: undefined,
|
|
||||||
});
|
|
||||||
@ -1,10 +1,12 @@
|
|||||||
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition';
|
import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition';
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
|
||||||
export const recordBoardFieldDefinitionsComponentState = createComponentState<
|
export const recordBoardFieldDefinitionsComponentState = createComponentStateV2<
|
||||||
RecordBoardFieldDefinition<FieldMetadata>[]
|
RecordBoardFieldDefinition<FieldMetadata>[]
|
||||||
>({
|
>({
|
||||||
key: 'recordBoardFieldDefinitionsComponentState',
|
key: 'recordBoardFieldDefinitionsComponentState',
|
||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
|
componentInstanceContext: RecordBoardComponentInstanceContext,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
|
||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
|
||||||
|
|
||||||
export const recordBoardFiltersComponentState = createComponentState<Filter[]>({
|
|
||||||
key: 'recordBoardFiltersComponentState',
|
|
||||||
defaultValue: [],
|
|
||||||
});
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
|
||||||
|
|
||||||
export const recordBoardKanbanFieldMetadataNameComponentState =
|
|
||||||
createComponentState<string | undefined>({
|
|
||||||
key: 'recordBoardKanbanFieldMetadataNameComponentState',
|
|
||||||
defaultValue: undefined,
|
|
||||||
});
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
|
||||||
|
|
||||||
export const recordBoardRecordIdsByColumnIdComponentFamilyState =
|
|
||||||
createComponentFamilyState<string[], string>({
|
|
||||||
key: 'recordBoardRecordIdsByColumnIdComponentFamilyState',
|
|
||||||
defaultValue: [],
|
|
||||||
});
|
|
||||||
@ -1,7 +1,9 @@
|
|||||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
|
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
||||||
|
|
||||||
export const recordBoardShouldFetchMoreInColumnComponentFamilyState =
|
export const recordBoardShouldFetchMoreInColumnComponentFamilyState =
|
||||||
createComponentFamilyState<boolean, string>({
|
createComponentFamilyStateV2<boolean, string>({
|
||||||
key: 'onRecordBoardFetchMoreIrecordBoardShouldFetchMoreInColumnComponentFamilyStatesVisibleComponentFamilyState',
|
key: 'recordBoardShouldFetchMoreInColumnComponentFamilyState',
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
|
componentInstanceContext: RecordBoardComponentInstanceContext,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
|
|
||||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
|
||||||
|
|
||||||
export const recordBoardSortsComponentState = createComponentState<Sort[]>({
|
|
||||||
key: 'recordBoardSortsComponentState',
|
|
||||||
defaultValue: [],
|
|
||||||
});
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
|
|
||||||
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
|
||||||
import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector';
|
|
||||||
|
|
||||||
export const recordBoardAllRecordIdsComponentSelector =
|
|
||||||
createComponentReadOnlySelector<string[]>({
|
|
||||||
key: 'recordBoardAllRecordIdsComponentSelector',
|
|
||||||
get:
|
|
||||||
({ scopeId }) =>
|
|
||||||
({ get }) => {
|
|
||||||
const columnIds = get(recordBoardColumnIdsComponentState({ scopeId }));
|
|
||||||
|
|
||||||
const recordIdsByColumn = columnIds.map((columnId) =>
|
|
||||||
get(
|
|
||||||
recordBoardRecordIdsByColumnIdComponentFamilyState({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordIds = recordIdsByColumn.flat();
|
|
||||||
|
|
||||||
return recordIds;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import { recordBoardColumnsComponentFamilyState } from '@/object-record/record-board/states/recordBoardColumnsComponentFamilyState';
|
|
||||||
import { createComponentFamilySelector } from '@/ui/utilities/state/component-state/utils/createComponentFamilySelector';
|
|
||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
|
||||||
|
|
||||||
export const recordBoardColumnsComponentFamilySelector =
|
|
||||||
createComponentFamilySelector<RecordGroupDefinition | undefined, string>({
|
|
||||||
key: 'recordBoardColumnsComponentFamilySelector',
|
|
||||||
get:
|
|
||||||
({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}: {
|
|
||||||
scopeId: string;
|
|
||||||
familyKey: string;
|
|
||||||
}) =>
|
|
||||||
({ get }) => {
|
|
||||||
return get(
|
|
||||||
recordBoardColumnsComponentFamilyState({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
set:
|
|
||||||
({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}: {
|
|
||||||
scopeId: string;
|
|
||||||
familyKey: string;
|
|
||||||
}) =>
|
|
||||||
({ set }, newColumn) => {
|
|
||||||
set(
|
|
||||||
recordBoardColumnsComponentFamilyState({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}),
|
|
||||||
newColumn,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@ -1,32 +1,24 @@
|
|||||||
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||||
import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector';
|
|
||||||
|
|
||||||
export const recordBoardSelectedRecordIdsComponentSelector =
|
export const recordBoardSelectedRecordIdsComponentSelector =
|
||||||
createComponentReadOnlySelector<string[]>({
|
createComponentSelectorV2<string[]>({
|
||||||
key: 'recordBoardSelectedRecordIdsSelector',
|
key: 'recordBoardSelectedRecordIdsSelector',
|
||||||
|
componentInstanceContext: RecordBoardComponentInstanceContext,
|
||||||
get:
|
get:
|
||||||
({ scopeId }) =>
|
({ instanceId }) =>
|
||||||
({ get }) => {
|
({ get }) => {
|
||||||
const columnIds = get(recordBoardColumnIdsComponentState({ scopeId }));
|
const allRowIds = get(
|
||||||
|
recordIndexAllRowIdsComponentState.atomFamily({ instanceId }),
|
||||||
const recordIdsByColumn = columnIds.map((columnId) =>
|
|
||||||
get(
|
|
||||||
recordBoardRecordIdsByColumnIdComponentFamilyState({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordIds = recordIdsByColumn.flat();
|
return allRowIds.filter(
|
||||||
|
|
||||||
return recordIds.filter(
|
|
||||||
(recordId) =>
|
(recordId) =>
|
||||||
get(
|
get(
|
||||||
isRecordBoardCardSelectedComponentFamilyState({
|
isRecordBoardCardSelectedComponentFamilyState.atomFamily({
|
||||||
scopeId,
|
instanceId,
|
||||||
familyKey: recordId,
|
familyKey: recordId,
|
||||||
}),
|
}),
|
||||||
) === true,
|
) === true,
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
|
|
||||||
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
|
||||||
import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector';
|
|
||||||
|
|
||||||
export const recordBoardShouldFetchMoreComponentSelector =
|
|
||||||
createComponentReadOnlySelector<boolean>({
|
|
||||||
key: 'recordBoardShouldFetchMoreComponentSelector',
|
|
||||||
get:
|
|
||||||
({ scopeId }: { scopeId: string }) =>
|
|
||||||
({ get }) => {
|
|
||||||
const columnIds = get(
|
|
||||||
recordBoardColumnIdsComponentState({
|
|
||||||
scopeId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const shouldFetchMoreInColumns = columnIds.map((columnId) => {
|
|
||||||
return get(
|
|
||||||
recordBoardShouldFetchMoreInColumnComponentFamilyState({
|
|
||||||
scopeId,
|
|
||||||
familyKey: columnId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return shouldFetchMoreInColumns.some(Boolean);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@ -1,13 +1,17 @@
|
|||||||
|
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||||
import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState';
|
import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState';
|
||||||
import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector';
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
|
|
||||||
export const recordBoardVisibleFieldDefinitionsComponentSelector =
|
export const recordBoardVisibleFieldDefinitionsComponentSelector =
|
||||||
createComponentReadOnlySelector({
|
createComponentSelectorV2({
|
||||||
key: 'recordBoardVisibleFieldDefinitionsComponentSelector',
|
key: 'recordBoardVisibleFieldDefinitionsComponentSelector',
|
||||||
get:
|
get:
|
||||||
({ scopeId }) =>
|
({ instanceId }) =>
|
||||||
({ get }) =>
|
({ get }) =>
|
||||||
get(recordBoardFieldDefinitionsComponentState({ scopeId }))
|
get(
|
||||||
|
recordBoardFieldDefinitionsComponentState.atomFamily({ instanceId }),
|
||||||
|
)
|
||||||
.filter((field) => field.isVisible)
|
.filter((field) => field.isVisible)
|
||||||
.sort((a, b) => a.position - b.position),
|
.sort((a, b) => a.position - b.position),
|
||||||
|
componentInstanceContext: RecordBoardComponentInstanceContext,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,31 +1,45 @@
|
|||||||
import { IconEye, IconEyeOff, MenuItemDraggable, Tag } from 'twenty-ui';
|
import { IconEye, IconEyeOff, MenuItemDraggable, Tag } from 'twenty-ui';
|
||||||
|
|
||||||
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
import {
|
import {
|
||||||
RecordGroupDefinition,
|
RecordGroupDefinition,
|
||||||
RecordGroupDefinitionType,
|
RecordGroupDefinitionType,
|
||||||
} from '@/object-record/record-group/types/RecordGroupDefinition';
|
} from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
type RecordGroupMenuItemDraggableProps = {
|
type RecordGroupMenuItemDraggableProps = {
|
||||||
recordGroup: RecordGroupDefinition;
|
recordGroupId: string;
|
||||||
showDragGrip?: boolean;
|
showDragGrip?: boolean;
|
||||||
isDraggable?: boolean;
|
isDraggable?: boolean;
|
||||||
onVisibilityChange: (viewGroup: RecordGroupDefinition) => void;
|
onVisibilityChange: (recordGroup: RecordGroupDefinition) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordGroupMenuItemDraggable = ({
|
export const RecordGroupMenuItemDraggable = ({
|
||||||
recordGroup,
|
recordGroupId,
|
||||||
showDragGrip,
|
showDragGrip,
|
||||||
isDraggable,
|
isDraggable,
|
||||||
onVisibilityChange,
|
onVisibilityChange,
|
||||||
}: RecordGroupMenuItemDraggableProps) => {
|
}: RecordGroupMenuItemDraggableProps) => {
|
||||||
|
const recordGroup = useRecoilValue(
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordGroup)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const isNoValue = recordGroup.type === RecordGroupDefinitionType.NoValue;
|
const isNoValue = recordGroup.type === RecordGroupDefinitionType.NoValue;
|
||||||
|
|
||||||
const getIconButtons = (recordGroup: RecordGroupDefinition) => {
|
const getIconButtons = (recordGroup: RecordGroupDefinition) => {
|
||||||
const iconButtons = [
|
const iconButtons = [
|
||||||
{
|
{
|
||||||
Icon: recordGroup.isVisible ? IconEyeOff : IconEye,
|
Icon: recordGroup.isVisible ? IconEyeOff : IconEye,
|
||||||
onClick: () => onVisibilityChange(recordGroup),
|
onClick: () =>
|
||||||
|
onVisibilityChange({
|
||||||
|
...recordGroup,
|
||||||
|
isVisible: !recordGroup.isVisible,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
].filter(isDefined);
|
].filter(isDefined);
|
||||||
|
|
||||||
|
|||||||
@ -13,17 +13,17 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
|||||||
import { StyledDropdownMenuSubheader } from '@/ui/layout/dropdown/components/StyledDropdownMenuSubheader';
|
import { StyledDropdownMenuSubheader } from '@/ui/layout/dropdown/components/StyledDropdownMenuSubheader';
|
||||||
|
|
||||||
type RecordGroupsVisibilityDropdownSectionProps = {
|
type RecordGroupsVisibilityDropdownSectionProps = {
|
||||||
recordGroups: RecordGroupDefinition[];
|
recordGroupIds: string[];
|
||||||
isDraggable: boolean;
|
isDraggable: boolean;
|
||||||
onDragEnd?: OnDragEndResponder;
|
onDragEnd?: OnDragEndResponder;
|
||||||
onVisibilityChange: (viewGroup: RecordGroupDefinition) => void;
|
onVisibilityChange: (recordGroup: RecordGroupDefinition) => void;
|
||||||
title: string;
|
title: string;
|
||||||
showSubheader?: boolean;
|
showSubheader?: boolean;
|
||||||
showDragGrip: boolean;
|
showDragGrip: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordGroupsVisibilityDropdownSection = ({
|
export const RecordGroupsVisibilityDropdownSection = ({
|
||||||
recordGroups,
|
recordGroupIds,
|
||||||
isDraggable,
|
isDraggable,
|
||||||
onDragEnd,
|
onDragEnd,
|
||||||
onVisibilityChange,
|
onVisibilityChange,
|
||||||
@ -43,12 +43,13 @@ export const RecordGroupsVisibilityDropdownSection = ({
|
|||||||
<StyledDropdownMenuSubheader>{title}</StyledDropdownMenuSubheader>
|
<StyledDropdownMenuSubheader>{title}</StyledDropdownMenuSubheader>
|
||||||
)}
|
)}
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
{!!recordGroups.length && (
|
{recordGroupIds.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{!isDraggable ? (
|
{!isDraggable ? (
|
||||||
recordGroups.map((recordGroup) => (
|
recordGroupIds.map((recordGroupId) => (
|
||||||
<RecordGroupMenuItemDraggable
|
<RecordGroupMenuItemDraggable
|
||||||
recordGroup={recordGroup}
|
key={recordGroupId}
|
||||||
|
recordGroupId={recordGroupId}
|
||||||
onVisibilityChange={onVisibilityChange}
|
onVisibilityChange={onVisibilityChange}
|
||||||
showDragGrip={showDragGrip}
|
showDragGrip={showDragGrip}
|
||||||
isDraggable={isDraggable}
|
isDraggable={isDraggable}
|
||||||
@ -59,14 +60,14 @@ export const RecordGroupsVisibilityDropdownSection = ({
|
|||||||
onDragEnd={handleOnDrag}
|
onDragEnd={handleOnDrag}
|
||||||
draggableItems={
|
draggableItems={
|
||||||
<>
|
<>
|
||||||
{recordGroups.map((recordGroup, index) => (
|
{recordGroupIds.map((recordGroupId, index) => (
|
||||||
<DraggableItem
|
<DraggableItem
|
||||||
key={recordGroup.id}
|
key={recordGroupId}
|
||||||
draggableId={recordGroup.id}
|
draggableId={recordGroupId}
|
||||||
index={index + 1}
|
index={index + 1}
|
||||||
itemComponent={
|
itemComponent={
|
||||||
<RecordGroupMenuItemDraggable
|
<RecordGroupMenuItemDraggable
|
||||||
recordGroup={recordGroup}
|
recordGroupId={recordGroupId}
|
||||||
onVisibilityChange={onVisibilityChange}
|
onVisibilityChange={onVisibilityChange}
|
||||||
showDragGrip={showDragGrip}
|
showDragGrip={showDragGrip}
|
||||||
isDraggable={isDraggable}
|
isDraggable={isDraggable}
|
||||||
|
|||||||
@ -1,37 +1,14 @@
|
|||||||
import { RecordGroupContext } from '@/object-record/record-group/states/context/RecordGroupContext';
|
import { RecordGroupContext } from '@/object-record/record-group/states/context/RecordGroupContext';
|
||||||
import { hasRecordGroupDefinitionsComponentSelector } from '@/object-record/record-group/states/hasRecordGroupDefinitionsComponentSelector';
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
import { useContext } from 'react';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useContext, useMemo } from 'react';
|
|
||||||
|
|
||||||
export const useCurrentRecordGroupDefinition = (recordTableId?: string) => {
|
export const useCurrentRecordGroupDefinition = () => {
|
||||||
const context = useContext(RecordGroupContext);
|
const context = useContext(RecordGroupContext);
|
||||||
|
|
||||||
const hasRecordGroups = useRecoilComponentValueV2(
|
const recordGroupDefinition = useRecoilValue(
|
||||||
hasRecordGroupDefinitionsComponentSelector,
|
recordGroupDefinitionFamilyState(context?.recordGroupId),
|
||||||
recordTableId,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordGroupDefinitions = useRecoilComponentValueV2(
|
|
||||||
recordGroupDefinitionsComponentState,
|
|
||||||
recordTableId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordGroupDefinition = useMemo(() => {
|
|
||||||
if (!hasRecordGroups) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
throw new Error(
|
|
||||||
'useCurrentRecordGroupDefinition must be used within a RecordGroupContextProvider.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return recordGroupDefinitions.find(
|
|
||||||
({ id }) => id === context.recordGroupId,
|
|
||||||
);
|
|
||||||
}, [context, hasRecordGroups, recordGroupDefinitions]);
|
|
||||||
|
|
||||||
return recordGroupDefinition;
|
return recordGroupDefinition;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,24 +2,18 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
|||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
||||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
|
||||||
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
||||||
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import { RecordGroupAction } from '@/object-record/record-group/types/RecordGroupActions';
|
import { RecordGroupAction } from '@/object-record/record-group/types/RecordGroupActions';
|
||||||
import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext';
|
import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext';
|
||||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useCallback, useContext, useMemo } from 'react';
|
import { useCallback, useContext, useMemo } from 'react';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
import { IconEyeOff, IconSettings, isDefined } from 'twenty-ui';
|
import { IconEyeOff, IconSettings, isDefined } from 'twenty-ui';
|
||||||
|
|
||||||
type UseRecordGroupActionsParams = {
|
export const useRecordGroupActions = () => {
|
||||||
viewType: ViewType;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useRecordGroupActions = ({
|
|
||||||
viewType,
|
|
||||||
}: UseRecordGroupActionsParams) => {
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
@ -35,14 +29,13 @@ export const useRecordGroupActions = ({
|
|||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { viewGroupFieldMetadataItem } = useRecordGroups({
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
objectNameSingular,
|
recordGroupFieldMetadataComponentState,
|
||||||
});
|
);
|
||||||
|
|
||||||
const { handleVisibilityChange: handleRecordGroupVisibilityChange } =
|
const { handleVisibilityChange: handleRecordGroupVisibilityChange } =
|
||||||
useRecordGroupVisibility({
|
useRecordGroupVisibility({
|
||||||
viewBarId: recordIndexId,
|
viewBarId: recordIndexId,
|
||||||
viewType,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const setNavigationMemorizedUrl = useSetRecoilState(
|
const setNavigationMemorizedUrl = useSetRecoilState(
|
||||||
@ -52,11 +45,11 @@ export const useRecordGroupActions = ({
|
|||||||
const navigateToSelectSettings = useCallback(() => {
|
const navigateToSelectSettings = useCallback(() => {
|
||||||
setNavigationMemorizedUrl(location.pathname + location.search);
|
setNavigationMemorizedUrl(location.pathname + location.search);
|
||||||
|
|
||||||
if (!isDefined(viewGroupFieldMetadataItem)) {
|
if (!isDefined(recordGroupFieldMetadata)) {
|
||||||
throw new Error('viewGroupFieldMetadataItem is not a non-empty string');
|
throw new Error('recordGroupFieldMetadata is not a non-empty string');
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsPath = `/settings/objects/${getObjectSlug(objectMetadataItem)}/${getFieldSlug(viewGroupFieldMetadataItem)}`;
|
const settingsPath = `/settings/objects/${getObjectSlug(objectMetadataItem)}/${getFieldSlug(recordGroupFieldMetadata)}`;
|
||||||
|
|
||||||
navigate(settingsPath);
|
navigate(settingsPath);
|
||||||
}, [
|
}, [
|
||||||
@ -65,7 +58,7 @@ export const useRecordGroupActions = ({
|
|||||||
location.search,
|
location.search,
|
||||||
navigate,
|
navigate,
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
viewGroupFieldMetadataItem,
|
recordGroupFieldMetadata,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const recordGroupActions: RecordGroupAction[] = useMemo(
|
const recordGroupActions: RecordGroupAction[] = useMemo(
|
||||||
|
|||||||
@ -1,59 +1,89 @@
|
|||||||
import { OnDragEndResponder } from '@hello-pangea/dnd';
|
import { OnDragEndResponder } from '@hello-pangea/dnd';
|
||||||
import { useCallback } from 'react';
|
|
||||||
|
|
||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
import { useSetRecordGroup } from '@/object-record/record-group/hooks/useSetRecordGroup';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||||
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
import { useSaveCurrentViewGroups } from '@/views/hooks/useSaveCurrentViewGroups';
|
import { useSaveCurrentViewGroups } from '@/views/hooks/useSaveCurrentViewGroups';
|
||||||
import { mapRecordGroupDefinitionsToViewGroups } from '@/views/utils/mapRecordGroupDefinitionsToViewGroups';
|
import { mapRecordGroupDefinitionsToViewGroups } from '@/views/utils/mapRecordGroupDefinitionsToViewGroups';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { moveArrayItem } from '~/utils/array/moveArrayItem';
|
import { moveArrayItem } from '~/utils/array/moveArrayItem';
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
type UseRecordGroupHandlersParams = {
|
type UseRecordGroupHandlersParams = {
|
||||||
objectNameSingular: string;
|
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useRecordGroupReorder = ({
|
export const useRecordGroupReorder = ({
|
||||||
objectNameSingular,
|
|
||||||
viewBarId,
|
viewBarId,
|
||||||
}: UseRecordGroupHandlersParams) => {
|
}: UseRecordGroupHandlersParams) => {
|
||||||
const setRecordGroupDefinitions = useSetRecoilComponentStateV2(
|
const setRecordGroup = useSetRecordGroup(viewBarId);
|
||||||
recordGroupDefinitionsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { visibleRecordGroups } = useRecordGroups({
|
const visibleRecordGroupIdsSelector = useRecoilComponentCallbackStateV2(
|
||||||
objectNameSingular: objectNameSingular,
|
visibleRecordGroupIdsComponentSelector,
|
||||||
});
|
);
|
||||||
|
|
||||||
const { saveViewGroups } = useSaveCurrentViewGroups(viewBarId);
|
const { saveViewGroups } = useSaveCurrentViewGroups(viewBarId);
|
||||||
|
|
||||||
const handleOrderChange: OnDragEndResponder = useCallback(
|
const handleOrderChange: OnDragEndResponder = useRecoilCallback(
|
||||||
(result) => {
|
({ snapshot }) =>
|
||||||
if (!result.destination) {
|
(result) => {
|
||||||
return;
|
if (!result.destination) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const reorderedVisibleBoardGroups = moveArrayItem(visibleRecordGroups, {
|
const visibleRecordGroupIds = getSnapshotValue(
|
||||||
fromIndex: result.source.index - 1,
|
snapshot,
|
||||||
toIndex: result.destination.index - 1,
|
visibleRecordGroupIdsSelector,
|
||||||
});
|
);
|
||||||
|
|
||||||
if (isDeeplyEqual(visibleRecordGroups, reorderedVisibleBoardGroups))
|
const reorderedVisibleRecordGroupIds = moveArrayItem(
|
||||||
return;
|
visibleRecordGroupIds,
|
||||||
|
{
|
||||||
|
fromIndex: result.source.index - 1,
|
||||||
|
toIndex: result.destination.index - 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const updatedGroups = [...reorderedVisibleBoardGroups].map(
|
if (
|
||||||
(group, index) => ({ ...group, position: index }),
|
isDeeplyEqual(visibleRecordGroupIds, reorderedVisibleRecordGroupIds)
|
||||||
);
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setRecordGroupDefinitions(updatedGroups);
|
const updatedRecordGroups = reorderedVisibleRecordGroupIds.reduce<
|
||||||
saveViewGroups(mapRecordGroupDefinitionsToViewGroups(updatedGroups));
|
RecordGroupDefinition[]
|
||||||
},
|
>((acc, recordGroupId, index) => {
|
||||||
[saveViewGroups, setRecordGroupDefinitions, visibleRecordGroups],
|
const recordGroupDefinition = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordGroupDefinition)) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
...acc,
|
||||||
|
{
|
||||||
|
...recordGroupDefinition,
|
||||||
|
position: index,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
setRecordGroup(updatedRecordGroups);
|
||||||
|
saveViewGroups(
|
||||||
|
mapRecordGroupDefinitionsToViewGroups(updatedRecordGroups),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[saveViewGroups, setRecordGroup, visibleRecordGroupIdsSelector],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visibleRecordGroups,
|
|
||||||
handleOrderChange,
|
handleOrderChange,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,125 +1,113 @@
|
|||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
import { recordIndexRecordGroupHideComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupHideComponentState';
|
import { recordIndexRecordGroupHideComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupHideComponentState';
|
||||||
import { tableRowIdsByGroupComponentFamilyState } from '@/object-record/record-table/states/tableRowIdsByGroupComponentFamilyState';
|
import { recordIndexRowIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRowIdsByGroupComponentFamilyState';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||||
import { useSaveCurrentViewGroups } from '@/views/hooks/useSaveCurrentViewGroups';
|
import { useSaveCurrentViewGroups } from '@/views/hooks/useSaveCurrentViewGroups';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
|
||||||
import { mapRecordGroupDefinitionsToViewGroups } from '@/views/utils/mapRecordGroupDefinitionsToViewGroups';
|
import { mapRecordGroupDefinitionsToViewGroups } from '@/views/utils/mapRecordGroupDefinitionsToViewGroups';
|
||||||
|
import { recordGroupDefinitionToViewGroup } from '@/views/utils/recordGroupDefinitionToViewGroup';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
type UseRecordGroupVisibilityParams = {
|
type UseRecordGroupVisibilityParams = {
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
viewType: ViewType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useRecordGroupVisibility = ({
|
export const useRecordGroupVisibility = ({
|
||||||
viewBarId,
|
viewBarId,
|
||||||
viewType,
|
|
||||||
}: UseRecordGroupVisibilityParams) => {
|
}: UseRecordGroupVisibilityParams) => {
|
||||||
const recordGroupDefinitionsState = useRecoilComponentCallbackStateV2(
|
const recordIndexRecordGroupIdsState = useRecoilComponentCallbackStateV2(
|
||||||
recordGroupDefinitionsComponentState,
|
recordGroupIdsComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||||
tableRowIdsByGroupComponentFamilyState,
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { recordIdsByColumnIdFamilyState } = useRecordBoardStates(viewBarId);
|
|
||||||
|
|
||||||
const objectOptionsDropdownRecordGroupHideState =
|
const objectOptionsDropdownRecordGroupHideState =
|
||||||
useRecoilComponentCallbackStateV2(recordIndexRecordGroupHideComponentState);
|
useRecoilComponentCallbackStateV2(recordIndexRecordGroupHideComponentState);
|
||||||
|
|
||||||
const { saveViewGroups } = useSaveCurrentViewGroups(viewBarId);
|
const { saveViewGroup, saveViewGroups } = useSaveCurrentViewGroups(viewBarId);
|
||||||
|
|
||||||
const handleVisibilityChange = useRecoilCallback(
|
const handleVisibilityChange = useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ set }) =>
|
||||||
async (updatedRecordGroupDefinition: RecordGroupDefinition) => {
|
async (updatedRecordGroup: RecordGroupDefinition) => {
|
||||||
const recordGroupDefinitions = getSnapshotValue(
|
set(
|
||||||
snapshot,
|
recordGroupDefinitionFamilyState(updatedRecordGroup.id),
|
||||||
recordGroupDefinitionsState,
|
updatedRecordGroup,
|
||||||
);
|
);
|
||||||
|
|
||||||
const updatedRecordGroupDefinitions = recordGroupDefinitions.map(
|
saveViewGroup(recordGroupDefinitionToViewGroup(updatedRecordGroup));
|
||||||
(groupDefinition) =>
|
|
||||||
groupDefinition.id === updatedRecordGroupDefinition.id
|
|
||||||
? {
|
|
||||||
...groupDefinition,
|
|
||||||
isVisible: !groupDefinition.isVisible,
|
|
||||||
}
|
|
||||||
: groupDefinition,
|
|
||||||
);
|
|
||||||
|
|
||||||
set(recordGroupDefinitionsState, updatedRecordGroupDefinitions);
|
|
||||||
|
|
||||||
saveViewGroups(
|
|
||||||
mapRecordGroupDefinitionsToViewGroups(updatedRecordGroupDefinitions),
|
|
||||||
);
|
|
||||||
|
|
||||||
// If visibility is manually toggled, we should reset the hideEmptyRecordGroup state
|
// If visibility is manually toggled, we should reset the hideEmptyRecordGroup state
|
||||||
set(objectOptionsDropdownRecordGroupHideState, false);
|
set(objectOptionsDropdownRecordGroupHideState, false);
|
||||||
},
|
},
|
||||||
[
|
[saveViewGroup, objectOptionsDropdownRecordGroupHideState],
|
||||||
objectOptionsDropdownRecordGroupHideState,
|
|
||||||
recordGroupDefinitionsState,
|
|
||||||
saveViewGroups,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleHideEmptyRecordGroupChange = useRecoilCallback(
|
const handleHideEmptyRecordGroupChange = useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
async () => {
|
async () => {
|
||||||
const recordGroupDefinitions = getSnapshotValue(
|
const updatedRecordGroupDefinitions: RecordGroupDefinition[] = [];
|
||||||
|
const recordGroupIds = getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
recordGroupDefinitionsState,
|
recordIndexRecordGroupIdsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentHideState = getSnapshotValue(
|
const currentHideState = getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
objectOptionsDropdownRecordGroupHideState,
|
objectOptionsDropdownRecordGroupHideState,
|
||||||
);
|
);
|
||||||
|
const newHideState = !currentHideState;
|
||||||
|
|
||||||
set(objectOptionsDropdownRecordGroupHideState, !currentHideState);
|
set(objectOptionsDropdownRecordGroupHideState, newHideState);
|
||||||
|
|
||||||
const updatedRecordGroupDefinitions = recordGroupDefinitions.map(
|
for (const recordGroupId of recordGroupIds) {
|
||||||
(recordGroup) => {
|
const recordGroup = getSnapshotValue(
|
||||||
// TODO: Maybe we can improve that and only use one state for both table and board
|
snapshot,
|
||||||
const recordGroupRowIds =
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
viewType === ViewType.Table
|
);
|
||||||
? getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
tableRowIdsByGroupFamilyState(recordGroup.id),
|
|
||||||
)
|
|
||||||
: getSnapshotValue(
|
|
||||||
snapshot,
|
|
||||||
recordIdsByColumnIdFamilyState(recordGroup.id),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (recordGroupRowIds.length > 0) {
|
if (!isDefined(recordGroup)) {
|
||||||
return recordGroup;
|
throw new Error(
|
||||||
}
|
`Record group with id ${recordGroupId} not found in snapshot`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
const recordGroupRowIds = getSnapshotValue(
|
||||||
...recordGroup,
|
snapshot,
|
||||||
isVisible: currentHideState,
|
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||||
};
|
);
|
||||||
},
|
|
||||||
);
|
if (recordGroupRowIds.length > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedRecordGroup = {
|
||||||
|
...recordGroup,
|
||||||
|
isVisible: !newHideState,
|
||||||
|
};
|
||||||
|
|
||||||
|
set(
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
updatedRecordGroup,
|
||||||
|
);
|
||||||
|
|
||||||
|
updatedRecordGroupDefinitions.push(updatedRecordGroup);
|
||||||
|
}
|
||||||
|
|
||||||
saveViewGroups(
|
saveViewGroups(
|
||||||
mapRecordGroupDefinitionsToViewGroups(updatedRecordGroupDefinitions),
|
mapRecordGroupDefinitionsToViewGroups(updatedRecordGroupDefinitions),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
recordGroupDefinitionsState,
|
recordIndexRecordGroupIdsState,
|
||||||
objectOptionsDropdownRecordGroupHideState,
|
objectOptionsDropdownRecordGroupHideState,
|
||||||
saveViewGroups,
|
saveViewGroups,
|
||||||
viewType,
|
recordIndexRowIdsByGroupFamilyState,
|
||||||
tableRowIdsByGroupFamilyState,
|
|
||||||
recordIdsByColumnIdFamilyState,
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
import { useMemo } from 'react';
|
|
||||||
|
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
|
||||||
import { sortRecordGroupDefinitions } from '@/object-record/record-group/utils/sortRecordGroupDefinitions';
|
|
||||||
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
|
||||||
|
|
||||||
type UseRecordGroupsParams = {
|
|
||||||
objectNameSingular: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useRecordGroups = ({
|
|
||||||
objectNameSingular,
|
|
||||||
}: UseRecordGroupsParams) => {
|
|
||||||
const recordGroupDefinitions = useRecoilComponentValueV2(
|
|
||||||
recordGroupDefinitionsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordGroupSort = useRecoilComponentValueV2(
|
|
||||||
recordIndexRecordGroupSortComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
|
||||||
objectNameSingular,
|
|
||||||
});
|
|
||||||
|
|
||||||
const viewGroupFieldMetadataItem = useMemo(() => {
|
|
||||||
if (recordGroupDefinitions.length === 0) return null;
|
|
||||||
// We're assuming that all groups have the same fieldMetadataId for now
|
|
||||||
const fieldMetadataId =
|
|
||||||
'fieldMetadataId' in recordGroupDefinitions[0]
|
|
||||||
? recordGroupDefinitions[0].fieldMetadataId
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (!fieldMetadataId) return null;
|
|
||||||
|
|
||||||
return objectMetadataItem.fields.find(
|
|
||||||
(field) => field.id === fieldMetadataId,
|
|
||||||
);
|
|
||||||
}, [objectMetadataItem, recordGroupDefinitions]);
|
|
||||||
|
|
||||||
const visibleRecordGroups = useMemo(
|
|
||||||
() => sortRecordGroupDefinitions(recordGroupDefinitions, recordGroupSort),
|
|
||||||
[recordGroupDefinitions, recordGroupSort],
|
|
||||||
);
|
|
||||||
|
|
||||||
const hiddenRecordGroups = useMemo(
|
|
||||||
() => recordGroupDefinitions.filter((boardGroup) => !boardGroup.isVisible),
|
|
||||||
[recordGroupDefinitions],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
hiddenRecordGroups,
|
|
||||||
visibleRecordGroups,
|
|
||||||
viewGroupFieldMetadataItem,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
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 { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
|
import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext';
|
||||||
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
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);
|
||||||
|
|
||||||
|
const recordIndexRecordGroupIdsState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordGroupIdsComponentState,
|
||||||
|
viewId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const recordGroupFieldMetadataState = useRecoilComponentCallbackStateV2(
|
||||||
|
recordGroupFieldMetadataComponentState,
|
||||||
|
viewId,
|
||||||
|
);
|
||||||
|
|
||||||
|
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 currentFieldMetadata = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupFieldMetadataState,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the field metadata linked to the record groups
|
||||||
|
if (
|
||||||
|
isDefined(fieldMetadata) &&
|
||||||
|
!isDeeplyEqual(fieldMetadata, currentFieldMetadata)
|
||||||
|
) {
|
||||||
|
set(recordGroupFieldMetadataState, fieldMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the record groups by id
|
||||||
|
recordGroups.forEach((recordGroup) => {
|
||||||
|
const existingRecordGroup = getSnapshotValue(
|
||||||
|
snapshot,
|
||||||
|
recordGroupDefinitionFamilyState(recordGroup.id),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeeplyEqual(existingRecordGroup, recordGroup)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(recordGroupDefinitionFamilyState(recordGroup.id), recordGroup);
|
||||||
|
});
|
||||||
|
|
||||||
|
const recordGroupIds = recordGroups.map(({ id }) => id);
|
||||||
|
|
||||||
|
if (isDeeplyEqual(currentRecordGroupId, recordGroupIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the record group ids
|
||||||
|
set(recordIndexRecordGroupIdsState, recordGroupIds);
|
||||||
|
},
|
||||||
|
[
|
||||||
|
objectMetadataItem.fields,
|
||||||
|
recordGroupFieldMetadataState,
|
||||||
|
recordIndexRecordGroupIdsState,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
|
import { atomFamily } from 'recoil';
|
||||||
|
|
||||||
|
export const recordGroupDefinitionFamilyState = atomFamily<
|
||||||
|
RecordGroupDefinition | undefined,
|
||||||
|
RecordGroupDefinition['id']
|
||||||
|
>({
|
||||||
|
key: 'recordGroupDefinitionFamilyState',
|
||||||
|
default: undefined,
|
||||||
|
});
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
|
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||||
|
|
||||||
|
export const recordGroupFieldMetadataComponentState = createComponentStateV2<
|
||||||
|
FieldMetadataItem | undefined
|
||||||
|
>({
|
||||||
|
key: 'recordGroupFieldMetadataComponentState',
|
||||||
|
defaultValue: undefined,
|
||||||
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
|
});
|
||||||
@ -2,10 +2,10 @@ import { RecordGroupDefinition } from '@/object-record/record-group/types/Record
|
|||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||||
|
|
||||||
export const recordGroupDefinitionsComponentState = createComponentStateV2<
|
export const recordGroupIdsComponentState = createComponentStateV2<
|
||||||
RecordGroupDefinition[]
|
RecordGroupDefinition['id'][]
|
||||||
>({
|
>({
|
||||||
key: 'recordGroupDefinitionsComponentState',
|
key: 'recordGroupIdsComponentState',
|
||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
});
|
});
|
||||||
@ -1,21 +1,21 @@
|
|||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||||
|
|
||||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||||
|
|
||||||
export const hasRecordGroupDefinitionsComponentSelector =
|
export const hasRecordGroupsComponentSelector =
|
||||||
createComponentSelectorV2<boolean>({
|
createComponentSelectorV2<boolean>({
|
||||||
key: 'hasRecordGroupDefinitionsComponentSelector',
|
key: 'hasRecordGroupsComponentSelector',
|
||||||
componentInstanceContext: ViewComponentInstanceContext,
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
get:
|
get:
|
||||||
({ instanceId }) =>
|
({ instanceId }) =>
|
||||||
({ get }) => {
|
({ get }) => {
|
||||||
const recordGroupDefinitions = get(
|
const recordGroupIds = get(
|
||||||
recordGroupDefinitionsComponentState.atomFamily({
|
recordGroupIdsComponentState.atomFamily({
|
||||||
instanceId,
|
instanceId,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return recordGroupDefinitions.length > 0;
|
return recordGroupIds.length > 0;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
|
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||||
|
|
||||||
|
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[]
|
||||||
|
>({
|
||||||
|
key: 'hiddenRecordGroupIdsComponentSelector',
|
||||||
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
|
get:
|
||||||
|
({ instanceId }) =>
|
||||||
|
({ get }) => {
|
||||||
|
const recordGroupIds = get(
|
||||||
|
recordGroupIdsComponentState.atomFamily({
|
||||||
|
instanceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return recordGroupIds.filter((recordGroupId) => {
|
||||||
|
const recordGroupDefinition = get(
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordGroupDefinition)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !recordGroupDefinition.isVisible;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
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 recordGroupDefinitionsComponentSelector =
|
||||||
|
createComponentSelectorV2<RecordGroupDefinition[]>({
|
||||||
|
key: 'recordGroupDefinitionsComponentSelector',
|
||||||
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
|
get:
|
||||||
|
({ instanceId }) =>
|
||||||
|
({ get }) => {
|
||||||
|
const recordGroupIds = get(
|
||||||
|
recordGroupIdsComponentState.atomFamily({
|
||||||
|
instanceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return recordGroupIds.reduce<RecordGroupDefinition[]>(
|
||||||
|
(acc, recordGroupId) => {
|
||||||
|
const recordGroupDefinition = get(
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(recordGroupDefinition)) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...acc, recordGroupDefinition];
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
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 { RecordGroupSort } from '@/object-record/record-group/types/RecordGroupSort';
|
||||||
|
import { sortedInsert } from '@/object-record/record-group/utils/sortedInsert';
|
||||||
|
import { recordIndexRecordGroupSortComponentState } from '@/object-record/record-index/states/recordIndexRecordGroupSortComponentState';
|
||||||
|
|
||||||
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
|
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
|
export const visibleRecordGroupIdsComponentSelector = createComponentSelectorV2<
|
||||||
|
string[]
|
||||||
|
>({
|
||||||
|
key: 'visibleRecordGroupIdsComponentSelector',
|
||||||
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
|
get:
|
||||||
|
({ instanceId }) =>
|
||||||
|
({ get }) => {
|
||||||
|
const recordGroupSort = get(
|
||||||
|
recordIndexRecordGroupSortComponentState.atomFamily({
|
||||||
|
instanceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const recordGroupIds = get(
|
||||||
|
recordGroupIdsComponentState.atomFamily({
|
||||||
|
instanceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result: RecordGroupDefinition[] = [];
|
||||||
|
|
||||||
|
const comparator = (
|
||||||
|
a: RecordGroupDefinition,
|
||||||
|
b: RecordGroupDefinition,
|
||||||
|
) => {
|
||||||
|
switch (recordGroupSort) {
|
||||||
|
case RecordGroupSort.Alphabetical:
|
||||||
|
return a.title.localeCompare(b.title);
|
||||||
|
case RecordGroupSort.ReverseAlphabetical:
|
||||||
|
return b.title.localeCompare(a.title);
|
||||||
|
case RecordGroupSort.Manual:
|
||||||
|
default:
|
||||||
|
return a.position - b.position;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const recordGroupId of recordGroupIds) {
|
||||||
|
const recordGroupDefinition = get(
|
||||||
|
recordGroupDefinitionFamilyState(recordGroupId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
isDefined(recordGroupDefinition) &&
|
||||||
|
recordGroupDefinition.isVisible
|
||||||
|
) {
|
||||||
|
sortedInsert(result, recordGroupDefinition, comparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.map(({ id }) => id);
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -5,7 +5,7 @@ export const sortRecordGroupDefinitions = (
|
|||||||
recordGroupDefinitions: RecordGroupDefinition[],
|
recordGroupDefinitions: RecordGroupDefinition[],
|
||||||
recordGroupSort: RecordGroupSort,
|
recordGroupSort: RecordGroupSort,
|
||||||
) => {
|
) => {
|
||||||
const visibleGroups = recordGroupDefinitions.filter(
|
const visibleRecordGroups = recordGroupDefinitions.filter(
|
||||||
(boardGroup) => boardGroup.isVisible,
|
(boardGroup) => boardGroup.isVisible,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -17,15 +17,15 @@ export const sortRecordGroupDefinitions = (
|
|||||||
|
|
||||||
switch (recordGroupSort) {
|
switch (recordGroupSort) {
|
||||||
case RecordGroupSort.Alphabetical:
|
case RecordGroupSort.Alphabetical:
|
||||||
return visibleGroups.sort((a, b) =>
|
return visibleRecordGroups.sort((a, b) =>
|
||||||
compareAlphabetical(a.title.toLowerCase(), b.title.toLowerCase()),
|
compareAlphabetical(a.title.toLowerCase(), b.title.toLowerCase()),
|
||||||
);
|
);
|
||||||
case RecordGroupSort.ReverseAlphabetical:
|
case RecordGroupSort.ReverseAlphabetical:
|
||||||
return visibleGroups.sort((a, b) =>
|
return visibleRecordGroups.sort((a, b) =>
|
||||||
compareAlphabetical(a.title.toLowerCase(), b.title.toLowerCase(), true),
|
compareAlphabetical(a.title.toLowerCase(), b.title.toLowerCase(), true),
|
||||||
);
|
);
|
||||||
case RecordGroupSort.Manual:
|
case RecordGroupSort.Manual:
|
||||||
default:
|
default:
|
||||||
return visibleGroups.sort((a, b) => a.position - b.position);
|
return visibleRecordGroups.sort((a, b) => a.position - b.position);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
export const sortedInsert = <T>(
|
||||||
|
array: T[],
|
||||||
|
item: T,
|
||||||
|
comparator: (a: T, b: T) => number,
|
||||||
|
) => {
|
||||||
|
let low = 0;
|
||||||
|
let high = array.length;
|
||||||
|
|
||||||
|
while (low < high) {
|
||||||
|
const mid = Math.floor((low + high) / 2);
|
||||||
|
|
||||||
|
if (comparator(item, array[mid]) < 0) {
|
||||||
|
high = mid;
|
||||||
|
} else {
|
||||||
|
low = mid + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array.splice(low, 0, item);
|
||||||
|
};
|
||||||
@ -5,7 +5,7 @@ import { isRecordBoardFetchingRecordsByColumnFamilyState } from '@/object-record
|
|||||||
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
||||||
import { useLoadRecordIndexBoardColumn } from '@/object-record/record-index/hooks/useLoadRecordIndexBoardColumn';
|
import { useLoadRecordIndexBoardColumn } from '@/object-record/record-index/hooks/useLoadRecordIndexBoardColumn';
|
||||||
import { isRecordIndexBoardColumnLoadingFamilyState } from '@/object-record/states/isRecordBoardColumnLoadingFamilyState';
|
import { isRecordIndexBoardColumnLoadingFamilyState } from '@/object-record/states/isRecordBoardColumnLoadingFamilyState';
|
||||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2';
|
||||||
|
|
||||||
export const RecordIndexBoardColumnLoaderEffect = ({
|
export const RecordIndexBoardColumnLoaderEffect = ({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
@ -18,20 +18,14 @@ export const RecordIndexBoardColumnLoaderEffect = ({
|
|||||||
boardFieldMetadataId: string | null;
|
boardFieldMetadataId: string | null;
|
||||||
columnId: string;
|
columnId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const [shouldFetchMore, setShouldFetchMore] = useRecoilState(
|
const [shouldFetchMore, setShouldFetchMore] = useRecoilComponentFamilyStateV2(
|
||||||
recordBoardShouldFetchMoreInColumnComponentFamilyState({
|
recordBoardShouldFetchMoreInColumnComponentFamilyState,
|
||||||
scopeId: getScopeIdFromComponentId(recordBoardId),
|
columnId,
|
||||||
familyKey: columnId,
|
recordBoardId,
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const [loadingRecordsForThisColumn, setLoadingRecordsForThisColumn] =
|
const [loadingRecordsForThisColumn, setLoadingRecordsForThisColumn] =
|
||||||
useRecoilState(
|
useRecoilState(isRecordBoardFetchingRecordsByColumnFamilyState(columnId));
|
||||||
isRecordBoardFetchingRecordsByColumnFamilyState({
|
|
||||||
scopeId: getScopeIdFromComponentId(recordBoardId),
|
|
||||||
familyKey: { columnId },
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const { fetchMoreRecords, loading, records, hasNextPage } =
|
const { fetchMoreRecords, loading, records, hasNextPage } =
|
||||||
useLoadRecordIndexBoardColumn({
|
useLoadRecordIndexBoardColumn({
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||||
import { RecordIndexBoardColumnLoaderEffect } from '@/object-record/record-index/components/RecordIndexBoardColumnLoaderEffect';
|
import { RecordIndexBoardColumnLoaderEffect } from '@/object-record/record-index/components/RecordIndexBoardColumnLoaderEffect';
|
||||||
import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState';
|
import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
type RecordIndexBoardDataLoaderProps = {
|
type RecordIndexBoardDataLoaderProps = {
|
||||||
objectNameSingular: string;
|
objectNameSingular: string;
|
||||||
@ -18,6 +19,10 @@ export const RecordIndexBoardDataLoader = ({
|
|||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const visibleRecordGroupIds = useRecoilComponentValueV2(
|
||||||
|
visibleRecordGroupIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
const recordIndexKanbanFieldMetadataId = useRecoilValue(
|
const recordIndexKanbanFieldMetadataId = useRecoilValue(
|
||||||
recordIndexKanbanFieldMetadataIdState,
|
recordIndexKanbanFieldMetadataIdState,
|
||||||
);
|
);
|
||||||
@ -26,18 +31,14 @@ export const RecordIndexBoardDataLoader = ({
|
|||||||
(field) => field.id === recordIndexKanbanFieldMetadataId,
|
(field) => field.id === recordIndexKanbanFieldMetadataId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { columnIdsState } = useRecordBoardStates(recordBoardId);
|
|
||||||
|
|
||||||
const columnIds = useRecoilValue(columnIdsState);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{columnIds.map((columnId, index) => (
|
{visibleRecordGroupIds.map((recordGroupId, index) => (
|
||||||
<RecordIndexBoardColumnLoaderEffect
|
<RecordIndexBoardColumnLoaderEffect
|
||||||
objectNameSingular={objectNameSingular}
|
objectNameSingular={objectNameSingular}
|
||||||
boardFieldMetadataId={recordIndexKanbanFieldMetadataId}
|
boardFieldMetadataId={recordIndexKanbanFieldMetadataId}
|
||||||
recordBoardId={recordBoardId}
|
recordBoardId={recordBoardId}
|
||||||
columnId={columnId}
|
columnId={recordGroupId}
|
||||||
key={index}
|
key={index}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,101 +1,52 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
||||||
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
||||||
import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState';
|
import { recordIndexIsCompactModeActiveState } from '@/object-record/record-index/states/recordIndexIsCompactModeActiveState';
|
||||||
import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
|
||||||
import { isDefined } from '~/utils/isDefined';
|
|
||||||
|
|
||||||
type RecordIndexBoardDataLoaderEffectProps = {
|
type RecordIndexBoardDataLoaderEffectProps = {
|
||||||
objectNameSingular: string;
|
|
||||||
recordBoardId: string;
|
recordBoardId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexBoardDataLoaderEffect = ({
|
export const RecordIndexBoardDataLoaderEffect = ({
|
||||||
objectNameSingular,
|
|
||||||
recordBoardId,
|
recordBoardId,
|
||||||
}: RecordIndexBoardDataLoaderEffectProps) => {
|
}: RecordIndexBoardDataLoaderEffectProps) => {
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
|
||||||
objectNameSingular,
|
|
||||||
});
|
|
||||||
|
|
||||||
const recordIndexFieldDefinitions = useRecoilValue(
|
const recordIndexFieldDefinitions = useRecoilValue(
|
||||||
recordIndexFieldDefinitionsState,
|
recordIndexFieldDefinitionsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordGroupDefinitions = useRecoilComponentValueV2(
|
|
||||||
recordGroupDefinitionsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordIndexKanbanFieldMetadataId = useRecoilValue(
|
|
||||||
recordIndexKanbanFieldMetadataIdState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordIndexIsCompactModeActive = useRecoilValue(
|
const recordIndexIsCompactModeActive = useRecoilValue(
|
||||||
recordIndexIsCompactModeActiveState,
|
recordIndexIsCompactModeActiveState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { isCompactModeActiveState } = useRecordBoard(recordBoardId);
|
const setRecordBoardFieldDefinitions = useSetRecoilComponentStateV2(
|
||||||
|
recordBoardFieldDefinitionsComponentState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
const setIsCompactModeActive = useSetRecoilState(isCompactModeActiveState);
|
const selectedRecordIds = useRecoilComponentValueV2(
|
||||||
|
recordBoardSelectedRecordIdsComponentSelector,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const setIsCompactModeActive = useSetRecoilComponentStateV2(
|
||||||
|
isRecordBoardCompactModeActiveComponentState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsCompactModeActive(recordIndexIsCompactModeActive);
|
setIsCompactModeActive(recordIndexIsCompactModeActive);
|
||||||
}, [recordIndexIsCompactModeActive, setIsCompactModeActive]);
|
}, [recordIndexIsCompactModeActive, setIsCompactModeActive]);
|
||||||
|
|
||||||
const {
|
|
||||||
setColumns,
|
|
||||||
setObjectSingularName,
|
|
||||||
selectedRecordIdsSelector,
|
|
||||||
setFieldDefinitions,
|
|
||||||
setKanbanFieldMetadataName,
|
|
||||||
} = useRecordBoard(recordBoardId);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFieldDefinitions(recordIndexFieldDefinitions);
|
setRecordBoardFieldDefinitions(recordIndexFieldDefinitions);
|
||||||
}, [recordIndexFieldDefinitions, setFieldDefinitions]);
|
}, [recordIndexFieldDefinitions, setRecordBoardFieldDefinitions]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setObjectSingularName(objectNameSingular);
|
|
||||||
}, [objectNameSingular, setObjectSingularName]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setColumns(recordGroupDefinitions);
|
|
||||||
}, [recordGroupDefinitions, setColumns]);
|
|
||||||
|
|
||||||
// TODO: Remove this duplicate useEffect by ensuring it's not here because
|
|
||||||
// We want it to be triggered by a change of objectMetadataItem, which would be an anti-pattern
|
|
||||||
// As it is an unnecessary dependency
|
|
||||||
useEffect(() => {
|
|
||||||
setFieldDefinitions(recordIndexFieldDefinitions);
|
|
||||||
}, [objectMetadataItem, setFieldDefinitions, recordIndexFieldDefinitions]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isDefined(recordIndexKanbanFieldMetadataId)) {
|
|
||||||
const kanbanFieldMetadataName = objectMetadataItem?.fields.find(
|
|
||||||
(field) =>
|
|
||||||
field.type === FieldMetadataType.Select &&
|
|
||||||
field.id === recordIndexKanbanFieldMetadataId,
|
|
||||||
)?.name;
|
|
||||||
|
|
||||||
if (isDefined(kanbanFieldMetadataName)) {
|
|
||||||
setKanbanFieldMetadataName(kanbanFieldMetadataName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
objectMetadataItem,
|
|
||||||
recordIndexKanbanFieldMetadataId,
|
|
||||||
setKanbanFieldMetadataName,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const selectedRecordIds = useRecoilValue(selectedRecordIdsSelector());
|
|
||||||
|
|
||||||
const setContextStoreTargetedRecords = useSetRecoilComponentStateV2(
|
const setContextStoreTargetedRecords = useSetRecoilComponentStateV2(
|
||||||
contextStoreTargetedRecordsRuleComponentState,
|
contextStoreTargetedRecordsRuleComponentState,
|
||||||
|
|||||||
@ -24,11 +24,9 @@ import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/compone
|
|||||||
|
|
||||||
import { RecordIndexActionMenu } from '@/action-menu/components/RecordIndexActionMenu';
|
import { RecordIndexActionMenu } from '@/action-menu/components/RecordIndexActionMenu';
|
||||||
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { useSetRecordGroup } from '@/object-record/record-group/hooks/useSetRecordGroup';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
|
||||||
import { RecordIndexFiltersToContextStoreEffect } from '@/object-record/record-index/components/RecordIndexFiltersToContextStoreEffect';
|
import { RecordIndexFiltersToContextStoreEffect } from '@/object-record/record-index/components/RecordIndexFiltersToContextStoreEffect';
|
||||||
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
|
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
|
||||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
import { ViewBar } from '@/views/components/ViewBar';
|
||||||
import { ViewField } from '@/views/types/ViewField';
|
import { ViewField } from '@/views/types/ViewField';
|
||||||
@ -38,7 +36,7 @@ import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToC
|
|||||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||||
import { mapViewGroupsToRecordGroupDefinitions } from '@/views/utils/mapViewGroupsToRecordGroupDefinitions';
|
import { mapViewGroupsToRecordGroupDefinitions } from '@/views/utils/mapViewGroupsToRecordGroupDefinitions';
|
||||||
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
||||||
import { useContext } from 'react';
|
import { useCallback, useContext } from 'react';
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -68,9 +66,7 @@ export const RecordIndexContainer = () => {
|
|||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
} = useContext(RecordIndexRootPropsContext);
|
} = useContext(RecordIndexRootPropsContext);
|
||||||
|
|
||||||
const recordGroupDefinitionsCallbackState = useRecoilComponentCallbackStateV2(
|
const setRecordGroup = useSetRecordGroup(recordIndexId);
|
||||||
recordGroupDefinitionsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
||||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||||
@ -96,8 +92,6 @@ export const RecordIndexContainer = () => {
|
|||||||
recordTableId: recordIndexId,
|
recordTableId: recordIndexId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { setColumns } = useRecordBoard(recordIndexId);
|
|
||||||
|
|
||||||
const onViewFieldsChange = useRecoilCallback(
|
const onViewFieldsChange = useRecoilCallback(
|
||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
(viewFields: ViewField[]) => {
|
(viewFields: ViewField[]) => {
|
||||||
@ -124,30 +118,16 @@ export const RecordIndexContainer = () => {
|
|||||||
[columnDefinitions, setTableColumns],
|
[columnDefinitions, setTableColumns],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onViewGroupsChange = useRecoilCallback(
|
const onViewGroupsChange = useCallback(
|
||||||
({ set, snapshot }) =>
|
(viewGroups: ViewGroup[]) => {
|
||||||
(viewGroups: ViewGroup[]) => {
|
const newGroupDefinitions = mapViewGroupsToRecordGroupDefinitions({
|
||||||
const newGroupDefinitions = mapViewGroupsToRecordGroupDefinitions({
|
objectMetadataItem,
|
||||||
objectMetadataItem,
|
viewGroups,
|
||||||
viewGroups,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
setColumns(newGroupDefinitions);
|
setRecordGroup(newGroupDefinitions);
|
||||||
|
},
|
||||||
const existingRecordIndexGroupDefinitions = snapshot
|
[objectMetadataItem, setRecordGroup],
|
||||||
.getLoadable(recordGroupDefinitionsCallbackState)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
if (
|
|
||||||
!isDeeplyEqual(
|
|
||||||
existingRecordIndexGroupDefinitions,
|
|
||||||
newGroupDefinitions,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
set(recordGroupDefinitionsCallbackState, newGroupDefinitions);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[objectMetadataItem, recordGroupDefinitionsCallbackState, setColumns],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const setContextStoreTargetedRecordsRule = useSetRecoilComponentStateV2(
|
const setContextStoreTargetedRecordsRule = useSetRecoilComponentStateV2(
|
||||||
@ -229,10 +209,7 @@ export const RecordIndexContainer = () => {
|
|||||||
objectNameSingular={objectNameSingular}
|
objectNameSingular={objectNameSingular}
|
||||||
recordBoardId={recordIndexId}
|
recordBoardId={recordIndexId}
|
||||||
/>
|
/>
|
||||||
<RecordIndexBoardDataLoaderEffect
|
<RecordIndexBoardDataLoaderEffect recordBoardId={recordIndexId} />
|
||||||
objectNameSingular={objectNameSingular}
|
|
||||||
recordBoardId={recordIndexId}
|
|
||||||
/>
|
|
||||||
</StyledContainerWithPadding>
|
</StyledContainerWithPadding>
|
||||||
)}
|
)}
|
||||||
<RecordIndexActionMenu />
|
<RecordIndexActionMenu />
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
|
import { useAddNewCard } from '@/object-record/record-board/record-board-column/hooks/useAddNewCard';
|
||||||
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
|
import { useIsOpportunitiesCompanyFieldDisabled } from '@/object-record/record-board/record-board-column/hooks/useIsOpportunitiesCompanyFieldDisabled';
|
||||||
|
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
|
||||||
|
import { visibleRecordGroupIdsComponentSelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentSelector';
|
||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
import { RecordIndexPageKanbanAddMenuItem } from '@/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem';
|
import { RecordIndexPageKanbanAddMenuItem } from '@/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem';
|
||||||
import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext';
|
import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext';
|
||||||
@ -11,6 +12,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
|||||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useCallback, useContext } from 'react';
|
import { useCallback, useContext } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
@ -32,6 +34,10 @@ export const RecordIndexPageKanbanAddButton = () => {
|
|||||||
);
|
);
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
|
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
|
||||||
|
|
||||||
|
const visibleRecordGroupIds = useRecoilComponentValueV2(
|
||||||
|
visibleRecordGroupIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
const recordIndexKanbanFieldMetadataId = useRecoilValue(
|
const recordIndexKanbanFieldMetadataId = useRecoilValue(
|
||||||
recordIndexKanbanFieldMetadataIdState,
|
recordIndexKanbanFieldMetadataIdState,
|
||||||
);
|
);
|
||||||
@ -42,12 +48,11 @@ export const RecordIndexPageKanbanAddButton = () => {
|
|||||||
const isOpportunity =
|
const isOpportunity =
|
||||||
objectMetadataItem.nameSingular === CoreObjectNameSingular.Opportunity;
|
objectMetadataItem.nameSingular === CoreObjectNameSingular.Opportunity;
|
||||||
|
|
||||||
const { columnIdsState, visibleFieldDefinitionsState } =
|
const visibleFieldDefinitions = useRecoilComponentValueV2(
|
||||||
useRecordBoardStates(recordIndexId);
|
recordBoardVisibleFieldDefinitionsComponentSelector,
|
||||||
const columnIds = useRecoilValue(columnIdsState);
|
recordIndexId,
|
||||||
const visibleFieldDefinitions = useRecoilValue(
|
|
||||||
visibleFieldDefinitionsState(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const labelIdentifierField = visibleFieldDefinitions.find(
|
const labelIdentifierField = visibleFieldDefinitions.find(
|
||||||
(field) => field.isLabelIdentifier,
|
(field) => field.isLabelIdentifier,
|
||||||
);
|
);
|
||||||
@ -101,11 +106,10 @@ export const RecordIndexPageKanbanAddButton = () => {
|
|||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<StyledDropDownMenu>
|
<StyledDropDownMenu>
|
||||||
<StyledDropdownMenuItemsContainer>
|
<StyledDropdownMenuItemsContainer>
|
||||||
{columnIds.map((columnId) => (
|
{visibleRecordGroupIds.map((recordGroupId) => (
|
||||||
<RecordIndexPageKanbanAddMenuItem
|
<RecordIndexPageKanbanAddMenuItem
|
||||||
key={columnId}
|
key={recordGroupId}
|
||||||
columnId={columnId}
|
columnId={recordGroupId}
|
||||||
recordIndexId={recordIndexId}
|
|
||||||
onItemClick={handleItemClick}
|
onItemClick={handleItemClick}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
import { RecordGroupDefinitionType } from '@/object-record/record-group/types/RecordGroupDefinition';
|
import { RecordGroupDefinitionType } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
import { useRecordIndexPageKanbanAddMenuItem } from '@/object-record/record-index/hooks/useRecordIndexPageKanbanAddMenuItem';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { MenuItem, Tag } from 'twenty-ui';
|
import { MenuItem, Tag } from 'twenty-ui';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
const StyledMenuItem = styled(MenuItem)`
|
const StyledMenuItem = styled(MenuItem)`
|
||||||
width: calc(100% - 2 * var(--horizontal-padding));
|
width: calc(100% - 2 * var(--horizontal-padding));
|
||||||
@ -9,20 +11,18 @@ const StyledMenuItem = styled(MenuItem)`
|
|||||||
|
|
||||||
type RecordIndexPageKanbanAddMenuItemProps = {
|
type RecordIndexPageKanbanAddMenuItemProps = {
|
||||||
columnId: string;
|
columnId: string;
|
||||||
recordIndexId: string;
|
|
||||||
onItemClick: (columnDefinition: any) => void;
|
onItemClick: (columnDefinition: any) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexPageKanbanAddMenuItem = ({
|
export const RecordIndexPageKanbanAddMenuItem = ({
|
||||||
columnId,
|
columnId,
|
||||||
recordIndexId,
|
|
||||||
onItemClick,
|
onItemClick,
|
||||||
}: RecordIndexPageKanbanAddMenuItemProps) => {
|
}: RecordIndexPageKanbanAddMenuItemProps) => {
|
||||||
const { columnDefinition } = useRecordIndexPageKanbanAddMenuItem(
|
const recordGroupDefinition = useRecoilValue(
|
||||||
recordIndexId,
|
recordGroupDefinitionFamilyState(columnId),
|
||||||
columnId,
|
|
||||||
);
|
);
|
||||||
if (!columnDefinition) {
|
|
||||||
|
if (!isDefined(recordGroupDefinition)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,24 +31,24 @@ export const RecordIndexPageKanbanAddMenuItem = ({
|
|||||||
text={
|
text={
|
||||||
<Tag
|
<Tag
|
||||||
variant={
|
variant={
|
||||||
columnDefinition.type === RecordGroupDefinitionType.Value
|
recordGroupDefinition.type === RecordGroupDefinitionType.Value
|
||||||
? 'solid'
|
? 'solid'
|
||||||
: 'outline'
|
: 'outline'
|
||||||
}
|
}
|
||||||
color={
|
color={
|
||||||
columnDefinition.type === RecordGroupDefinitionType.Value
|
recordGroupDefinition.type === RecordGroupDefinitionType.Value
|
||||||
? columnDefinition.color
|
? recordGroupDefinition.color
|
||||||
: 'transparent'
|
: 'transparent'
|
||||||
}
|
}
|
||||||
text={columnDefinition.title}
|
text={recordGroupDefinition.title}
|
||||||
weight={
|
weight={
|
||||||
columnDefinition.type === RecordGroupDefinitionType.Value
|
recordGroupDefinition.type === RecordGroupDefinitionType.Value
|
||||||
? 'regular'
|
? 'regular'
|
||||||
: 'medium'
|
: 'medium'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={() => onItemClick(columnDefinition)}
|
onClick={() => onItemClick(recordGroupDefinition)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,14 +8,12 @@ import {
|
|||||||
|
|
||||||
import { PERSON_FRAGMENT_WITH_DEPTH_ZERO_RELATIONS } from '@/object-record/hooks/__mocks__/personFragments';
|
import { PERSON_FRAGMENT_WITH_DEPTH_ZERO_RELATIONS } from '@/object-record/hooks/__mocks__/personFragments';
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import { recordBoardKanbanFieldMetadataNameComponentState } from '@/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState';
|
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { MockedResponse } from '@apollo/client/testing';
|
import { MockedResponse } from '@apollo/client/testing';
|
||||||
import { expect } from '@storybook/test';
|
import { expect } from '@storybook/test';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
import { getJestMetadataAndApolloMocksAndContextStoreWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndContextStoreWrapper';
|
import { getJestMetadataAndApolloMocksAndContextStoreWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndContextStoreWrapper';
|
||||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
|
|
||||||
@ -232,10 +230,12 @@ describe('useRecordData', () => {
|
|||||||
const callback = jest.fn();
|
const callback = jest.fn();
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() => {
|
() => {
|
||||||
const kanbanFieldNameState = extractComponentState(
|
const [recordGroupFieldMetadata, setRecordGroupFieldMetadata] =
|
||||||
recordBoardKanbanFieldMetadataNameComponentState,
|
useRecoilComponentStateV2(
|
||||||
recordIndexId,
|
recordGroupFieldMetadataComponentState,
|
||||||
);
|
recordIndexId,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tableData: useExportFetchRecords({
|
tableData: useExportFetchRecords({
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
@ -246,8 +246,8 @@ describe('useRecordData', () => {
|
|||||||
delayMs: 0,
|
delayMs: 0,
|
||||||
viewType: ViewType.Kanban,
|
viewType: ViewType.Kanban,
|
||||||
}),
|
}),
|
||||||
useRecordBoardHook: useRecordBoard(recordIndexId),
|
kanbanFieldName: recordGroupFieldMetadata?.name,
|
||||||
kanbanFieldName: useRecoilValue(kanbanFieldNameState),
|
setRecordGroupFieldMetadata,
|
||||||
kanbanData: useObjectOptionsForBoard({
|
kanbanData: useObjectOptionsForBoard({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
recordBoardId: recordIndexId,
|
recordBoardId: recordIndexId,
|
||||||
@ -269,9 +269,7 @@ describe('useRecordData', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
result.current.useRecordBoardHook.setKanbanFieldMetadataName(
|
result.current.setRecordGroupFieldMetadata(updatedAtFieldMetadataItem);
|
||||||
updatedAtFieldMetadataItem?.name,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@ -322,10 +320,12 @@ describe('useRecordData', () => {
|
|||||||
const callback = jest.fn();
|
const callback = jest.fn();
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() => {
|
() => {
|
||||||
const kanbanFieldNameState = extractComponentState(
|
const [recordGroupFieldMetadata, setRecordGroupFieldMetadata] =
|
||||||
recordBoardKanbanFieldMetadataNameComponentState,
|
useRecoilComponentStateV2(
|
||||||
recordIndexId,
|
recordGroupFieldMetadataComponentState,
|
||||||
);
|
recordIndexId,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tableData: useExportFetchRecords({
|
tableData: useExportFetchRecords({
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
@ -336,8 +336,9 @@ describe('useRecordData', () => {
|
|||||||
delayMs: 0,
|
delayMs: 0,
|
||||||
viewType: ViewType.Table,
|
viewType: ViewType.Table,
|
||||||
}),
|
}),
|
||||||
setKanbanFieldName: useRecordBoard(recordIndexId),
|
objectMetadataItem,
|
||||||
kanbanFieldName: useRecoilValue(kanbanFieldNameState),
|
kanbanFieldName: recordGroupFieldMetadata?.name,
|
||||||
|
setRecordGroupFieldMetadata,
|
||||||
kanbanData: useObjectOptionsForBoard({
|
kanbanData: useObjectOptionsForBoard({
|
||||||
objectNameSingular: objectMetadataItem.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
recordBoardId: recordIndexId,
|
recordBoardId: recordIndexId,
|
||||||
@ -351,9 +352,14 @@ describe('useRecordData', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
result.current.setKanbanFieldName.setKanbanFieldMetadataName(
|
const fieldMetadataItem =
|
||||||
result.current.kanbanData.hiddenBoardFields[0].metadata.fieldName,
|
result.current.objectMetadataItem?.fields.find(
|
||||||
);
|
(fieldMetadata) =>
|
||||||
|
fieldMetadata.id ===
|
||||||
|
result.current.kanbanData.hiddenBoardFields[0].fieldMetadataId,
|
||||||
|
);
|
||||||
|
|
||||||
|
result.current.setRecordGroupFieldMetadata(fieldMetadataItem);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||||
@ -13,7 +12,7 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
|||||||
import { useLazyFindManyRecords } from '@/object-record/hooks/useLazyFindManyRecords';
|
import { useLazyFindManyRecords } from '@/object-record/hooks/useLazyFindManyRecords';
|
||||||
import { EXPORT_TABLE_DATA_DEFAULT_PAGE_SIZE } from '@/object-record/object-options-dropdown/constants/ExportTableDataDefaultPageSize';
|
import { EXPORT_TABLE_DATA_DEFAULT_PAGE_SIZE } from '@/object-record/object-options-dropdown/constants/ExportTableDataDefaultPageSize';
|
||||||
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
import { useFindManyParams } from '@/object-record/record-index/hooks/useLoadRecordIndexTable';
|
import { useFindManyParams } from '@/object-record/record-index/hooks/useLoadRecordIndexTable';
|
||||||
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
import { visibleTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/visibleTableColumnsComponentSelector';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
@ -68,10 +67,13 @@ export const useExportFetchRecords = ({
|
|||||||
viewBarId: recordIndexId,
|
viewBarId: recordIndexId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { kanbanFieldMetadataNameState } = useRecordBoardStates(recordIndexId);
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
const kanbanFieldMetadataName = useRecoilValue(kanbanFieldMetadataNameState);
|
recordGroupFieldMetadataComponentState,
|
||||||
|
recordIndexId,
|
||||||
|
);
|
||||||
|
|
||||||
const hiddenKanbanFieldColumn = hiddenBoardFields.find(
|
const hiddenKanbanFieldColumn = hiddenBoardFields.find(
|
||||||
(column) => column.metadata.fieldName === kanbanFieldMetadataName,
|
(column) => column.metadata.fieldName === recordGroupFieldMetadata?.name,
|
||||||
);
|
);
|
||||||
const columns = useRecoilComponentValueV2(
|
const columns = useRecoilComponentValueV2(
|
||||||
visibleTableColumnsComponentSelector,
|
visibleTableColumnsComponentSelector,
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
|
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/useSetRecordBoardRecordIds';
|
||||||
|
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
||||||
|
import { recordBoardFieldDefinitionsComponentState } from '@/object-record/record-board/states/recordBoardFieldDefinitionsComponentState';
|
||||||
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
|
||||||
import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hooks/useRecordBoardRecordGqlFields';
|
import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hooks/useRecordBoardRecordGqlFields';
|
||||||
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
||||||
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
||||||
@ -14,7 +15,7 @@ import { recordIndexIsCompactModeActiveState } from '@/object-record/record-inde
|
|||||||
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
|
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
|
||||||
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
|
import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState';
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||||
import { useSetRecordCountInCurrentView } from '@/views/hooks/useSetRecordCountInCurrentView';
|
import { useSetRecordCountInCurrentView } from '@/views/hooks/useSetRecordCountInCurrentView';
|
||||||
|
|
||||||
type UseLoadRecordIndexBoardProps = {
|
type UseLoadRecordIndexBoardProps = {
|
||||||
@ -31,33 +32,28 @@ export const useLoadRecordIndexBoard = ({
|
|||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
const {
|
|
||||||
setRecordIds: setRecordIdsInBoard,
|
const setRecordBoardFieldDefinitions = useSetRecoilComponentStateV2(
|
||||||
setFieldDefinitions,
|
recordBoardFieldDefinitionsComponentState,
|
||||||
setColumns,
|
recordBoardId,
|
||||||
isCompactModeActiveState,
|
);
|
||||||
} = useRecordBoard(recordBoardId);
|
|
||||||
|
const { setRecordIds: setRecordIdsInBoard } =
|
||||||
|
useSetRecordBoardRecordIds(recordBoardId);
|
||||||
|
|
||||||
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
||||||
|
|
||||||
const recordIndexFieldDefinitions = useRecoilValue(
|
const recordIndexFieldDefinitions = useRecoilValue(
|
||||||
recordIndexFieldDefinitionsState,
|
recordIndexFieldDefinitionsState,
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFieldDefinitions(recordIndexFieldDefinitions);
|
setRecordBoardFieldDefinitions(recordIndexFieldDefinitions);
|
||||||
}, [recordIndexFieldDefinitions, setFieldDefinitions]);
|
}, [recordIndexFieldDefinitions, setRecordBoardFieldDefinitions]);
|
||||||
|
|
||||||
const recordIndexViewFilterGroups = useRecoilValue(
|
const recordIndexViewFilterGroups = useRecoilValue(
|
||||||
recordIndexViewFilterGroupsState,
|
recordIndexViewFilterGroupsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordGroupDefinitions = useRecoilComponentValueV2(
|
|
||||||
recordGroupDefinitionsComponentState,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setColumns(recordGroupDefinitions);
|
|
||||||
}, [recordGroupDefinitions, setColumns]);
|
|
||||||
|
|
||||||
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
|
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
|
||||||
const recordIndexSorts = useRecoilValue(recordIndexSortsState);
|
const recordIndexSorts = useRecoilValue(recordIndexSortsState);
|
||||||
const requestFilters = computeViewRecordGqlOperationFilter(
|
const requestFilters = computeViewRecordGqlOperationFilter(
|
||||||
@ -92,7 +88,10 @@ export const useLoadRecordIndexBoard = ({
|
|||||||
const { setRecordCountInCurrentView } =
|
const { setRecordCountInCurrentView } =
|
||||||
useSetRecordCountInCurrentView(viewBarId);
|
useSetRecordCountInCurrentView(viewBarId);
|
||||||
|
|
||||||
const setIsCompactModeActive = useSetRecoilState(isCompactModeActiveState);
|
const setIsCompactModeActive = useSetRecoilComponentStateV2(
|
||||||
|
isRecordBoardCompactModeActiveComponentState,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRecordIdsInBoard(records);
|
setRecordIdsInBoard(records);
|
||||||
|
|||||||
@ -4,9 +4,9 @@ import { useRecoilValue } from 'recoil';
|
|||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
|
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { useSetRecordIdsForColumn } from '@/object-record/record-board/hooks/useSetRecordIdsForColumn';
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
|
||||||
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
import { computeViewRecordGqlOperationFilter } from '@/object-record/record-filter/utils/computeViewRecordGqlOperationFilter';
|
||||||
|
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
|
||||||
import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hooks/useRecordBoardRecordGqlFields';
|
import { useRecordBoardRecordGqlFields } from '@/object-record/record-index/hooks/useRecordBoardRecordGqlFields';
|
||||||
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
||||||
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
|
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
|
||||||
@ -30,16 +30,18 @@ export const useLoadRecordIndexBoardColumn = ({
|
|||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
const { setRecordIdsForColumn } = useRecordBoard(recordBoardId);
|
const { setRecordIdsForColumn } = useSetRecordIdsForColumn(recordBoardId);
|
||||||
const { columnsFamilySelector } = useRecordBoardStates(recordBoardId);
|
|
||||||
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
||||||
|
|
||||||
|
const recordGroupDefinition = useRecoilValue(
|
||||||
|
recordGroupDefinitionFamilyState(columnId),
|
||||||
|
);
|
||||||
|
|
||||||
const recordIndexViewFilterGroups = useRecoilValue(
|
const recordIndexViewFilterGroups = useRecoilValue(
|
||||||
recordIndexViewFilterGroupsState,
|
recordIndexViewFilterGroupsState,
|
||||||
);
|
);
|
||||||
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
|
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
|
||||||
const recordIndexSorts = useRecoilValue(recordIndexSortsState);
|
const recordIndexSorts = useRecoilValue(recordIndexSortsState);
|
||||||
const columnDefinition = useRecoilValue(columnsFamilySelector(columnId));
|
|
||||||
|
|
||||||
const requestFilters = computeViewRecordGqlOperationFilter(
|
const requestFilters = computeViewRecordGqlOperationFilter(
|
||||||
recordIndexFilters,
|
recordIndexFilters,
|
||||||
@ -60,9 +62,9 @@ export const useLoadRecordIndexBoardColumn = ({
|
|||||||
const filter = {
|
const filter = {
|
||||||
...requestFilters,
|
...requestFilters,
|
||||||
[recordIndexKanbanFieldMetadataItem?.name ?? '']: isDefined(
|
[recordIndexKanbanFieldMetadataItem?.name ?? '']: isDefined(
|
||||||
columnDefinition?.value,
|
recordGroupDefinition?.value,
|
||||||
)
|
)
|
||||||
? { in: [columnDefinition?.value] }
|
? { in: [recordGroupDefinition?.value] }
|
||||||
: { is: 'NULL' },
|
: { is: 'NULL' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -27,8 +27,7 @@ export const useFindManyParams = (
|
|||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentRecordGroupDefinition =
|
const currentRecordGroupDefinition = useCurrentRecordGroupDefinition();
|
||||||
useCurrentRecordGroupDefinition(recordTableId);
|
|
||||||
|
|
||||||
const tableViewFilterGroups = useRecoilComponentValueV2(
|
const tableViewFilterGroups = useRecoilComponentValueV2(
|
||||||
tableViewFilterGroupsComponentState,
|
tableViewFilterGroupsComponentState,
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { getObjectMetadataIdentifierFields } from '@/object-metadata/utils/getObjectMetadataIdentifierFields';
|
import { getObjectMetadataIdentifierFields } from '@/object-metadata/utils/getObjectMetadataIdentifierFields';
|
||||||
import { hasPositionField } from '@/object-metadata/utils/hasPositionField';
|
import { hasPositionField } from '@/object-metadata/utils/hasPositionField';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { recordBoardVisibleFieldDefinitionsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsComponentSelector';
|
||||||
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
export const useRecordBoardRecordGqlFields = ({
|
export const useRecordBoardRecordGqlFields = ({
|
||||||
@ -13,15 +13,17 @@ export const useRecordBoardRecordGqlFields = ({
|
|||||||
recordBoardId: string;
|
recordBoardId: string;
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
const { kanbanFieldMetadataNameState, visibleFieldDefinitionsState } =
|
const visibleFieldDefinitions = useRecoilComponentValueV2(
|
||||||
useRecordBoardStates(recordBoardId);
|
recordBoardVisibleFieldDefinitionsComponentSelector,
|
||||||
|
recordBoardId,
|
||||||
|
);
|
||||||
|
|
||||||
const { imageIdentifierFieldMetadataItem, labelIdentifierFieldMetadataItem } =
|
const { imageIdentifierFieldMetadataItem, labelIdentifierFieldMetadataItem } =
|
||||||
getObjectMetadataIdentifierFields({ objectMetadataItem });
|
getObjectMetadataIdentifierFields({ objectMetadataItem });
|
||||||
|
|
||||||
const kanbanFieldMetadataName = useRecoilValue(kanbanFieldMetadataNameState);
|
const recordGroupFieldMetadata = useRecoilComponentValueV2(
|
||||||
const visibleFieldDefinitions = useRecoilValue(
|
recordGroupFieldMetadataComponentState,
|
||||||
visibleFieldDefinitionsState(),
|
recordBoardId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const identifierQueryFields: Record<string, boolean> = {};
|
const identifierQueryFields: Record<string, boolean> = {};
|
||||||
@ -59,8 +61,8 @@ export const useRecordBoardRecordGqlFields = ({
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isDefined(kanbanFieldMetadataName)) {
|
if (isDefined(recordGroupFieldMetadata?.name)) {
|
||||||
recordGqlFields[kanbanFieldMetadataName] = true;
|
recordGqlFields[recordGroupFieldMetadata.name] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return recordGqlFields;
|
return recordGqlFields;
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
export const useRecordIndexPageKanbanAddMenuItem = (
|
|
||||||
recordIndexId: string,
|
|
||||||
columnId: string,
|
|
||||||
) => {
|
|
||||||
const { columnsFamilySelector } = useRecordBoardStates(recordIndexId);
|
|
||||||
const columnDefinition = useRecoilValue(columnsFamilySelector(columnId));
|
|
||||||
|
|
||||||
return { columnDefinition };
|
|
||||||
};
|
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
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,
|
||||||
|
});
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
|
||||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
||||||
|
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
|
||||||
|
|
||||||
export const tableRowIdsByGroupComponentFamilyState =
|
export const recordIndexRowIdsByGroupComponentFamilyState =
|
||||||
createComponentFamilyStateV2<string[], RecordGroupDefinition['id']>({
|
createComponentFamilyStateV2<string[], RecordGroupDefinition['id']>({
|
||||||
key: 'tableRowIdsByGroupComponentFamilyState',
|
key: 'recordIndexRowIdsByGroupComponentFamilyState',
|
||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
componentInstanceContext: RecordTableComponentInstanceContext,
|
componentInstanceContext: ViewComponentInstanceContext,
|
||||||
});
|
});
|
||||||
@ -1,7 +1,8 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { isNonEmptyString, isNull } from '@sniptt/guards';
|
import { isNonEmptyString, isNull } from '@sniptt/guards';
|
||||||
|
|
||||||
import { hasRecordGroupDefinitionsComponentSelector } from '@/object-record/record-group/states/hasRecordGroupDefinitionsComponentSelector';
|
import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector';
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
import { RecordTableComponentInstance } from '@/object-record/record-table/components/RecordTableComponentInstance';
|
||||||
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider';
|
||||||
import { RecordTableStickyEffect } from '@/object-record/record-table/components/RecordTableStickyEffect';
|
import { RecordTableStickyEffect } from '@/object-record/record-table/components/RecordTableStickyEffect';
|
||||||
@ -16,7 +17,6 @@ import { RecordTableRecordGroupsBody } from '@/object-record/record-table/record
|
|||||||
import { RecordTableHeader } from '@/object-record/record-table/record-table-header/components/RecordTableHeader';
|
import { RecordTableHeader } from '@/object-record/record-table/record-table-header/components/RecordTableHeader';
|
||||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||||
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
|
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||||
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
|
import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
@ -53,8 +53,8 @@ export const RecordTable = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableRowIds = useRecoilComponentValueV2(
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -64,13 +64,13 @@ export const RecordTable = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const hasRecordGroups = useRecoilComponentValueV2(
|
const hasRecordGroups = useRecoilComponentValueV2(
|
||||||
hasRecordGroupDefinitionsComponentSelector,
|
hasRecordGroupsComponentSelector,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordTableIsEmpty =
|
const recordTableIsEmpty =
|
||||||
!isRecordTableInitialLoading &&
|
!isRecordTableInitialLoading &&
|
||||||
tableRowIds.length === 0 &&
|
allRowIds.length === 0 &&
|
||||||
isNull(pendingRecordId);
|
isNull(pendingRecordId);
|
||||||
|
|
||||||
const { resetTableRowSelection, setRowSelected } = useRecordTable({
|
const { resetTableRowSelection, setRowSelected } = useRecordTable({
|
||||||
@ -109,9 +109,7 @@ export const RecordTable = ({
|
|||||||
{!hasRecordGroups ? (
|
{!hasRecordGroups ? (
|
||||||
<RecordTableNoRecordGroupBody />
|
<RecordTableNoRecordGroupBody />
|
||||||
) : (
|
) : (
|
||||||
<RecordTableRecordGroupsBody
|
<RecordTableRecordGroupsBody />
|
||||||
objectNameSingular={objectNameSingular}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<RecordTableStickyEffect />
|
<RecordTableStickyEffect />
|
||||||
</StyledTable>
|
</StyledTable>
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { RecordTableBodyFetchMoreLoader } from '@/object-record/record-table/record-table-body/components/RecordTableBodyFetchMoreLoader';
|
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 { RecordTableRow } from '@/object-record/record-table/record-table-row/components/RecordTableRow';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
export const RecordTableNoRecordGroupRows = () => {
|
export const RecordTableNoRecordGroupRows = () => {
|
||||||
const rowIds = useRecoilComponentValueV2(tableAllRowIdsComponentState);
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
|
recordIndexAllRowIdsComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{rowIds.map((recordId, rowIndex) => {
|
{allRowIds.map((recordId, rowIndex) => {
|
||||||
return (
|
return (
|
||||||
<RecordTableRow
|
<RecordTableRow
|
||||||
key={recordId}
|
key={recordId}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId';
|
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 { RecordTableRow } from '@/object-record/record-table/record-table-row/components/RecordTableRow';
|
import { RecordTableRow } from '@/object-record/record-table/record-table-row/components/RecordTableRow';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { tableRowIdsByGroupComponentFamilyState } from '@/object-record/record-table/states/tableRowIdsByGroupComponentFamilyState';
|
|
||||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
@ -9,10 +9,12 @@ import { useMemo } from 'react';
|
|||||||
export const RecordTableRecordGroupRows = () => {
|
export const RecordTableRecordGroupRows = () => {
|
||||||
const recordGroupId = useCurrentRecordGroupId();
|
const recordGroupId = useCurrentRecordGroupId();
|
||||||
|
|
||||||
const allRowIds = useRecoilComponentValueV2(tableAllRowIdsComponentState);
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
|
recordIndexAllRowIdsComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
const recordGroupRowIds = useRecoilComponentFamilyValueV2(
|
const recordGroupRowIds = useRecoilComponentFamilyValueV2(
|
||||||
tableRowIdsByGroupComponentFamilyState,
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
recordGroupId,
|
recordGroupId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { isNull } from '@sniptt/guards';
|
import { isNull } from '@sniptt/guards';
|
||||||
|
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { RecordTableEmptyState } from '@/object-record/record-table/empty-state/components/RecordTableEmptyState';
|
import { RecordTableEmptyState } from '@/object-record/record-table/empty-state/components/RecordTableEmptyState';
|
||||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||||
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
|
import { recordTablePendingRecordIdComponentState } from '@/object-record/record-table/states/recordTablePendingRecordIdComponentState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
type RecordTableEmptyHandlerProps = {
|
type RecordTableEmptyHandlerProps = {
|
||||||
@ -20,8 +20,8 @@ export const RecordTableEmptyHandler = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableRowIds = useRecoilComponentValueV2(
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ export const RecordTableEmptyHandler = ({
|
|||||||
|
|
||||||
const recordTableIsEmpty =
|
const recordTableIsEmpty =
|
||||||
!isRecordTableInitialLoading &&
|
!isRecordTableInitialLoading &&
|
||||||
tableRowIds.length === 0 &&
|
allRowIds.length === 0 &&
|
||||||
isNull(pendingRecordId);
|
isNull(pendingRecordId);
|
||||||
|
|
||||||
if (recordTableIsEmpty) {
|
if (recordTableIsEmpty) {
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
|
|
||||||
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
import { getActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getActionMenuDropdownIdFromActionMenuId';
|
||||||
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
import { getActionMenuIdFromRecordIndexId } from '@/action-menu/utils/getActionMenuIdFromRecordIndexId';
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
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 { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
@ -18,8 +18,8 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableAllRowIdsState = useRecoilComponentCallbackStateV2(
|
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
recordTableIdFromContext,
|
recordTableIdFromContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -43,9 +43,9 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
|||||||
return useRecoilCallback(
|
return useRecoilCallback(
|
||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
() => {
|
() => {
|
||||||
const tableRowIds = getSnapshotValue(snapshot, tableAllRowIdsState);
|
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||||
|
|
||||||
for (const rowId of tableRowIds) {
|
for (const rowId of allRowIds) {
|
||||||
set(isRowSelectedFamilyState(rowId), false);
|
set(isRowSelectedFamilyState(rowId), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ export const useResetTableRowSelection = (recordTableId?: string) => {
|
|||||||
set(isActionMenuDropdownOpenState, false);
|
set(isActionMenuDropdownOpenState, false);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
tableAllRowIdsState,
|
recordIndexAllRowIdsState,
|
||||||
hasUserSelectedAllRowsState,
|
hasUserSelectedAllRowsState,
|
||||||
isActionMenuDropdownOpenState,
|
isActionMenuDropdownOpenState,
|
||||||
isRowSelectedFamilyState,
|
isRowSelectedFamilyState,
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { allRowsSelectedStatusComponentSelector } from '@/object-record/record-table/states/selectors/allRowsSelectedStatusComponentSelector';
|
import { allRowsSelectedStatusComponentSelector } from '@/object-record/record-table/states/selectors/allRowsSelectedStatusComponentSelector';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
|
|
||||||
@ -15,8 +15,8 @@ export const useSelectAllRows = (recordTableId?: string) => {
|
|||||||
isRowSelectedComponentFamilyState,
|
isRowSelectedComponentFamilyState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
const tableAllRowIdsState = useRecoilComponentCallbackStateV2(
|
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -28,24 +28,24 @@ export const useSelectAllRows = (recordTableId?: string) => {
|
|||||||
allRowsSelectedStatusSelector,
|
allRowsSelectedStatusSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableRowIds = getSnapshotValue(snapshot, tableAllRowIdsState);
|
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
allRowsSelectedStatus === 'none' ||
|
allRowsSelectedStatus === 'none' ||
|
||||||
allRowsSelectedStatus === 'some'
|
allRowsSelectedStatus === 'some'
|
||||||
) {
|
) {
|
||||||
for (const rowId of tableRowIds) {
|
for (const rowId of allRowIds) {
|
||||||
set(isRowSelectedFamilyState(rowId), true);
|
set(isRowSelectedFamilyState(rowId), true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const rowId of tableRowIds) {
|
for (const rowId of allRowIds) {
|
||||||
set(isRowSelectedFamilyState(rowId), false);
|
set(isRowSelectedFamilyState(rowId), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
allRowsSelectedStatusSelector,
|
allRowsSelectedStatusSelector,
|
||||||
tableAllRowIdsState,
|
recordIndexAllRowIdsState,
|
||||||
isRowSelectedFamilyState,
|
isRowSelectedFamilyState,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
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 { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { hasUserSelectedAllRowsComponentState } from '@/object-record/record-table/record-table-row/states/hasUserSelectedAllRowsFamilyState';
|
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 { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { tableRowIdsByGroupComponentFamilyState } from '@/object-record/record-table/states/tableRowIdsByGroupComponentFamilyState';
|
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
@ -21,12 +21,12 @@ export const useSetRecordTableData = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
onEntityCountChange,
|
onEntityCountChange,
|
||||||
}: useSetRecordTableDataProps) => {
|
}: useSetRecordTableDataProps) => {
|
||||||
const tableRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
const recordIndexRowIdsByGroupFamilyState = useRecoilComponentCallbackStateV2(
|
||||||
tableRowIdsByGroupComponentFamilyState,
|
recordIndexRowIdsByGroupComponentFamilyState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
const tableAllRowIdsState = useRecoilComponentCallbackStateV2(
|
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
const isRowSelectedFamilyState = useRecoilComponentCallbackStateV2(
|
const isRowSelectedFamilyState = useRecoilComponentCallbackStateV2(
|
||||||
@ -37,8 +37,8 @@ export const useSetRecordTableData = ({
|
|||||||
hasUserSelectedAllRowsComponentState,
|
hasUserSelectedAllRowsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
const recordGroupDefinitionsState = useRecoilComponentCallbackStateV2(
|
const recordIndexRecordGroupIdsState = useRecoilComponentCallbackStateV2(
|
||||||
recordGroupDefinitionsComponentState,
|
recordGroupIdsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -46,11 +46,11 @@ export const useSetRecordTableData = ({
|
|||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
<T extends ObjectRecord>({
|
<T extends ObjectRecord>({
|
||||||
records,
|
records,
|
||||||
recordGroupId,
|
currentRecordGroupId,
|
||||||
totalCount,
|
totalCount,
|
||||||
}: {
|
}: {
|
||||||
records: T[];
|
records: T[];
|
||||||
recordGroupId?: string;
|
currentRecordGroupId?: string;
|
||||||
totalCount?: number;
|
totalCount?: number;
|
||||||
}) => {
|
}) => {
|
||||||
for (const record of records) {
|
for (const record of records) {
|
||||||
@ -66,9 +66,9 @@ export const useSetRecordTableData = ({
|
|||||||
|
|
||||||
const currentRowIds = getSnapshotValue(
|
const currentRowIds = getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
recordGroupId
|
currentRecordGroupId
|
||||||
? tableRowIdsByGroupFamilyState(recordGroupId)
|
? recordIndexRowIdsByGroupFamilyState(currentRecordGroupId)
|
||||||
: tableAllRowIdsState,
|
: recordIndexAllRowIdsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasUserSelectedAllRows = getSnapshotValue(
|
const hasUserSelectedAllRows = getSnapshotValue(
|
||||||
@ -76,9 +76,9 @@ export const useSetRecordTableData = ({
|
|||||||
hasUserSelectedAllRowsState,
|
hasUserSelectedAllRowsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordGroupDefinitions = getSnapshotValue(
|
const recordGroupIds = getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
recordGroupDefinitionsState,
|
recordIndexRecordGroupIdsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const recordIds = records.map((record) => record.id);
|
const recordIds = records.map((record) => record.id);
|
||||||
@ -90,39 +90,42 @@ export const useSetRecordTableData = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDefined(recordGroupId)) {
|
if (isDefined(currentRecordGroupId)) {
|
||||||
// TODO: Hack to store all ids in the same order as the record group definitions
|
// TODO: Hack to store all ids in the same order as the record group definitions
|
||||||
// Should be replaced by something more efficient
|
// Should be replaced by something more efficient
|
||||||
const allRowIds: string[] = [];
|
const allRowIds: string[] = [];
|
||||||
|
|
||||||
set(tableRowIdsByGroupFamilyState(recordGroupId), recordIds);
|
set(
|
||||||
|
recordIndexRowIdsByGroupFamilyState(currentRecordGroupId),
|
||||||
|
recordIds,
|
||||||
|
);
|
||||||
|
|
||||||
for (const recordGroupDefinition of recordGroupDefinitions) {
|
for (const recordGroupId of recordGroupIds) {
|
||||||
const tableRowIdsByGroup =
|
const tableRowIdsByGroup =
|
||||||
recordGroupDefinition.id !== recordGroupId
|
recordGroupId !== currentRecordGroupId
|
||||||
? getSnapshotValue(
|
? getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
tableRowIdsByGroupFamilyState(recordGroupDefinition.id),
|
recordIndexRowIdsByGroupFamilyState(recordGroupId),
|
||||||
)
|
)
|
||||||
: recordIds;
|
: recordIds;
|
||||||
|
|
||||||
allRowIds.push(...tableRowIdsByGroup);
|
allRowIds.push(...tableRowIdsByGroup);
|
||||||
}
|
}
|
||||||
set(tableAllRowIdsState, allRowIds);
|
set(recordIndexAllRowIdsState, allRowIds);
|
||||||
} else {
|
} else {
|
||||||
set(tableAllRowIdsState, recordIds);
|
set(recordIndexAllRowIdsState, recordIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEntityCountChange(totalCount);
|
onEntityCountChange(totalCount);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
tableRowIdsByGroupFamilyState,
|
recordIndexRowIdsByGroupFamilyState,
|
||||||
tableAllRowIdsState,
|
recordIndexAllRowIdsState,
|
||||||
recordGroupDefinitionsState,
|
hasUserSelectedAllRowsState,
|
||||||
|
recordIndexRecordGroupIdsState,
|
||||||
onEntityCountChange,
|
onEntityCountChange,
|
||||||
isRowSelectedFamilyState,
|
isRowSelectedFamilyState,
|
||||||
hasUserSelectedAllRowsState,
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import { useRecoilCallback } from 'recoil';
|
|||||||
import { MoveFocusDirection } from '@/object-record/record-table/types/MoveFocusDirection';
|
import { MoveFocusDirection } from '@/object-record/record-table/types/MoveFocusDirection';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
|
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { numberOfTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/numberOfTableColumnsComponentSelector';
|
import { numberOfTableColumnsComponentSelector } from '@/object-record/record-table/states/selectors/numberOfTableColumnsComponentSelector';
|
||||||
import { softFocusPositionComponentState } from '@/object-record/record-table/states/softFocusPositionComponentState';
|
import { softFocusPositionComponentState } from '@/object-record/record-table/states/softFocusPositionComponentState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||||
import { useSetSoftFocusPosition } from './internal/useSetSoftFocusPosition';
|
import { useSetSoftFocusPosition } from './internal/useSetSoftFocusPosition';
|
||||||
|
|
||||||
@ -17,8 +17,8 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableAllRowIdsState = useRecoilComponentCallbackStateV2(
|
const recordIndexAllRowIdsState = useRecoilComponentCallbackStateV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
|||||||
const moveDown = useRecoilCallback(
|
const moveDown = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
() => {
|
() => {
|
||||||
const allRowIds = getSnapshotValue(snapshot, tableAllRowIdsState);
|
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||||
const softFocusPosition = getSnapshotValue(
|
const softFocusPosition = getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
softFocusPositionState,
|
softFocusPositionState,
|
||||||
@ -64,7 +64,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
|||||||
row: newRowIndex,
|
row: newRowIndex,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[tableAllRowIdsState, setSoftFocusPosition, softFocusPositionState],
|
[recordIndexAllRowIdsState, setSoftFocusPosition, softFocusPositionState],
|
||||||
);
|
);
|
||||||
|
|
||||||
const numberOfTableColumnsSelector = useRecoilComponentCallbackStateV2(
|
const numberOfTableColumnsSelector = useRecoilComponentCallbackStateV2(
|
||||||
@ -75,7 +75,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
|||||||
const moveRight = useRecoilCallback(
|
const moveRight = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
() => {
|
() => {
|
||||||
const allRowIds = getSnapshotValue(snapshot, tableAllRowIdsState);
|
const allRowIds = getSnapshotValue(snapshot, recordIndexAllRowIdsState);
|
||||||
const softFocusPosition = getSnapshotValue(
|
const softFocusPosition = getSnapshotValue(
|
||||||
snapshot,
|
snapshot,
|
||||||
softFocusPositionState,
|
softFocusPositionState,
|
||||||
@ -116,7 +116,7 @@ export const useRecordTableMoveFocus = (recordTableId?: string) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
tableAllRowIdsState,
|
recordIndexAllRowIdsState,
|
||||||
softFocusPositionState,
|
softFocusPositionState,
|
||||||
numberOfTableColumnsSelector,
|
numberOfTableColumnsSelector,
|
||||||
setSoftFocusPosition,
|
setSoftFocusPosition,
|
||||||
|
|||||||
@ -3,10 +3,10 @@ import { ReactNode, useContext } from 'react';
|
|||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { RecordTableContext } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { RecordTableContext } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { useComputeNewRowPosition } from '@/object-record/record-table/hooks/useComputeNewRowPosition';
|
import { useComputeNewRowPosition } from '@/object-record/record-table/hooks/useComputeNewRowPosition';
|
||||||
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
import { isRemoveSortingModalOpenState } from '@/object-record/record-table/states/isRemoveSortingModalOpenState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
@ -22,8 +22,8 @@ export const RecordTableBodyDragDropContext = ({
|
|||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableAllRowIds = useRecoilComponentValueV2(
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { currentViewWithCombinedFiltersAndSorts } =
|
const { currentViewWithCombinedFiltersAndSorts } =
|
||||||
@ -43,7 +43,7 @@ export const RecordTableBodyDragDropContext = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const computeResult = computeNewRowPosition(result, tableAllRowIds);
|
const computeResult = computeNewRowPosition(result, allRowIds);
|
||||||
|
|
||||||
if (!isDefined(computeResult)) {
|
if (!isDefined(computeResult)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { RecordTableNoRecordGroupRows } from '@/object-record/record-table/components/RecordTableNoRecordGroupRows';
|
import { RecordTableNoRecordGroupRows } from '@/object-record/record-table/components/RecordTableNoRecordGroupRows';
|
||||||
import { RecordTableBodyDragDropContext } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDragDropContext';
|
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 { RecordTableBodyDroppable } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDroppable';
|
||||||
import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading';
|
import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading';
|
||||||
import { RecordTablePendingRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRow';
|
import { RecordTablePendingRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRow';
|
||||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
export const RecordTableNoRecordGroupBody = () => {
|
export const RecordTableNoRecordGroupBody = () => {
|
||||||
const tableAllRowIds = useRecoilComponentValueV2(
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
tableAllRowIdsComponentState,
|
recordIndexAllRowIdsComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const isRecordTableInitialLoading = useRecoilComponentValueV2(
|
const isRecordTableInitialLoading = useRecoilComponentValueV2(
|
||||||
isRecordTableInitialLoadingComponentState,
|
isRecordTableInitialLoadingComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isRecordTableInitialLoading && tableAllRowIds.length === 0) {
|
if (isRecordTableInitialLoading && allRowIds.length === 0) {
|
||||||
return <RecordTableBodyLoading />;
|
return <RecordTableBodyLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,7 @@ export const RecordTableRecordGroupBodyEffect = () => {
|
|||||||
if (!loading) {
|
if (!loading) {
|
||||||
setRecordTableData({
|
setRecordTableData({
|
||||||
records,
|
records,
|
||||||
recordGroupId,
|
currentRecordGroupId: recordGroupId,
|
||||||
totalCount,
|
totalCount,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,15 @@
|
|||||||
import { RecordGroupContext } from '@/object-record/record-group/states/context/RecordGroupContext';
|
import { RecordGroupContext } from '@/object-record/record-group/states/context/RecordGroupContext';
|
||||||
import { recordGroupDefinitionsComponentState } from '@/object-record/record-group/states/recordGroupDefinitionsComponentState';
|
import { recordGroupIdsComponentState } from '@/object-record/record-group/states/recordGroupIdsComponentState';
|
||||||
import { RecordTableRecordGroupBodyEffect } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupBodyEffect';
|
import { RecordTableRecordGroupBodyEffect } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupBodyEffect';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
export const RecordTableRecordGroupBodyEffects = () => {
|
export const RecordTableRecordGroupBodyEffects = () => {
|
||||||
const recordGroupDefinitions = useRecoilComponentValueV2(
|
const recordGroupIds = useRecoilComponentValueV2(
|
||||||
recordGroupDefinitionsComponentState,
|
recordGroupIdsComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
return recordGroupDefinitions.map((recordGroupDefinition) => (
|
return recordGroupIds.map((recordGroupId) => (
|
||||||
<RecordGroupContext.Provider
|
<RecordGroupContext.Provider key={recordGroupId} value={{ recordGroupId }}>
|
||||||
key={recordGroupDefinition.id}
|
|
||||||
value={{ recordGroupId: recordGroupDefinition.id }}
|
|
||||||
>
|
|
||||||
<RecordTableRecordGroupBodyEffect />
|
<RecordTableRecordGroupBodyEffect />
|
||||||
</RecordGroupContext.Provider>
|
</RecordGroupContext.Provider>
|
||||||
));
|
));
|
||||||
|
|||||||
@ -1,32 +1,28 @@
|
|||||||
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
|
|
||||||
import { RecordGroupContext } from '@/object-record/record-group/states/context/RecordGroupContext';
|
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 { RecordTableRecordGroupRows } from '@/object-record/record-table/components/RecordTableRecordGroupRows';
|
import { RecordTableRecordGroupRows } from '@/object-record/record-table/components/RecordTableRecordGroupRows';
|
||||||
import { RecordTableBodyDragDropContext } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDragDropContext';
|
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 { RecordTableBodyDroppable } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDroppable';
|
||||||
import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading';
|
import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading';
|
||||||
import { RecordTablePendingRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRow';
|
import { RecordTablePendingRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRow';
|
||||||
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
|
|
||||||
type RecordTableRecordGroupsBodyProps = {
|
export const RecordTableRecordGroupsBody = () => {
|
||||||
objectNameSingular: string;
|
const allRowIds = useRecoilComponentValueV2(
|
||||||
};
|
recordIndexAllRowIdsComponentState,
|
||||||
|
|
||||||
export const RecordTableRecordGroupsBody = ({
|
|
||||||
objectNameSingular,
|
|
||||||
}: RecordTableRecordGroupsBodyProps) => {
|
|
||||||
const tableAllRowIds = useRecoilComponentValueV2(
|
|
||||||
tableAllRowIdsComponentState,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const isRecordTableInitialLoading = useRecoilComponentValueV2(
|
const isRecordTableInitialLoading = useRecoilComponentValueV2(
|
||||||
isRecordTableInitialLoadingComponentState,
|
isRecordTableInitialLoadingComponentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { visibleRecordGroups } = useRecordGroups({ objectNameSingular });
|
const visibleRecordGroupIds = useRecoilComponentValueV2(
|
||||||
|
visibleRecordGroupIdsComponentSelector,
|
||||||
|
);
|
||||||
|
|
||||||
if (isRecordTableInitialLoading && tableAllRowIds.length === 0) {
|
if (isRecordTableInitialLoading && allRowIds.length === 0) {
|
||||||
return <RecordTableBodyLoading />;
|
return <RecordTableBodyLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,10 +30,10 @@ export const RecordTableRecordGroupsBody = ({
|
|||||||
<RecordTableBodyDragDropContext>
|
<RecordTableBodyDragDropContext>
|
||||||
<RecordTableBodyDroppable>
|
<RecordTableBodyDroppable>
|
||||||
<RecordTablePendingRow />
|
<RecordTablePendingRow />
|
||||||
{visibleRecordGroups.map((recordGroupDefinition) => (
|
{visibleRecordGroupIds.map((recordGroupId) => (
|
||||||
<RecordGroupContext.Provider
|
<RecordGroupContext.Provider
|
||||||
key={recordGroupDefinition.id}
|
key={recordGroupId}
|
||||||
value={{ recordGroupId: recordGroupDefinition.id }}
|
value={{ recordGroupId }}
|
||||||
>
|
>
|
||||||
<RecordTableRecordGroupRows />
|
<RecordTableRecordGroupRows />
|
||||||
</RecordGroupContext.Provider>
|
</RecordGroupContext.Provider>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { selectedRowIdsComponentSelector } from '@/object-record/record-table/states/selectors/selectedRowIdsComponentSelector';
|
import { selectedRowIdsComponentSelector } from '@/object-record/record-table/states/selectors/selectedRowIdsComponentSelector';
|
||||||
|
|
||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
import { AllRowsSelectedStatus } from '../../types/AllRowSelectedStatus';
|
import { AllRowsSelectedStatus } from '../../types/AllRowSelectedStatus';
|
||||||
|
|
||||||
@ -12,8 +12,9 @@ export const allRowsSelectedStatusComponentSelector =
|
|||||||
get:
|
get:
|
||||||
({ instanceId }) =>
|
({ instanceId }) =>
|
||||||
({ get }) => {
|
({ get }) => {
|
||||||
const tableRowIds = get(
|
const allRowIds = get(
|
||||||
tableAllRowIdsComponentState.atomFamily({
|
// TODO: Working because instanceId is the same, but we're not in the same context, should be changed !
|
||||||
|
recordIndexAllRowIdsComponentState.atomFamily({
|
||||||
instanceId,
|
instanceId,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -29,7 +30,7 @@ export const allRowsSelectedStatusComponentSelector =
|
|||||||
const allRowsSelectedStatus =
|
const allRowsSelectedStatus =
|
||||||
numberOfSelectedRows === 0
|
numberOfSelectedRows === 0
|
||||||
? 'none'
|
? 'none'
|
||||||
: selectedRowIds.length === tableRowIds.length
|
: selectedRowIds.length === allRowIds.length
|
||||||
? 'all'
|
? 'all'
|
||||||
: 'some';
|
: 'some';
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
|
|
||||||
export const selectedRowIdsComponentSelector = createComponentSelectorV2<
|
export const selectedRowIdsComponentSelector = createComponentSelectorV2<
|
||||||
@ -11,13 +11,14 @@ export const selectedRowIdsComponentSelector = createComponentSelectorV2<
|
|||||||
get:
|
get:
|
||||||
({ instanceId }) =>
|
({ instanceId }) =>
|
||||||
({ get }) => {
|
({ get }) => {
|
||||||
const rowIds = get(
|
const allRowIds = get(
|
||||||
tableAllRowIdsComponentState.atomFamily({
|
// TODO: Working because instanceId is the same, but we're not in the same context, should be changed !
|
||||||
|
recordIndexAllRowIdsComponentState.atomFamily({
|
||||||
instanceId,
|
instanceId,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return rowIds.filter(
|
return allRowIds.filter(
|
||||||
(rowId) =>
|
(rowId) =>
|
||||||
get(
|
get(
|
||||||
isRowSelectedComponentFamilyState.atomFamily({
|
isRowSelectedComponentFamilyState.atomFamily({
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { recordIndexAllRowIdsComponentState } from '@/object-record/record-index/states/recordIndexAllRowIdsComponentState';
|
||||||
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
import { isRowSelectedComponentFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedComponentFamilyState';
|
||||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||||
import { tableAllRowIdsComponentState } from '@/object-record/record-table/states/tableAllRowIdsComponentState';
|
|
||||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||||
|
|
||||||
export const unselectedRowIdsComponentSelector = createComponentSelectorV2<
|
export const unselectedRowIdsComponentSelector = createComponentSelectorV2<
|
||||||
@ -12,7 +12,8 @@ export const unselectedRowIdsComponentSelector = createComponentSelectorV2<
|
|||||||
({ instanceId }) =>
|
({ instanceId }) =>
|
||||||
({ get }) => {
|
({ get }) => {
|
||||||
const rowIds = get(
|
const rowIds = get(
|
||||||
tableAllRowIdsComponentState.atomFamily({
|
// TODO: Working because instanceId is the same, but we're not in the same context, should be changed !
|
||||||
|
recordIndexAllRowIdsComponentState.atomFamily({
|
||||||
instanceId,
|
instanceId,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
|
||||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
|
||||||
|
|
||||||
export const tableAllRowIdsComponentState = createComponentStateV2<string[]>({
|
|
||||||
key: 'tableAllRowIdsComponentState',
|
|
||||||
defaultValue: [],
|
|
||||||
componentInstanceContext: RecordTableComponentInstanceContext,
|
|
||||||
});
|
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||||
|
import { ComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/types/ComponentFamilyStateV2';
|
||||||
|
import { globalComponentInstanceContextMap } from '@/ui/utilities/state/component-state/utils/globalComponentInstanceContextMap';
|
||||||
|
import { SerializableParam, useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
export const useRecoilComponentFamilyStateV2 = <
|
||||||
|
StateType,
|
||||||
|
FamilyKey extends SerializableParam,
|
||||||
|
>(
|
||||||
|
componentState: ComponentFamilyStateV2<StateType, FamilyKey>,
|
||||||
|
familyKey: FamilyKey,
|
||||||
|
instanceIdFromProps?: string,
|
||||||
|
) => {
|
||||||
|
const componentInstanceContext = globalComponentInstanceContextMap.get(
|
||||||
|
componentState.key,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!componentInstanceContext) {
|
||||||
|
throw new Error(
|
||||||
|
`Instance context for key "${componentState.key}" is not defined`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||||
|
componentInstanceContext,
|
||||||
|
instanceIdFromProps,
|
||||||
|
);
|
||||||
|
|
||||||
|
return useRecoilState(componentState.atomFamily({ instanceId, familyKey }));
|
||||||
|
};
|
||||||
@ -20,6 +20,56 @@ export const useSaveCurrentViewGroups = (viewBarComponentId?: string) => {
|
|||||||
viewBarComponentId,
|
viewBarComponentId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const saveViewGroup = useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
async (viewGroupToSave: ViewGroup) => {
|
||||||
|
const currentViewId = snapshot
|
||||||
|
.getLoadable(currentViewIdCallbackState)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (!currentViewId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const view = await getViewFromCache(currentViewId);
|
||||||
|
|
||||||
|
if (isUndefinedOrNull(view)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentViewGroups = view.viewGroups;
|
||||||
|
|
||||||
|
const existingField = currentViewGroups.find(
|
||||||
|
(currentViewGroup) =>
|
||||||
|
currentViewGroup.fieldValue === viewGroupToSave.fieldValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isUndefinedOrNull(existingField)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
isDeeplyEqual(
|
||||||
|
{
|
||||||
|
position: existingField.position,
|
||||||
|
isVisible: existingField.isVisible,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
position: viewGroupToSave.position,
|
||||||
|
isVisible: viewGroupToSave.isVisible,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateViewGroupRecords([
|
||||||
|
{ ...viewGroupToSave, id: existingField.id },
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
[currentViewIdCallbackState, getViewFromCache, updateViewGroupRecords],
|
||||||
|
);
|
||||||
|
|
||||||
const saveViewGroups = useRecoilCallback(
|
const saveViewGroups = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
async (viewGroupsToSave: ViewGroup[]) => {
|
async (viewGroupsToSave: ViewGroup[]) => {
|
||||||
@ -91,6 +141,7 @@ export const useSaveCurrentViewGroups = (viewBarComponentId?: string) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
saveViewGroup,
|
||||||
saveViewGroups,
|
saveViewGroups,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,17 +1,9 @@
|
|||||||
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
import { ViewGroup } from '@/views/types/ViewGroup';
|
import { ViewGroup } from '@/views/types/ViewGroup';
|
||||||
|
import { recordGroupDefinitionToViewGroup } from '@/views/utils/recordGroupDefinitionToViewGroup';
|
||||||
|
|
||||||
export const mapRecordGroupDefinitionsToViewGroups = (
|
export const mapRecordGroupDefinitionsToViewGroups = (
|
||||||
groupDefinitions: RecordGroupDefinition[],
|
groupDefinitions: RecordGroupDefinition[],
|
||||||
): ViewGroup[] => {
|
): ViewGroup[] => {
|
||||||
return groupDefinitions.map(
|
return groupDefinitions.map(recordGroupDefinitionToViewGroup);
|
||||||
(groupDefinition): ViewGroup => ({
|
|
||||||
__typename: 'ViewGroup',
|
|
||||||
id: groupDefinition.id,
|
|
||||||
fieldMetadataId: groupDefinition.fieldMetadataId,
|
|
||||||
position: groupDefinition.position,
|
|
||||||
isVisible: groupDefinition.isVisible ?? true,
|
|
||||||
fieldValue: groupDefinition.value ?? '',
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { v4 } from 'uuid';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
@ -42,16 +43,7 @@ export const mapViewGroupsToRecordGroupDefinitions = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!selectedOption) {
|
if (!selectedOption) {
|
||||||
return {
|
return null;
|
||||||
id: 'no-value',
|
|
||||||
title: 'No Value',
|
|
||||||
type: RecordGroupDefinitionType.NoValue,
|
|
||||||
value: null,
|
|
||||||
position: viewGroup.position,
|
|
||||||
isVisible: viewGroup.isVisible,
|
|
||||||
fieldMetadataId: selectFieldMetadataItem.id,
|
|
||||||
color: 'transparent',
|
|
||||||
} satisfies RecordGroupDefinition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -65,8 +57,32 @@ export const mapViewGroupsToRecordGroupDefinitions = ({
|
|||||||
isVisible: viewGroup.isVisible,
|
isVisible: viewGroup.isVisible,
|
||||||
} as RecordGroupDefinition;
|
} as RecordGroupDefinition;
|
||||||
})
|
})
|
||||||
.filter(isDefined)
|
.filter(isDefined);
|
||||||
.sort((a, b) => a.position - b.position);
|
|
||||||
|
|
||||||
return recordGroupDefinitionsFromViewGroups;
|
if (selectFieldMetadataItem.isNullable === true) {
|
||||||
|
const viewGroup = viewGroups.find(
|
||||||
|
(viewGroup) => viewGroup.fieldValue === '',
|
||||||
|
);
|
||||||
|
|
||||||
|
const noValueColumn = {
|
||||||
|
id: viewGroup?.id ?? v4(),
|
||||||
|
title: 'No Value',
|
||||||
|
type: RecordGroupDefinitionType.NoValue,
|
||||||
|
value: null,
|
||||||
|
position:
|
||||||
|
viewGroup?.position ??
|
||||||
|
recordGroupDefinitionsFromViewGroups
|
||||||
|
.map((option) => option.position)
|
||||||
|
.reduce((a, b) => Math.max(a, b), 0) + 1,
|
||||||
|
isVisible: viewGroup?.isVisible ?? true,
|
||||||
|
fieldMetadataId: selectFieldMetadataItem.id,
|
||||||
|
color: 'transparent',
|
||||||
|
} satisfies RecordGroupDefinition;
|
||||||
|
|
||||||
|
return [...recordGroupDefinitionsFromViewGroups, noValueColumn];
|
||||||
|
}
|
||||||
|
|
||||||
|
return recordGroupDefinitionsFromViewGroups.sort(
|
||||||
|
(a, b) => a.position - b.position,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { RecordGroupDefinition } from '@/object-record/record-group/types/RecordGroupDefinition';
|
||||||
|
import { ViewGroup } from '@/views/types/ViewGroup';
|
||||||
|
|
||||||
|
export const recordGroupDefinitionToViewGroup = (
|
||||||
|
recordGroup: RecordGroupDefinition,
|
||||||
|
): ViewGroup => {
|
||||||
|
return {
|
||||||
|
__typename: 'ViewGroup',
|
||||||
|
id: recordGroup.id,
|
||||||
|
fieldMetadataId: recordGroup.fieldMetadataId,
|
||||||
|
position: recordGroup.position,
|
||||||
|
isVisible: recordGroup.isVisible ?? true,
|
||||||
|
fieldValue: recordGroup.value ?? '',
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user