Allow Card field update and card drag on new record board (#3661)
This commit is contained in:
@ -1,14 +1,14 @@
|
|||||||
import { getActivitySummary } from '../getActivitySummary';
|
import { getActivitySummary } from '../getActivitySummary';
|
||||||
|
|
||||||
describe('getActivitySummary', () => {
|
describe('getActivitySummary', () => {
|
||||||
it('should work for empty body', () => {
|
it('should work for empty body ""', () => {
|
||||||
const activityBody = {};
|
const activityBody = {};
|
||||||
|
|
||||||
const res = getActivitySummary(JSON.stringify(activityBody));
|
const res = getActivitySummary(JSON.stringify(activityBody));
|
||||||
|
|
||||||
expect(res).toEqual('');
|
expect(res).toEqual('');
|
||||||
});
|
});
|
||||||
it('should work for empty body', () => {
|
it('should work for empty body {}', () => {
|
||||||
const activityBody = '';
|
const activityBody = '';
|
||||||
|
|
||||||
const res = getActivitySummary(JSON.stringify(activityBody));
|
const res = getActivitySummary(JSON.stringify(activityBody));
|
||||||
@ -109,4 +109,34 @@ describe('getActivitySummary', () => {
|
|||||||
|
|
||||||
expect(res).toEqual('');
|
expect(res).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work for table as first block', () => {
|
||||||
|
const activityBody = [
|
||||||
|
{
|
||||||
|
id: '591c3aa1-9e51-465d-bb59-611ef60344fb',
|
||||||
|
type: 'table',
|
||||||
|
props: { textColor: 'default', backgroundColor: 'default' },
|
||||||
|
content: {
|
||||||
|
type: 'tableContent',
|
||||||
|
rows: [{ cells: [[], [], []] }, { cells: [[], [], []] }],
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1899ab29-0122-4890-bb50-4d7cf2802f98',
|
||||||
|
type: 'paragraph',
|
||||||
|
props: {
|
||||||
|
textColor: 'default',
|
||||||
|
backgroundColor: 'default',
|
||||||
|
textAlignment: 'left',
|
||||||
|
},
|
||||||
|
content: [],
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const res = getActivitySummary(JSON.stringify(activityBody));
|
||||||
|
|
||||||
|
expect(res).toEqual('');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,9 +1,25 @@
|
|||||||
|
import { isArray } from '@sniptt/guards';
|
||||||
|
|
||||||
export const getActivitySummary = (activityBody: string) => {
|
export const getActivitySummary = (activityBody: string) => {
|
||||||
const noteBody = activityBody ? JSON.parse(activityBody) : [];
|
const noteBody = activityBody ? JSON.parse(activityBody) : [];
|
||||||
|
|
||||||
return (
|
if (!noteBody.length) {
|
||||||
noteBody[0]?.content?.text ||
|
return '';
|
||||||
noteBody[0]?.content?.map((content: any) => content?.text).join(' ') ||
|
}
|
||||||
''
|
|
||||||
);
|
const firstNoteBlockContent = noteBody[0].content;
|
||||||
|
|
||||||
|
if (!firstNoteBlockContent) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstNoteBlockContent.text) {
|
||||||
|
return noteBody[0].content.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isArray(firstNoteBlockContent)) {
|
||||||
|
return firstNoteBlockContent.map((content: any) => content.text).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
import { useRef } from 'react';
|
import { useContext, useRef } from 'react';
|
||||||
import styled from '@emotion/styled';
|
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, 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 { useRecoilValue } from 'recoil';
|
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
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';
|
||||||
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 { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
export type RecordBoardProps = {
|
export type RecordBoardProps = {
|
||||||
recordBoardId: string;
|
recordBoardId: string;
|
||||||
@ -38,11 +40,50 @@ const StyledBoardHeader = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
||||||
|
const { updateOneRecord, objectMetadataItem } =
|
||||||
|
useContext(RecordBoardContext);
|
||||||
const boardRef = useRef<HTMLDivElement>(null);
|
const boardRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const { getColumnIdsState } = useRecordBoardStates(recordBoardId);
|
const { getColumnIdsState, columnsFamilySelector } =
|
||||||
|
useRecordBoardStates(recordBoardId);
|
||||||
const columnIds = useRecoilValue(getColumnIdsState());
|
const columnIds = useRecoilValue(getColumnIdsState());
|
||||||
|
|
||||||
|
const selectFieldMetadataItem = objectMetadataItem.fields.find(
|
||||||
|
(field) => field.type === FieldMetadataType.Select,
|
||||||
|
);
|
||||||
|
|
||||||
|
const onDragEnd: OnDragEndResponder = useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
async (result) => {
|
||||||
|
const draggedRecordId = result.draggableId;
|
||||||
|
const destinationColumnId = result.destination?.droppableId;
|
||||||
|
|
||||||
|
if (!destinationColumnId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const column = await snapshot
|
||||||
|
.getLoadable(columnsFamilySelector(destinationColumnId))
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (!column) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectFieldMetadataItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOneRecord({
|
||||||
|
idToUpdate: draggedRecordId,
|
||||||
|
updateOneRecordInput: {
|
||||||
|
[selectFieldMetadataItem.name]: column.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[columnsFamilySelector, selectFieldMetadataItem, updateOneRecord],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RecordBoardScope
|
<RecordBoardScope
|
||||||
recordBoardScopeId={getScopeIdFromComponentId(recordBoardId)}
|
recordBoardScopeId={getScopeIdFromComponentId(recordBoardId)}
|
||||||
@ -53,7 +94,7 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
|||||||
<StyledBoardHeader />
|
<StyledBoardHeader />
|
||||||
<ScrollWrapper>
|
<ScrollWrapper>
|
||||||
<StyledContainer ref={boardRef}>
|
<StyledContainer ref={boardRef}>
|
||||||
<DragDropContext onDragEnd={() => {}}>
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
{columnIds.map((columnId) => (
|
{columnIds.map((columnId) => (
|
||||||
<RecordBoardColumn
|
<RecordBoardColumn
|
||||||
key={columnId}
|
key={columnId}
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
import { createContext } from 'react';
|
||||||
|
|
||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
|
||||||
|
type RecordBoardContextProps = {
|
||||||
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
|
createOneRecord: (recordInput: Partial<ObjectRecord>) => void;
|
||||||
|
updateOneRecord: ({
|
||||||
|
idToUpdate,
|
||||||
|
updateOneRecordInput,
|
||||||
|
}: {
|
||||||
|
idToUpdate: string;
|
||||||
|
updateOneRecordInput: Partial<Omit<ObjectRecord, 'id'>>;
|
||||||
|
}) => void;
|
||||||
|
deleteOneRecord: (idToDelete: string) => Promise<unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RecordBoardContext = createContext<RecordBoardContextProps>(
|
||||||
|
{} as RecordBoardContextProps,
|
||||||
|
);
|
||||||
@ -1,17 +1,24 @@
|
|||||||
import { ReactNode, useContext, useState } from 'react';
|
import { ReactNode, useContext, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||||
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
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 { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
|
import {
|
||||||
|
FieldContext,
|
||||||
|
RecordUpdateHook,
|
||||||
|
RecordUpdateHookParams,
|
||||||
|
} from '@/object-record/record-field/contexts/FieldContext';
|
||||||
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
||||||
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { IconEye } from '@/ui/display/icon/index';
|
import { IconEye } from '@/ui/display/icon/index';
|
||||||
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||||
import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
|
import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
|
||||||
|
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
|
||||||
|
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
|
||||||
import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut';
|
import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut';
|
||||||
|
|
||||||
const StyledBoardCard = styled.div<{ selected: boolean }>`
|
const StyledBoardCard = styled.div<{ selected: boolean }>`
|
||||||
@ -105,7 +112,7 @@ const StyledCheckboxContainer = styled.div`
|
|||||||
const StyledFieldContainer = styled.div`
|
const StyledFieldContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
width: 100%;
|
width: fit-content;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledCompactIconContainer = styled.div`
|
const StyledCompactIconContainer = styled.div`
|
||||||
@ -116,7 +123,7 @@ const StyledCompactIconContainer = styled.div`
|
|||||||
|
|
||||||
export const RecordBoardCard = () => {
|
export const RecordBoardCard = () => {
|
||||||
const { recordId } = useContext(RecordBoardCardContext);
|
const { recordId } = useContext(RecordBoardCardContext);
|
||||||
|
const { updateOneRecord } = useContext(RecordBoardContext);
|
||||||
const {
|
const {
|
||||||
getObjectSingularNameState,
|
getObjectSingularNameState,
|
||||||
getIsCompactModeActiveState,
|
getIsCompactModeActiveState,
|
||||||
@ -139,6 +146,19 @@ export const RecordBoardCard = () => {
|
|||||||
|
|
||||||
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
||||||
|
|
||||||
|
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
||||||
|
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||||
|
|
||||||
|
const handleContextMenu = (event: React.MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
setIsCurrentCardSelected(true);
|
||||||
|
setContextMenuPosition({
|
||||||
|
x: event.clientX,
|
||||||
|
y: event.clientY,
|
||||||
|
});
|
||||||
|
setContextMenuOpenState(true);
|
||||||
|
};
|
||||||
|
|
||||||
const PreventSelectOnClickContainer = ({
|
const PreventSelectOnClickContainer = ({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
@ -159,16 +179,29 @@ export const RecordBoardCard = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const useUpdateOneRecordHook: RecordUpdateHook = () => {
|
||||||
|
const updateEntity = ({ variables }: RecordUpdateHookParams) => {
|
||||||
|
updateOneRecord?.({
|
||||||
|
idToUpdate: variables.where.id as string,
|
||||||
|
updateOneRecordInput: variables.updateOneRecordInput,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return [updateEntity, { loading: false }];
|
||||||
|
};
|
||||||
|
|
||||||
if (!objectNameSingular || !record) {
|
if (!objectNameSingular || !record) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledBoardCardWrapper>
|
<StyledBoardCardWrapper onContextMenu={handleContextMenu}>
|
||||||
<StyledBoardCard
|
<StyledBoardCard
|
||||||
selected={isCurrentCardSelected}
|
selected={isCurrentCardSelected}
|
||||||
onMouseLeave={onMouseLeaveBoard}
|
onMouseLeave={onMouseLeaveBoard}
|
||||||
onClick={() => setIsCurrentCardSelected(!isCurrentCardSelected)}
|
onClick={() => {
|
||||||
|
setIsCurrentCardSelected(!isCurrentCardSelected);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
|
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
|
||||||
<RecordChip objectNameSingular={objectNameSingular} record={record} />
|
<RecordChip objectNameSingular={objectNameSingular} record={record} />
|
||||||
@ -212,6 +245,7 @@ export const RecordBoardCard = () => {
|
|||||||
type: fieldDefinition.type,
|
type: fieldDefinition.type,
|
||||||
metadata: fieldDefinition.metadata,
|
metadata: fieldDefinition.metadata,
|
||||||
},
|
},
|
||||||
|
useUpdateRecord: useUpdateOneRecordHook,
|
||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
import { Draggable } from '@hello-pangea/dnd';
|
||||||
|
|
||||||
|
import { RecordBoardCard } from '@/object-record/record-board/record-board-card/components/RecordBoardCard';
|
||||||
|
|
||||||
|
export const RecordBoardCardDraggableContainer = ({
|
||||||
|
recordId,
|
||||||
|
index,
|
||||||
|
}: {
|
||||||
|
recordId: string;
|
||||||
|
index: number;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Draggable key={recordId} draggableId={recordId} index={index}>
|
||||||
|
{(draggableProvided) => (
|
||||||
|
<div
|
||||||
|
ref={draggableProvided?.innerRef}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...draggableProvided?.dragHandleProps}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...draggableProvided?.draggableProps}
|
||||||
|
className="entity-board-card"
|
||||||
|
data-selectable-id={recordId}
|
||||||
|
data-select-disable
|
||||||
|
>
|
||||||
|
<RecordBoardCard />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -3,8 +3,6 @@ import { Droppable } from '@hello-pangea/dnd';
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
||||||
import { RecordBoardCard } from '@/object-record/record-board/record-board-card/components/RecordBoardCard';
|
|
||||||
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
|
||||||
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 { 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';
|
||||||
@ -52,7 +50,7 @@ export const RecordBoardColumn = ({
|
|||||||
recordBoardRecordIdsByColumnIdFamilyState(recordBoardColumnId),
|
recordBoardRecordIdsByColumnIdFamilyState(recordBoardColumnId),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!columnDefinition || !recordIds) {
|
if (!columnDefinition) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,16 +68,8 @@ export const RecordBoardColumn = ({
|
|||||||
<RecordBoardColumnHeader />
|
<RecordBoardColumnHeader />
|
||||||
<RecordBoardColumnCardsContainer
|
<RecordBoardColumnCardsContainer
|
||||||
droppableProvided={droppableProvided}
|
droppableProvided={droppableProvided}
|
||||||
>
|
recordIds={recordIds}
|
||||||
{recordIds.map((recordId) => (
|
/>
|
||||||
<RecordBoardCardContext.Provider
|
|
||||||
value={{ recordId }}
|
|
||||||
key={recordId}
|
|
||||||
>
|
|
||||||
<RecordBoardCard />
|
|
||||||
</RecordBoardCardContext.Provider>
|
|
||||||
))}
|
|
||||||
</RecordBoardColumnCardsContainer>
|
|
||||||
</StyledColumn>
|
</StyledColumn>
|
||||||
)}
|
)}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import React from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { DroppableProvided } from '@hello-pangea/dnd';
|
import { DroppableProvided } from '@hello-pangea/dnd';
|
||||||
|
|
||||||
|
import { RecordBoardColumnCardsMemo } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsMemo';
|
||||||
|
|
||||||
const StyledPlaceholder = styled.div`
|
const StyledPlaceholder = styled.div`
|
||||||
min-height: 1px;
|
min-height: 1px;
|
||||||
`;
|
`;
|
||||||
@ -13,12 +15,12 @@ const StyledColumnCardsContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
type RecordBoardColumnCardsContainerProps = {
|
type RecordBoardColumnCardsContainerProps = {
|
||||||
children: React.ReactNode;
|
recordIds: string[];
|
||||||
droppableProvided: DroppableProvided;
|
droppableProvided: DroppableProvided;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordBoardColumnCardsContainer = ({
|
export const RecordBoardColumnCardsContainer = ({
|
||||||
children,
|
recordIds,
|
||||||
droppableProvided,
|
droppableProvided,
|
||||||
}: RecordBoardColumnCardsContainerProps) => {
|
}: RecordBoardColumnCardsContainerProps) => {
|
||||||
return (
|
return (
|
||||||
@ -27,7 +29,7 @@ export const RecordBoardColumnCardsContainer = ({
|
|||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
{...droppableProvided?.droppableProps}
|
{...droppableProvided?.droppableProps}
|
||||||
>
|
>
|
||||||
{children}
|
<RecordBoardColumnCardsMemo recordIds={recordIds} />
|
||||||
<StyledPlaceholder>{droppableProvided?.placeholder}</StyledPlaceholder>
|
<StyledPlaceholder>{droppableProvided?.placeholder}</StyledPlaceholder>
|
||||||
</StyledColumnCardsContainer>
|
</StyledColumnCardsContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { RecordBoardCardDraggableContainer } from '@/object-record/record-board/record-board-card/components/RecordBoardCardDraggableContainer';
|
||||||
|
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
||||||
|
|
||||||
|
type RecordBoardColumnCardsMemoProps = {
|
||||||
|
recordIds: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RecordBoardColumnCardsMemo = React.memo(
|
||||||
|
({ recordIds }: RecordBoardColumnCardsMemoProps) => {
|
||||||
|
return recordIds.map((recordId, index) => (
|
||||||
|
<RecordBoardCardContext.Provider value={{ recordId }} key={recordId}>
|
||||||
|
<RecordBoardCardDraggableContainer recordId={recordId} index={index} />
|
||||||
|
</RecordBoardCardContext.Provider>
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
@ -1,4 +1,9 @@
|
|||||||
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
|
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||||
|
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||||
|
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||||
import { RecordBoard } from '@/object-record/record-board/components/RecordBoard';
|
import { RecordBoard } from '@/object-record/record-board/components/RecordBoard';
|
||||||
|
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||||
|
|
||||||
type RecordIndexBoardContainerProps = {
|
type RecordIndexBoardContainerProps = {
|
||||||
recordBoardId: string;
|
recordBoardId: string;
|
||||||
@ -9,6 +14,24 @@ type RecordIndexBoardContainerProps = {
|
|||||||
|
|
||||||
export const RecordIndexBoardContainer = ({
|
export const RecordIndexBoardContainer = ({
|
||||||
recordBoardId,
|
recordBoardId,
|
||||||
|
objectNameSingular,
|
||||||
}: RecordIndexBoardContainerProps) => {
|
}: RecordIndexBoardContainerProps) => {
|
||||||
return <RecordBoard recordBoardId={recordBoardId} />;
|
const { objectMetadataItem } = useObjectMetadataItem({ objectNameSingular });
|
||||||
|
|
||||||
|
const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular });
|
||||||
|
const { updateOneRecord } = useUpdateOneRecord({ objectNameSingular });
|
||||||
|
const { createOneRecord } = useCreateOneRecord({ objectNameSingular });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RecordBoardContext.Provider
|
||||||
|
value={{
|
||||||
|
objectMetadataItem,
|
||||||
|
createOneRecord,
|
||||||
|
updateOneRecord,
|
||||||
|
deleteOneRecord,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RecordBoard recordBoardId={recordBoardId} />
|
||||||
|
</RecordBoardContext.Provider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user