@ -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 { 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 { 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 { 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 { 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';
|
||||||
@ -22,6 +24,7 @@ const StyledContainer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding-left: ${({ theme }) => theme.table.horizontalCellPadding};
|
padding-left: ${({ theme }) => theme.table.horizontalCellPadding};
|
||||||
`;
|
`;
|
||||||
@ -98,19 +101,41 @@ export const RecordIndexContainer = ({
|
|||||||
setRecordIndexViewType(viewType);
|
setRecordIndexViewType(viewType);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<RecordIndexViewBarEffect
|
||||||
|
objectNamePlural={objectNamePlural}
|
||||||
|
viewBarId={recordIndexId}
|
||||||
|
/>
|
||||||
</SpreadsheetImportProvider>
|
</SpreadsheetImportProvider>
|
||||||
{recordIndexViewType === ViewType.Table && (
|
{recordIndexViewType === ViewType.Table && (
|
||||||
<RecordIndexTableContainer
|
<>
|
||||||
recordTableId={recordIndexId}
|
<RecordIndexTableContainer
|
||||||
viewBarId={recordIndexId}
|
recordTableId={recordIndexId}
|
||||||
objectNamePlural={objectNamePlural}
|
viewBarId={recordIndexId}
|
||||||
createRecord={createRecord}
|
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>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||||
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 { RecordTableEffect } from '@/object-record/record-index/components/RecordTableEffect';
|
|
||||||
import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar';
|
import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar';
|
||||||
import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers';
|
import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers';
|
||||||
import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu';
|
import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu';
|
||||||
@ -36,11 +35,6 @@ export const RecordIndexTableContainer = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RecordTableEffect
|
|
||||||
objectNamePlural={objectNamePlural}
|
|
||||||
recordTableId={recordTableId}
|
|
||||||
viewBarId={viewBarId}
|
|
||||||
/>
|
|
||||||
<RecordTableWithWrappers
|
<RecordTableWithWrappers
|
||||||
recordTableId={recordTableId}
|
recordTableId={recordTableId}
|
||||||
objectNamePlural={objectNamePlural}
|
objectNamePlural={objectNamePlural}
|
||||||
|
|||||||
@ -8,15 +8,17 @@ import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTabl
|
|||||||
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';
|
||||||
|
|
||||||
export const RecordTableEffect = ({
|
type RecordIndexTableContainerEffectProps = {
|
||||||
objectNamePlural,
|
|
||||||
recordTableId,
|
|
||||||
viewBarId,
|
|
||||||
}: {
|
|
||||||
objectNamePlural: string;
|
objectNamePlural: string;
|
||||||
recordTableId: string;
|
recordTableId: string;
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
export const RecordIndexTableContainerEffect = ({
|
||||||
|
objectNamePlural,
|
||||||
|
recordTableId,
|
||||||
|
viewBarId,
|
||||||
|
}: RecordIndexTableContainerEffectProps) => {
|
||||||
const {
|
const {
|
||||||
setAvailableTableColumns,
|
setAvailableTableColumns,
|
||||||
setOnEntityCountChange,
|
setOnEntityCountChange,
|
||||||
@ -5,13 +5,15 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
|||||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
export const RecordIndexViewInitEffect = ({
|
type RecordIndexViewBarEffectProps = {
|
||||||
objectNamePlural,
|
|
||||||
viewBarId,
|
|
||||||
}: {
|
|
||||||
objectNamePlural: string;
|
objectNamePlural: string;
|
||||||
viewBarId: string;
|
viewBarId: string;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
export const RecordIndexViewBarEffect = ({
|
||||||
|
objectNamePlural,
|
||||||
|
viewBarId,
|
||||||
|
}: RecordIndexViewBarEffectProps) => {
|
||||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
||||||
objectNamePlural,
|
objectNamePlural,
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user