From 220434530049bb96e3854927c6353b68b8507995 Mon Sep 17 00:00:00 2001 From: Muralidhar <33935339+Muralidhar22@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:07:29 +0530 Subject: [PATCH] first column of objects table fixed (#3147) * ui:first column of objects table fixed * refactor shadow style logic * Minor renaming fixes --------- Co-authored-by: Lucas Bordeau --- .../components/RecordTableContainer.tsx | 5 +- .../record-table/components/RecordTable.tsx | 209 +++++------------- .../RecordTableFirstColumnScrollObserver.tsx | 22 ++ .../components/RecordTableHeaderCell.tsx | 2 +- .../components/RecordTableRefContext.tsx | 19 ++ .../components/RecordTableWithWrappers.tsx | 154 +++++++++++++ .../contexts/RecordTableRefContext.ts | 7 + .../SignInBackgroundMockContainer.tsx | 4 +- .../src/modules/ui/theme/constants/theme.ts | 1 + 9 files changed, 269 insertions(+), 154 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-table/components/RecordTableFirstColumnScrollObserver.tsx create mode 100644 packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRefContext.tsx create mode 100644 packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx create mode 100644 packages/twenty-front/src/modules/object-record/record-table/contexts/RecordTableRefContext.ts diff --git a/packages/twenty-front/src/modules/object-record/components/RecordTableContainer.tsx b/packages/twenty-front/src/modules/object-record/components/RecordTableContainer.tsx index 5f897dcf33..0045a46201 100644 --- a/packages/twenty-front/src/modules/object-record/components/RecordTableContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/components/RecordTableContainer.tsx @@ -6,7 +6,7 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; import { RecordUpdateHookParams } from '@/object-record/field/contexts/FieldContext'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; -import { RecordTable } from '@/object-record/record-table/components/RecordTable'; +import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers'; 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'; @@ -24,6 +24,7 @@ const StyledContainer = styled.div` flex-direction: column; height: 100%; overflow: auto; + padding-left: ${({ theme }) => theme.table.horizontalCellPadding}; `; export const RecordTableContainer = ({ @@ -103,7 +104,7 @@ export const RecordTableContainer = ({ /> - theme.spacing(2)}; - justify-content: center; - padding-bottom: ${({ theme }) => theme.spacing(16)}; - padding-left: ${({ theme }) => theme.spacing(4)}; - padding-right: ${({ theme }) => theme.spacing(4)}; - padding-top: ${({ theme }) => theme.spacing(3)}; -`; - -const StyledEmptyObjectTitle = styled.div` - color: ${({ theme }) => theme.font.color.secondary}; - font-size: ${({ theme }) => theme.font.size.xxl}; - font-weight: ${({ theme }) => theme.font.weight.semiBold}; - line-height: ${({ theme }) => theme.text.lineHeight.md}; -`; - -const StyledEmptyObjectSubTitle = styled.div` - color: ${({ theme }) => theme.font.color.extraLight}; - font-size: ${({ theme }) => theme.font.size.xxl}; - font-weight: ${({ theme }) => theme.font.weight.semiBold}; - line-height: ${({ theme }) => theme.text.lineHeight.md}; - margin-bottom: ${({ theme }) => theme.spacing(2)}; -`; +import { RecordTableBody } from '@/object-record/record-table/components/RecordTableBody'; +import { RecordTableBodyEffect } from '@/object-record/record-table/components/RecordTableBodyEffect'; +import { RecordTableHeader } from '@/object-record/record-table/components/RecordTableHeader'; +import { RecordTableRefContext } from '@/object-record/record-table/contexts/RecordTableRefContext'; +import { rgba } from '@/ui/theme/constants/colors'; const StyledTable = styled.table` - border-collapse: collapse; - border-radius: ${({ theme }) => theme.border.radius.sm}; border-spacing: 0; - margin-left: ${({ theme }) => theme.table.horizontalCellMargin}; margin-right: ${({ theme }) => theme.table.horizontalCellMargin}; table-layout: fixed; width: calc(100% - ${({ theme }) => theme.table.horizontalCellMargin} * 2); th { - border: 1px solid ${({ theme }) => theme.border.color.light}; - border-collapse: collapse; + border-block: 1px solid ${({ theme }) => theme.border.color.light}; color: ${({ theme }) => theme.font.color.tertiary}; padding: 0; text-align: left; @@ -79,8 +31,7 @@ const StyledTable = styled.table` } td { - border: 1px solid ${({ theme }) => theme.border.color.light}; - border-collapse: collapse; + border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; color: ${({ theme }) => theme.font.color.primary}; padding: 0; @@ -94,107 +45,67 @@ const StyledTable = styled.table` border-right-color: transparent; } } -`; -const StyledTableWithHeader = styled.div` - display: flex; - flex: 1; - flex-direction: column; - width: 100%; -`; + th, + td { + background-color: ${({ theme }) => theme.background.primary}; + border-right: 1px solid ${({ theme }) => theme.border.color.light}; + } -const StyledTableContainer = styled.div` - display: flex; - flex-direction: column; - height: 100%; - position: relative; + thead th:nth-of-type(-n + 2), + tbody td:nth-of-type(-n + 2) { + position: sticky; + z-index: 2; + border-right: none; + } + + thead th:nth-of-type(1), + tbody td:nth-of-type(1) { + left: 0; + } + thead th:nth-of-type(2), + tbody td:nth-of-type(2) { + left: calc(${({ theme }) => theme.table.checkboxColumnWidth} - 2px); + } + + tbody td:nth-of-type(2)::after, + thead th:nth-of-type(2)::after { + content: ''; + height: calc(100% + 1px); + position: absolute; + top: 0; + width: 4px; + right: -4px; + } + + &.freeze-first-columns-shadow thead th:nth-of-type(2)::after, + &.freeze-first-columns-shadow tbody td:nth-of-type(2)::after { + box-shadow: ${({ theme }) => + `4px 0px 4px -4px ${ + theme.name === 'dark' + ? rgba(theme.grayScale.gray50, 0.8) + : rgba(theme.grayScale.gray100, 0.25) + } inset`}; + } + + thead th:nth-of-type(3), + tbody td:nth-of-type(3) { + border-left: 1px solid ${({ theme }) => theme.border.color.light}; + } `; type RecordTableProps = { - recordTableId: string; - viewBarId: string; - updateRecordMutation: (params: any) => void; createRecord: () => void; }; -export const RecordTable = ({ - updateRecordMutation, - createRecord, - recordTableId, - viewBarId, -}: RecordTableProps) => { - const tableBodyRef = useRef(null); - - const numberOfTableRows = useRecoilValue(numberOfTableRowsState); - - const isRecordTableInitialLoading = useRecoilValue( - isRecordTableInitialLoadingState, - ); - - const { - scopeId: objectNamePlural, - resetTableRowSelection, - setRowSelectedState, - } = useRecordTable({ - recordTableScopeId: recordTableId, - }); - - const { objectNameSingular } = useObjectNameSingularFromPlural({ - objectNamePlural, - }); - - const { objectMetadataItem: foundObjectMetadataItem } = useObjectMetadataItem( - { - objectNameSingular, - }, - ); - - const { persistViewFields } = useViewFields(viewBarId); +export const RecordTable = ({ createRecord }: RecordTableProps) => { + const recordTableRef = useContext(RecordTableRefContext); return ( - (columns) => { - persistViewFields(mapColumnDefinitionsToViewFields(columns)); - })} - > - - - - -
- - - - - - -
- - {!isRecordTableInitialLoading && numberOfTableRows === 0 && ( - - - No {foundObjectMetadataItem?.namePlural} - - - Create one: - -