Remap items in board (#3643)
* Remap items in board * Fix according to review
This commit is contained in:
@ -3,7 +3,7 @@ import styled from '@emotion/styled';
|
|||||||
import { DragDropContext } 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 } 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 { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
||||||
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 { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||||
@ -40,7 +40,7 @@ const StyledBoardHeader = styled.div`
|
|||||||
export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
||||||
const boardRef = useRef<HTMLDivElement>(null);
|
const boardRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const { getColumnIdsState } = useRecordBoard(recordBoardId);
|
const { getColumnIdsState } = useRecordBoardStates(recordBoardId);
|
||||||
|
|
||||||
const columnIds = useRecoilValue(getColumnIdsState());
|
const columnIds = useRecoilValue(getColumnIdsState());
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,11 @@ import { RecordBoardScopeInternalContext } from '@/object-record/record-board/sc
|
|||||||
import { isFirstRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isFirstRecordBoardColumnFamilyStateScopeMap';
|
import { isFirstRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isFirstRecordBoardColumnFamilyStateScopeMap';
|
||||||
import { isLastRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isLastRecordBoardColumnFamilyStateScopeMap';
|
import { isLastRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isLastRecordBoardColumnFamilyStateScopeMap';
|
||||||
import { recordBoardColumnIdsStateScopeMap } from '@/object-record/record-board/states/recordBoardColumnIdsStateScopeMap';
|
import { recordBoardColumnIdsStateScopeMap } from '@/object-record/record-board/states/recordBoardColumnIdsStateScopeMap';
|
||||||
|
import { recordBoardFieldDefinitionsStateScopeMap } from '@/object-record/record-board/states/recordBoardFieldDefinitionsStateScopeMap';
|
||||||
|
import { recordBoardFiltersStateScopeMap } from '@/object-record/record-board/states/recordBoardFiltersStateScopeMap';
|
||||||
|
import { recordBoardObjectMetadataSingularNameStateScopeMap } from '@/object-record/record-board/states/recordBoardObjectMetadataSingularNameStateScopeMap';
|
||||||
|
import { recordBoardRecordIdsByColumnIdFamilyStateScopeMap } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdFamilyStateScopeMap';
|
||||||
|
import { recordBoardSortsStateScopeMap } from '@/object-record/record-board/states/recordBoardSortsStateScopeMap';
|
||||||
import { recordBoardColumnsFamilySelectorScopeMap } from '@/object-record/record-board/states/selectors/recordBoardColumnsFamilySelectorScopeMap';
|
import { recordBoardColumnsFamilySelectorScopeMap } from '@/object-record/record-board/states/selectors/recordBoardColumnsFamilySelectorScopeMap';
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
import { getFamilyState } from '@/ui/utilities/recoil-scope/utils/getFamilyState';
|
import { getFamilyState } from '@/ui/utilities/recoil-scope/utils/getFamilyState';
|
||||||
@ -16,6 +21,10 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
scopeId,
|
scopeId,
|
||||||
|
getObjectMetadataSingularNameState: getState(
|
||||||
|
recordBoardObjectMetadataSingularNameStateScopeMap,
|
||||||
|
scopeId,
|
||||||
|
),
|
||||||
getColumnIdsState: getState(recordBoardColumnIdsStateScopeMap, scopeId),
|
getColumnIdsState: getState(recordBoardColumnIdsStateScopeMap, scopeId),
|
||||||
isFirstColumnFamilyState: getFamilyState(
|
isFirstColumnFamilyState: getFamilyState(
|
||||||
isFirstRecordBoardColumnFamilyStateScopeMap,
|
isFirstRecordBoardColumnFamilyStateScopeMap,
|
||||||
@ -29,5 +38,17 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
|
|||||||
recordBoardColumnsFamilySelectorScopeMap,
|
recordBoardColumnsFamilySelectorScopeMap,
|
||||||
scopeId,
|
scopeId,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
getFiltersState: getState(recordBoardFiltersStateScopeMap, scopeId),
|
||||||
|
getSortsState: getState(recordBoardSortsStateScopeMap, scopeId),
|
||||||
|
getFieldDefinitionsState: getState(
|
||||||
|
recordBoardFieldDefinitionsStateScopeMap,
|
||||||
|
scopeId,
|
||||||
|
),
|
||||||
|
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyState: getFamilyState(
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyStateScopeMap,
|
||||||
|
scopeId,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => {
|
|||||||
const { scopeId, getColumnIdsState, columnsFamilySelector } =
|
const { scopeId, getColumnIdsState, columnsFamilySelector } =
|
||||||
useRecordBoardStates(recordBoardId);
|
useRecordBoardStates(recordBoardId);
|
||||||
|
|
||||||
const setRecordBoardColumns = useRecoilCallback(
|
const setColumns = useRecoilCallback(
|
||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
(columns: RecordBoardColumnDefinition[]) => {
|
(columns: RecordBoardColumnDefinition[]) => {
|
||||||
const currentColumnsIds = snapshot
|
const currentColumnsIds = snapshot
|
||||||
@ -43,6 +43,6 @@ export const useSetRecordBoardColumns = (recordBoardId?: string) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
scopeId,
|
scopeId,
|
||||||
setRecordBoardColumns,
|
setColumns,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,44 @@
|
|||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
|
||||||
|
export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
|
||||||
|
const {
|
||||||
|
scopeId,
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyState,
|
||||||
|
columnsFamilySelector,
|
||||||
|
getColumnIdsState,
|
||||||
|
} = useRecordBoardStates(recordBoardId);
|
||||||
|
|
||||||
|
const setRecordIds = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
(records: ObjectRecord[]) => {
|
||||||
|
const columnIds = snapshot.getLoadable(getColumnIdsState()).getValue();
|
||||||
|
|
||||||
|
columnIds.forEach((columnId) => {
|
||||||
|
const column = snapshot
|
||||||
|
.getLoadable(columnsFamilySelector(columnId))
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
const columnRecordIds = records
|
||||||
|
.filter((record) => record.stage === column?.value)
|
||||||
|
.map((record) => record.id);
|
||||||
|
set(
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyState(columnId),
|
||||||
|
columnRecordIds,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[
|
||||||
|
columnsFamilySelector,
|
||||||
|
getColumnIdsState,
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyState,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
scopeId,
|
||||||
|
setRecordIds,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,16 +1,21 @@
|
|||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
||||||
import { useSetRecordBoardColumns } from '@/object-record/record-board/hooks/internal/useSetRecordBoardColumns';
|
import { useSetRecordBoardColumns } from '@/object-record/record-board/hooks/internal/useSetRecordBoardColumns';
|
||||||
|
import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds';
|
||||||
|
|
||||||
export const useRecordBoard = (recordBoardId?: string) => {
|
export const useRecordBoard = (recordBoardId?: string) => {
|
||||||
const { scopeId, getColumnIdsState, columnsFamilySelector } =
|
const { scopeId, getFieldDefinitionsState } =
|
||||||
useRecordBoardStates(recordBoardId);
|
useRecordBoardStates(recordBoardId);
|
||||||
|
|
||||||
const { setRecordBoardColumns } = useSetRecordBoardColumns(recordBoardId);
|
const { setColumns } = useSetRecordBoardColumns(recordBoardId);
|
||||||
|
const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId);
|
||||||
|
const setFieldDefinitions = useSetRecoilState(getFieldDefinitionsState());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scopeId,
|
scopeId,
|
||||||
getColumnIdsState,
|
setColumns,
|
||||||
columnsFamilySelector,
|
setRecordIds,
|
||||||
setRecordBoardColumns,
|
setFieldDefinitions,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -33,6 +33,7 @@ export const RecordBoardColumn = ({
|
|||||||
isFirstColumnFamilyState,
|
isFirstColumnFamilyState,
|
||||||
isLastColumnFamilyState,
|
isLastColumnFamilyState,
|
||||||
columnsFamilySelector,
|
columnsFamilySelector,
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyState,
|
||||||
} = useRecordBoardStates();
|
} = useRecordBoardStates();
|
||||||
const columnDefinition = useRecoilValue(
|
const columnDefinition = useRecoilValue(
|
||||||
columnsFamilySelector(recordBoardColumnId),
|
columnsFamilySelector(recordBoardColumnId),
|
||||||
@ -46,7 +47,11 @@ export const RecordBoardColumn = ({
|
|||||||
isLastColumnFamilyState(recordBoardColumnId),
|
isLastColumnFamilyState(recordBoardColumnId),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!columnDefinition) {
|
const recordIds = useRecoilValue(
|
||||||
|
recordBoardRecordIdsByColumnIdFamilyState(recordBoardColumnId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!columnDefinition || !recordIds) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,11 +70,10 @@ export const RecordBoardColumn = ({
|
|||||||
<RecordBoardColumnCardsContainer
|
<RecordBoardColumnCardsContainer
|
||||||
droppableProvided={droppableProvided}
|
droppableProvided={droppableProvided}
|
||||||
>
|
>
|
||||||
{[].map((cardId, _index) => (
|
{recordIds.map((recordId) => (
|
||||||
<BoardCardIdContext.Provider
|
<BoardCardIdContext.Provider value={recordId} key={recordId}>
|
||||||
value={cardId}
|
<div>Card</div>
|
||||||
key={cardId}
|
</BoardCardIdContext.Provider>
|
||||||
></BoardCardIdContext.Provider>
|
|
||||||
))}
|
))}
|
||||||
</RecordBoardColumnCardsContainer>
|
</RecordBoardColumnCardsContainer>
|
||||||
</StyledColumn>
|
</StyledColumn>
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
|
||||||
|
import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition';
|
||||||
|
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||||
|
|
||||||
|
export const recordBoardFieldDefinitionsStateScopeMap = createStateScopeMap<
|
||||||
|
RecordBoardFieldDefinition<FieldMetadata>[]
|
||||||
|
>({
|
||||||
|
key: 'recordBoardFieldDefinitionsStateScopeMap',
|
||||||
|
defaultValue: [],
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
||||||
|
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||||
|
|
||||||
|
export const recordBoardFiltersStateScopeMap = createStateScopeMap<Filter[]>({
|
||||||
|
key: 'recordBoardFiltersStateScopeMap',
|
||||||
|
defaultValue: [],
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||||
|
|
||||||
|
export const recordBoardObjectMetadataSingularNameStateScopeMap =
|
||||||
|
createStateScopeMap<string | undefined>({
|
||||||
|
key: 'recordBoardObjectMetadataSingularNameStateScopeMap',
|
||||||
|
defaultValue: undefined,
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||||
|
|
||||||
|
export const recordBoardRecordIdsByColumnIdFamilyStateScopeMap =
|
||||||
|
createFamilyStateScopeMap<string[], string>({
|
||||||
|
key: 'recordBoardRecordIdsByColumnIdFamilyStateScopeMap',
|
||||||
|
defaultValue: [],
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
|
||||||
|
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||||
|
|
||||||
|
export const recordBoardSortsStateScopeMap = createStateScopeMap<Sort[]>({
|
||||||
|
key: 'recordBoardSortsStateScopeMap',
|
||||||
|
defaultValue: [],
|
||||||
|
});
|
||||||
@ -4,6 +4,7 @@ import { ThemeColor } from '@/ui/theme/constants/colors';
|
|||||||
export type RecordBoardColumnDefinition = {
|
export type RecordBoardColumnDefinition = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
|
value: string;
|
||||||
position: number;
|
position: number;
|
||||||
color: ThemeColor;
|
color: ThemeColor;
|
||||||
actions: RecordBoardColumnAction[];
|
actions: RecordBoardColumnAction[];
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
|
||||||
|
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
|
||||||
|
|
||||||
|
export type RecordBoardFieldDefinition<T extends FieldMetadata> =
|
||||||
|
FieldDefinition<T> & {
|
||||||
|
viewFieldId?: string;
|
||||||
|
position: number;
|
||||||
|
isVisible?: boolean;
|
||||||
|
};
|
||||||
@ -3,12 +3,12 @@ import { RecordBoard } from '@/object-record/record-board/components/RecordBoard
|
|||||||
type RecordIndexBoardContainerProps = {
|
type RecordIndexBoardContainerProps = {
|
||||||
recordBoardId: string;
|
recordBoardId: string;
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
objectNamePlural: string;
|
objectNameSingular: string;
|
||||||
createRecord: () => Promise<void>;
|
createRecord: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexBoardContainer = ({
|
export const RecordIndexBoardContainer = ({
|
||||||
recordBoardId,
|
recordBoardId,
|
||||||
}: RecordIndexBoardContainerProps) => {
|
}: RecordIndexBoardContainerProps) => {
|
||||||
return <RecordBoard recordBoardId={recordBoardId}></RecordBoard>;
|
return <RecordBoard recordBoardId={recordBoardId} />;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,38 +2,36 @@ import { useCallback, useEffect } from 'react';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
|
||||||
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
||||||
|
import { useLoadRecordIndexBoard } from '@/object-record/record-index/hooks/useLoadRecordIndexBoard';
|
||||||
import { computeRecordBoardColumnDefinitionsFromObjectMetadata } from '@/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata';
|
import { computeRecordBoardColumnDefinitionsFromObjectMetadata } from '@/object-record/utils/computeRecordBoardColumnDefinitionsFromObjectMetadata';
|
||||||
|
|
||||||
type RecordIndexBoardContainerEffectProps = {
|
type RecordIndexBoardContainerEffectProps = {
|
||||||
objectNamePlural: string;
|
objectNameSingular: string;
|
||||||
recordBoardId: string;
|
recordBoardId: string;
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexBoardContainerEffect = ({
|
export const RecordIndexBoardContainerEffect = ({
|
||||||
objectNamePlural,
|
objectNameSingular,
|
||||||
recordBoardId,
|
recordBoardId,
|
||||||
}: RecordIndexBoardContainerEffectProps) => {
|
}: RecordIndexBoardContainerEffectProps) => {
|
||||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
|
||||||
objectNamePlural,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useLoadRecordIndexBoard(objectNameSingular, recordBoardId);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const navigateToSelectSettings = useCallback(() => {
|
const navigateToSelectSettings = useCallback(() => {
|
||||||
navigate(`/settings/objects/${objectNamePlural}`);
|
navigate(`/settings/objects/${objectMetadataItem.namePlural}`);
|
||||||
}, [navigate, objectNamePlural]);
|
}, [navigate, objectMetadataItem.namePlural]);
|
||||||
|
|
||||||
const { setRecordBoardColumns } = useRecordBoard(recordBoardId);
|
const { setColumns } = useRecordBoard(recordBoardId);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRecordBoardColumns(
|
setColumns(
|
||||||
computeRecordBoardColumnDefinitionsFromObjectMetadata(
|
computeRecordBoardColumnDefinitionsFromObjectMetadata(
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
navigateToSelectSettings,
|
navigateToSelectSettings,
|
||||||
@ -43,7 +41,7 @@ export const RecordIndexBoardContainerEffect = ({
|
|||||||
navigateToSelectSettings,
|
navigateToSelectSettings,
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
setRecordBoardColumns,
|
setColumns,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
|
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
|
||||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||||
@ -10,6 +11,9 @@ import { RecordIndexBoardContainerEffect } from '@/object-record/record-index/co
|
|||||||
import { RecordIndexTableContainer } from '@/object-record/record-index/components/RecordIndexTableContainer';
|
import { RecordIndexTableContainer } from '@/object-record/record-index/components/RecordIndexTableContainer';
|
||||||
import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect';
|
import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect';
|
||||||
import { RecordIndexViewBarEffect } from '@/object-record/record-index/components/RecordIndexViewBarEffect';
|
import { RecordIndexViewBarEffect } from '@/object-record/record-index/components/RecordIndexViewBarEffect';
|
||||||
|
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
||||||
|
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
||||||
|
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
|
||||||
import { TableOptionsDropdownId } from '@/object-record/record-table/constants/TableOptionsDropdownId';
|
import { TableOptionsDropdownId } from '@/object-record/record-table/constants/TableOptionsDropdownId';
|
||||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||||
import { TableOptionsDropdown } from '@/object-record/record-table/options/components/TableOptionsDropdown';
|
import { TableOptionsDropdown } from '@/object-record/record-table/options/components/TableOptionsDropdown';
|
||||||
@ -56,6 +60,12 @@ export const RecordIndexContainer = ({
|
|||||||
const { columnDefinitions } =
|
const { columnDefinitions } =
|
||||||
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
useColumnDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||||
|
|
||||||
|
const setRecordIndexFieldDefinitions = useSetRecoilState(
|
||||||
|
recordIndexFieldDefinitionsState,
|
||||||
|
);
|
||||||
|
const setRecordIndexFilters = useSetRecoilState(recordIndexFiltersState);
|
||||||
|
const setRecordIndexSorts = useSetRecoilState(recordIndexSortsState);
|
||||||
|
|
||||||
const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport();
|
const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport();
|
||||||
const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
|
const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
|
||||||
|
|
||||||
@ -91,12 +101,17 @@ export const RecordIndexContainer = ({
|
|||||||
setTableColumns(
|
setTableColumns(
|
||||||
mapViewFieldsToColumnDefinitions(viewFields, columnDefinitions),
|
mapViewFieldsToColumnDefinitions(viewFields, columnDefinitions),
|
||||||
);
|
);
|
||||||
|
setRecordIndexFieldDefinitions(
|
||||||
|
mapViewFieldsToColumnDefinitions(viewFields, columnDefinitions),
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
onViewFiltersChange={(viewFilters) => {
|
onViewFiltersChange={(viewFilters) => {
|
||||||
setTableFilters(mapViewFiltersToFilters(viewFilters));
|
setTableFilters(mapViewFiltersToFilters(viewFilters));
|
||||||
|
setRecordIndexFilters(mapViewFiltersToFilters(viewFilters));
|
||||||
}}
|
}}
|
||||||
onViewSortsChange={(viewSorts) => {
|
onViewSortsChange={(viewSorts) => {
|
||||||
setTableSorts(mapViewSortsToSorts(viewSorts));
|
setTableSorts(mapViewSortsToSorts(viewSorts));
|
||||||
|
setRecordIndexSorts(mapViewSortsToSorts(viewSorts));
|
||||||
}}
|
}}
|
||||||
onViewTypeChange={(viewType: ViewType) => {
|
onViewTypeChange={(viewType: ViewType) => {
|
||||||
setRecordIndexViewType(viewType);
|
setRecordIndexViewType(viewType);
|
||||||
@ -112,11 +127,11 @@ export const RecordIndexContainer = ({
|
|||||||
<RecordIndexTableContainer
|
<RecordIndexTableContainer
|
||||||
recordTableId={recordIndexId}
|
recordTableId={recordIndexId}
|
||||||
viewBarId={recordIndexId}
|
viewBarId={recordIndexId}
|
||||||
objectNamePlural={objectNamePlural}
|
objectNameSingular={objectNameSingular}
|
||||||
createRecord={createRecord}
|
createRecord={createRecord}
|
||||||
/>
|
/>
|
||||||
<RecordIndexTableContainerEffect
|
<RecordIndexTableContainerEffect
|
||||||
objectNamePlural={objectNamePlural}
|
objectNameSingular={objectNameSingular}
|
||||||
recordTableId={recordIndexId}
|
recordTableId={recordIndexId}
|
||||||
viewBarId={recordIndexId}
|
viewBarId={recordIndexId}
|
||||||
/>
|
/>
|
||||||
@ -127,11 +142,11 @@ export const RecordIndexContainer = ({
|
|||||||
<RecordIndexBoardContainer
|
<RecordIndexBoardContainer
|
||||||
recordBoardId={recordIndexId}
|
recordBoardId={recordIndexId}
|
||||||
viewBarId={recordIndexId}
|
viewBarId={recordIndexId}
|
||||||
objectNamePlural={objectNamePlural}
|
objectNameSingular={objectNameSingular}
|
||||||
createRecord={createRecord}
|
createRecord={createRecord}
|
||||||
/>
|
/>
|
||||||
<RecordIndexBoardContainerEffect
|
<RecordIndexBoardContainerEffect
|
||||||
objectNamePlural={objectNamePlural}
|
objectNameSingular={objectNameSingular}
|
||||||
recordBoardId={recordIndexId}
|
recordBoardId={recordIndexId}
|
||||||
viewBarId={recordIndexId}
|
viewBarId={recordIndexId}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { RecordUpdateHookParams } from '@/object-record/field/contexts/FieldContext';
|
import { RecordUpdateHookParams } from '@/object-record/field/contexts/FieldContext';
|
||||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar';
|
import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar';
|
||||||
@ -8,18 +8,18 @@ import { RecordTableContextMenu } from '@/object-record/record-table/context-men
|
|||||||
type RecordIndexTableContainerProps = {
|
type RecordIndexTableContainerProps = {
|
||||||
recordTableId: string;
|
recordTableId: string;
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
objectNamePlural: string;
|
objectNameSingular: string;
|
||||||
createRecord: () => Promise<void>;
|
createRecord: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexTableContainer = ({
|
export const RecordIndexTableContainer = ({
|
||||||
recordTableId,
|
recordTableId,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
objectNamePlural,
|
objectNameSingular,
|
||||||
createRecord,
|
createRecord,
|
||||||
}: RecordIndexTableContainerProps) => {
|
}: RecordIndexTableContainerProps) => {
|
||||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNamePlural,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { updateOneRecord } = useUpdateOneRecord({
|
const { updateOneRecord } = useUpdateOneRecord({
|
||||||
@ -37,7 +37,7 @@ export const RecordIndexTableContainer = ({
|
|||||||
<>
|
<>
|
||||||
<RecordTableWithWrappers
|
<RecordTableWithWrappers
|
||||||
recordTableId={recordTableId}
|
recordTableId={recordTableId}
|
||||||
objectNamePlural={objectNamePlural}
|
objectNamePlural={objectMetadataItem.namePlural}
|
||||||
viewBarId={viewBarId}
|
viewBarId={viewBarId}
|
||||||
updateRecordMutation={updateEntity}
|
updateRecordMutation={updateEntity}
|
||||||
createRecord={createRecord}
|
createRecord={createRecord}
|
||||||
|
|||||||
@ -2,20 +2,19 @@ import { useEffect } from 'react';
|
|||||||
|
|
||||||
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 { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
|
||||||
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
||||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
type RecordIndexTableContainerEffectProps = {
|
type RecordIndexTableContainerEffectProps = {
|
||||||
objectNamePlural: string;
|
objectNameSingular: string;
|
||||||
recordTableId: string;
|
recordTableId: string;
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexTableContainerEffect = ({
|
export const RecordIndexTableContainerEffect = ({
|
||||||
objectNamePlural,
|
objectNameSingular,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
}: RecordIndexTableContainerEffectProps) => {
|
}: RecordIndexTableContainerEffectProps) => {
|
||||||
@ -25,10 +24,6 @@ export const RecordIndexTableContainerEffect = ({
|
|||||||
setObjectMetadataConfig,
|
setObjectMetadataConfig,
|
||||||
} = useRecordTable({ recordTableId });
|
} = useRecordTable({ recordTableId });
|
||||||
|
|
||||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
|
||||||
objectNamePlural,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
basePathToShowPage,
|
basePathToShowPage,
|
||||||
@ -74,7 +69,7 @@ export const RecordIndexTableContainerEffect = ({
|
|||||||
|
|
||||||
const { setActionBarEntries, setContextMenuEntries } =
|
const { setActionBarEntries, setContextMenuEntries } =
|
||||||
useRecordTableContextMenuEntries({
|
useRecordTableContextMenuEntries({
|
||||||
objectNamePlural,
|
objectNamePlural: objectMetadataItem.namePlural,
|
||||||
recordTableId,
|
recordTableId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,64 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
|
import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy';
|
||||||
|
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
||||||
|
import { turnObjectDropdownFilterIntoQueryFilter } from '@/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter';
|
||||||
|
import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState';
|
||||||
|
import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState';
|
||||||
|
import { recordIndexSortsState } from '@/object-record/record-index/states/recordIndexSortsState';
|
||||||
|
import { useSetRecordInStore } from '@/object-record/record-store/hooks/useSetRecordInStore';
|
||||||
|
|
||||||
|
export const useLoadRecordIndexBoard = (
|
||||||
|
objectNameSingular: string,
|
||||||
|
recordBoardId: string,
|
||||||
|
) => {
|
||||||
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
|
objectNameSingular,
|
||||||
|
});
|
||||||
|
const { setRecordIds: setRecordIdsInBoard, setFieldDefinitions } =
|
||||||
|
useRecordBoard(recordBoardId);
|
||||||
|
const { setRecords: setRecordsInStore } = useSetRecordInStore();
|
||||||
|
|
||||||
|
const recordIndexFieldDefinitions = useRecoilValue(
|
||||||
|
recordIndexFieldDefinitionsState,
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
setFieldDefinitions(recordIndexFieldDefinitions);
|
||||||
|
}, [recordIndexFieldDefinitions, setFieldDefinitions]);
|
||||||
|
|
||||||
|
const recordIndexFilters = useRecoilValue(recordIndexFiltersState);
|
||||||
|
const recordIndexSorts = useRecoilValue(recordIndexSortsState);
|
||||||
|
const requestFilters = turnObjectDropdownFilterIntoQueryFilter(
|
||||||
|
recordIndexFilters,
|
||||||
|
objectMetadataItem?.fields ?? [],
|
||||||
|
);
|
||||||
|
const orderBy = turnSortsIntoOrderBy(
|
||||||
|
recordIndexSorts,
|
||||||
|
objectMetadataItem?.fields ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
const { records, loading, fetchMoreRecords, queryStateIdentifier } =
|
||||||
|
useFindManyRecords({
|
||||||
|
objectNameSingular,
|
||||||
|
filter: requestFilters,
|
||||||
|
orderBy,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setRecordIdsInBoard(records);
|
||||||
|
}, [records, setRecordIdsInBoard]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setRecordsInStore(records);
|
||||||
|
}, [records, setRecordsInStore]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
records,
|
||||||
|
loading,
|
||||||
|
fetchMoreRecords,
|
||||||
|
queryStateIdentifier,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
|
||||||
|
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||||
|
|
||||||
|
export const recordIndexFieldDefinitionsState = atom<
|
||||||
|
ColumnDefinition<FieldMetadata>[]
|
||||||
|
>({
|
||||||
|
key: 'recordIndexFieldDefinitionsState',
|
||||||
|
default: [],
|
||||||
|
});
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
||||||
|
|
||||||
|
export const recordIndexFiltersState = atom<Filter[]>({
|
||||||
|
key: 'recordIndexFiltersState',
|
||||||
|
default: [],
|
||||||
|
});
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
|
||||||
|
|
||||||
|
export const recordIndexSortsState = atom<Sort[]>({
|
||||||
|
key: 'recordIndexSortsState',
|
||||||
|
default: [],
|
||||||
|
});
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
|
||||||
|
export const useSetRecordInStore = () => {
|
||||||
|
const setRecords = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
(records: ObjectRecord[]) => {
|
||||||
|
records.forEach((record) => {
|
||||||
|
const currentRecord = snapshot
|
||||||
|
.getLoadable(recordStoreFamilyState(record.id))
|
||||||
|
.valueOrThrow();
|
||||||
|
|
||||||
|
if (JSON.stringify(currentRecord) !== JSON.stringify(record)) {
|
||||||
|
set(recordStoreFamilyState(record.id), record);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
setRecords,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { atomFamily } from 'recoil';
|
||||||
|
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
|
||||||
|
export const recordStoreFamilyState = atomFamily<ObjectRecord | null, string>({
|
||||||
|
key: 'recordStoreFamilyState',
|
||||||
|
default: null,
|
||||||
|
});
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { selectorFamily } from 'recoil';
|
||||||
|
|
||||||
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
|
|
||||||
|
export const recordStoreFamilySelector = selectorFamily({
|
||||||
|
key: 'recordStoreFamilySelector',
|
||||||
|
get:
|
||||||
|
<T>({ fieldName, recordId }: { fieldName: string; recordId: string }) =>
|
||||||
|
({ get }) =>
|
||||||
|
get(recordStoreFamilyState(recordId))?.[fieldName] as T,
|
||||||
|
set:
|
||||||
|
<T>({ fieldName, recordId }: { fieldName: string; recordId: string }) =>
|
||||||
|
({ set }, newValue: T) =>
|
||||||
|
set(recordStoreFamilyState(recordId), (prevState) =>
|
||||||
|
prevState ? { ...prevState, [fieldName]: newValue } : null,
|
||||||
|
),
|
||||||
|
});
|
||||||
@ -24,6 +24,7 @@ export const computeRecordBoardColumnDefinitionsFromObjectMetadata = (
|
|||||||
return selectFieldMetadataItem.options.map((selectOption) => ({
|
return selectFieldMetadataItem.options.map((selectOption) => ({
|
||||||
id: selectOption.id,
|
id: selectOption.id,
|
||||||
title: selectOption.label,
|
title: selectOption.label,
|
||||||
|
value: selectOption.value,
|
||||||
color: selectOption.color,
|
color: selectOption.color,
|
||||||
position: selectOption.position,
|
position: selectOption.position,
|
||||||
actions: [
|
actions: [
|
||||||
|
|||||||
Reference in New Issue
Block a user