mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-24 06:48:42 +03:00
parent
8ffd958a3c
commit
afbb87ae12
@ -0,0 +1,68 @@
|
||||
import { useRef } from 'react';
|
||||
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 { RecordBoardColumn } from '@/object-record/record-board/record-board-column/components/RecordBoardColumn';
|
||||
import { RecordBoardScope } from '@/object-record/record-board/scopes/RecordBoardScope';
|
||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
|
||||
export type RecordBoardProps = {
|
||||
recordBoardId: string;
|
||||
};
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
border-top: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
margin-left: ${({ theme }) => theme.spacing(2)};
|
||||
margin-right: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledBoardHeader = styled.div`
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
|
||||
const boardRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
return (
|
||||
<RecordBoardScope
|
||||
recordBoardScopeId={recordBoardId}
|
||||
onColumnsChange={() => {}}
|
||||
onFieldsChange={() => {}}
|
||||
>
|
||||
<StyledWrapper>
|
||||
<StyledBoardHeader />
|
||||
<ScrollWrapper>
|
||||
<StyledContainer ref={boardRef}>
|
||||
<DragDropContext onDragEnd={() => {}}>
|
||||
{[].map((column) => (
|
||||
<RecordBoardColumn
|
||||
key={'a'}
|
||||
recordBoardColumnId={'a'}
|
||||
columnDefinition={column}
|
||||
/>
|
||||
))}
|
||||
</DragDropContext>
|
||||
</StyledContainer>
|
||||
</ScrollWrapper>
|
||||
<DragSelect
|
||||
dragSelectable={boardRef}
|
||||
onDragSelectionChange={() => {}}
|
||||
/>
|
||||
</StyledWrapper>
|
||||
</RecordBoardScope>
|
||||
);
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import { BoardColumnDefinition } from '@/object-record/record-board-deprecated/types/BoardColumnDefinition';
|
||||
|
||||
type RecordBoardColumnContextProps = {
|
||||
id: string;
|
||||
columnDefinition: BoardColumnDefinition;
|
||||
};
|
||||
|
||||
export const RecordBoardColumnContext =
|
||||
createContext<RecordBoardColumnContextProps | null>(null);
|
@ -0,0 +1,59 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { Droppable } from '@hello-pangea/dnd';
|
||||
|
||||
import { RecordBoardColumnContext } from '@/object-record/record-board/contexts/RecordBoardColumnContext';
|
||||
import { RecordBoardColumnCardsContainer } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer';
|
||||
import { BoardCardIdContext } from '@/object-record/record-board-deprecated/contexts/BoardCardIdContext';
|
||||
import { BoardColumnDefinition } from '@/object-record/record-board-deprecated/types/BoardColumnDefinition';
|
||||
|
||||
const StyledColumn = styled.div<{ isFirstColumn: boolean }>`
|
||||
background-color: ${({ theme }) => theme.background.primary};
|
||||
border-left: 1px solid
|
||||
${({ theme, isFirstColumn }) =>
|
||||
isFirstColumn ? 'none' : theme.border.color.light};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 200px;
|
||||
min-width: 200px;
|
||||
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
type RecordBoardColumnProps = {
|
||||
recordBoardColumnId: string;
|
||||
columnDefinition: BoardColumnDefinition;
|
||||
};
|
||||
|
||||
export const RecordBoardColumn = ({
|
||||
recordBoardColumnId,
|
||||
columnDefinition,
|
||||
}: RecordBoardColumnProps) => {
|
||||
const isFirstColumn = columnDefinition.position === 0;
|
||||
|
||||
return (
|
||||
<RecordBoardColumnContext.Provider
|
||||
value={{
|
||||
id: recordBoardColumnId,
|
||||
columnDefinition: columnDefinition,
|
||||
}}
|
||||
>
|
||||
<Droppable droppableId={recordBoardColumnId}>
|
||||
{(droppableProvided) => (
|
||||
<StyledColumn isFirstColumn={isFirstColumn}>
|
||||
<RecordBoardColumnCardsContainer
|
||||
droppableProvided={droppableProvided}
|
||||
>
|
||||
{[].map((cardId, _index) => (
|
||||
<BoardCardIdContext.Provider
|
||||
value={cardId}
|
||||
key={cardId}
|
||||
></BoardCardIdContext.Provider>
|
||||
))}
|
||||
</RecordBoardColumnCardsContainer>
|
||||
</StyledColumn>
|
||||
)}
|
||||
</Droppable>
|
||||
</RecordBoardColumnContext.Provider>
|
||||
);
|
||||
};
|
@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { DroppableProvided } from '@hello-pangea/dnd';
|
||||
|
||||
const StyledPlaceholder = styled.div`
|
||||
min-height: 1px;
|
||||
`;
|
||||
|
||||
const StyledColumnCardsContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
type RecordBoardColumnCardsContainerProps = {
|
||||
children: React.ReactNode;
|
||||
droppableProvided: DroppableProvided;
|
||||
};
|
||||
|
||||
export const RecordBoardColumnCardsContainer = ({
|
||||
children,
|
||||
droppableProvided,
|
||||
}: RecordBoardColumnCardsContainerProps) => {
|
||||
return (
|
||||
<StyledColumnCardsContainer
|
||||
ref={droppableProvided?.innerRef}
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...droppableProvided?.droppableProps}
|
||||
>
|
||||
{children}
|
||||
<StyledPlaceholder>{droppableProvided?.placeholder}</StyledPlaceholder>
|
||||
</StyledColumnCardsContainer>
|
||||
);
|
||||
};
|
@ -0,0 +1,32 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
|
||||
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
|
||||
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
|
||||
import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
|
||||
|
||||
type RecordBoardScopeProps = {
|
||||
children: ReactNode;
|
||||
recordBoardScopeId: string;
|
||||
onFieldsChange: (fields: FieldDefinition<FieldMetadata>[]) => void;
|
||||
onColumnsChange: (column: RecordBoardColumnDefinition[]) => void;
|
||||
};
|
||||
|
||||
export const RecordBoardScope = ({
|
||||
children,
|
||||
recordBoardScopeId,
|
||||
onColumnsChange,
|
||||
onFieldsChange,
|
||||
}: RecordBoardScopeProps) => {
|
||||
return (
|
||||
<RecordBoardScopeInternalContext.Provider
|
||||
value={{
|
||||
scopeId: recordBoardScopeId,
|
||||
onColumnsChange,
|
||||
onFieldsChange,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RecordBoardScopeInternalContext.Provider>
|
||||
);
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
|
||||
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
|
||||
import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||
|
||||
type RecordBoardDeprecatedScopeInternalContextProps = StateScopeMapKey & {
|
||||
onFieldsChange: (fields: FieldDefinition<FieldMetadata>[]) => void;
|
||||
onColumnsChange: (column: RecordBoardColumnDefinition[]) => void;
|
||||
};
|
||||
|
||||
export const RecordBoardScopeInternalContext =
|
||||
createScopeInternalContext<RecordBoardDeprecatedScopeInternalContextProps>();
|
@ -0,0 +1,8 @@
|
||||
import { ThemeColor } from '@/ui/theme/constants/colors';
|
||||
|
||||
export type RecordBoardColumnDefinition = {
|
||||
id: string;
|
||||
title: string;
|
||||
position: number;
|
||||
colorCode?: ThemeColor;
|
||||
};
|
@ -0,0 +1,14 @@
|
||||
import { RecordBoard } from '@/object-record/record-board/components/RecordBoard';
|
||||
|
||||
type RecordIndexBoardContainerProps = {
|
||||
recordBoardId: string;
|
||||
viewBarId: string;
|
||||
objectNamePlural: string;
|
||||
createRecord: () => Promise<void>;
|
||||
};
|
||||
|
||||
export const RecordIndexBoardContainer = ({
|
||||
recordBoardId,
|
||||
}: RecordIndexBoardContainerProps) => {
|
||||
return <RecordBoard recordBoardId={recordBoardId}></RecordBoard>;
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
type RecordIndexBoardContainerEffectProps = {
|
||||
objectNamePlural: string;
|
||||
recordBoardId: string;
|
||||
viewBarId: string;
|
||||
};
|
||||
|
||||
export const RecordIndexBoardContainerEffect = (
|
||||
_props: RecordIndexBoardContainerEffectProps,
|
||||
) => {
|
||||
return <></>;
|
||||
};
|
@ -5,8 +5,10 @@ import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCom
|
||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||
import { RecordIndexBoardContainer } from '@/object-record/record-index/components/RecordIndexBoardContainer';
|
||||
import { RecordIndexTableContainer } from '@/object-record/record-index/components/RecordIndexTableContainer';
|
||||
import { RecordIndexViewInitEffect } from '@/object-record/record-index/components/RecordIndexViewInitEffect';
|
||||
import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect';
|
||||
import { RecordIndexViewBarEffect } from '@/object-record/record-index/components/RecordIndexViewBarEffect';
|
||||
import { TableOptionsDropdownId } from '@/object-record/record-table/constants/TableOptionsDropdownId';
|
||||
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
|
||||
import { TableOptionsDropdown } from '@/object-record/record-table/options/components/TableOptionsDropdown';
|
||||
@ -22,6 +24,7 @@ const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
padding-left: ${({ theme }) => theme.table.horizontalCellPadding};
|
||||
`;
|
||||
@ -98,19 +101,41 @@ export const RecordIndexContainer = ({
|
||||
setRecordIndexViewType(viewType);
|
||||
}}
|
||||
/>
|
||||
<RecordIndexViewBarEffect
|
||||
objectNamePlural={objectNamePlural}
|
||||
viewBarId={recordIndexId}
|
||||
/>
|
||||
</SpreadsheetImportProvider>
|
||||
{recordIndexViewType === ViewType.Table && (
|
||||
<RecordIndexTableContainer
|
||||
recordTableId={recordIndexId}
|
||||
viewBarId={recordIndexId}
|
||||
objectNamePlural={objectNamePlural}
|
||||
createRecord={createRecord}
|
||||
/>
|
||||
<>
|
||||
<RecordIndexTableContainer
|
||||
recordTableId={recordIndexId}
|
||||
viewBarId={recordIndexId}
|
||||
objectNamePlural={objectNamePlural}
|
||||
createRecord={createRecord}
|
||||
/>
|
||||
<RecordIndexTableContainerEffect
|
||||
objectNamePlural={objectNamePlural}
|
||||
recordTableId={recordIndexId}
|
||||
viewBarId={recordIndexId}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{recordIndexViewType === ViewType.Kanban && (
|
||||
<>
|
||||
<RecordIndexBoardContainer
|
||||
recordBoardId={recordIndexId}
|
||||
viewBarId={recordIndexId}
|
||||
objectNamePlural={objectNamePlural}
|
||||
createRecord={createRecord}
|
||||
/>
|
||||
<RecordIndexTableContainerEffect
|
||||
objectNamePlural={objectNamePlural}
|
||||
recordTableId={recordIndexId}
|
||||
viewBarId={recordIndexId}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<RecordIndexViewInitEffect
|
||||
objectNamePlural={objectNamePlural}
|
||||
viewBarId={recordIndexId}
|
||||
/>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||
import { RecordUpdateHookParams } from '@/object-record/field/contexts/FieldContext';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { RecordTableEffect } from '@/object-record/record-index/components/RecordTableEffect';
|
||||
import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar';
|
||||
import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers';
|
||||
import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu';
|
||||
@ -36,11 +35,6 @@ export const RecordIndexTableContainer = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<RecordTableEffect
|
||||
objectNamePlural={objectNamePlural}
|
||||
recordTableId={recordTableId}
|
||||
viewBarId={viewBarId}
|
||||
/>
|
||||
<RecordTableWithWrappers
|
||||
recordTableId={recordTableId}
|
||||
objectNamePlural={objectNamePlural}
|
||||
|
@ -8,15 +8,17 @@ import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTabl
|
||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
|
||||
export const RecordTableEffect = ({
|
||||
objectNamePlural,
|
||||
recordTableId,
|
||||
viewBarId,
|
||||
}: {
|
||||
type RecordIndexTableContainerEffectProps = {
|
||||
objectNamePlural: string;
|
||||
recordTableId: string;
|
||||
viewBarId: string;
|
||||
}) => {
|
||||
};
|
||||
|
||||
export const RecordIndexTableContainerEffect = ({
|
||||
objectNamePlural,
|
||||
recordTableId,
|
||||
viewBarId,
|
||||
}: RecordIndexTableContainerEffectProps) => {
|
||||
const {
|
||||
setAvailableTableColumns,
|
||||
setOnEntityCountChange,
|
@ -5,13 +5,15 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
|
||||
export const RecordIndexViewInitEffect = ({
|
||||
objectNamePlural,
|
||||
viewBarId,
|
||||
}: {
|
||||
type RecordIndexViewBarEffectProps = {
|
||||
objectNamePlural: string;
|
||||
viewBarId: string;
|
||||
}) => {
|
||||
};
|
||||
|
||||
export const RecordIndexViewBarEffect = ({
|
||||
objectNamePlural,
|
||||
viewBarId,
|
||||
}: RecordIndexViewBarEffectProps) => {
|
||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
||||
objectNamePlural,
|
||||
});
|
Loading…
Reference in New Issue
Block a user