From 921366f5b3f1c5c53f1e6b100e52c899e9556417 Mon Sep 17 00:00:00 2001 From: Tenzin Mahabir <55632829+tmahabir@users.noreply.github.com> Date: Fri, 8 Dec 2023 04:59:42 -0500 Subject: [PATCH] Feature: Add Empty State Display for Tables (#2841) * Added empty state display for when object table is empty * Added functionality to add button for empty state * Fixed positioning of empty state * Renamed style containers for empty state * Added empty state display for when object table is empty * Added functionality to add button for empty state * Fixed positioning of empty state * Renamed style containers for empty state * Addressed PR comments by using createRecord prop and numberOfTableRowsState --- .../record-table/components/RecordTable.tsx | 81 +++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/front/src/modules/object-record/record-table/components/RecordTable.tsx b/front/src/modules/object-record/record-table/components/RecordTable.tsx index 5015e131b..eb94690e4 100644 --- a/front/src/modules/object-record/record-table/components/RecordTable.tsx +++ b/front/src/modules/object-record/record-table/components/RecordTable.tsx @@ -1,20 +1,54 @@ import { useRef } from 'react'; import styled from '@emotion/styled'; -import { useRecoilCallback } from 'recoil'; +import { useRecoilCallback, useRecoilValue } from 'recoil'; -import { RecordTableBodyEffect } from '@/object-record/record-table/components/RecordTableBodyEffect'; -import { RecordTableHeader } from '@/object-record/record-table/components/RecordTableHeader'; -import { RecordTableInternalEffect } from '@/object-record/record-table/components/RecordTableInternalEffect'; -import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; -import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; +import { IconPlus } from '@/ui/display/icon'; +import { Button } from '@/ui/input/button/components/Button'; import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { useViewFields } from '@/views/hooks/internal/useViewFields'; import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField'; import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext'; +import { useRecordTable } from '../hooks/useRecordTable'; +import { RecordTableScope } from '../scopes/RecordTableScope'; +import { numberOfTableRowsState } from '../states/numberOfTableRowsState'; import { RecordTableBody } from './RecordTableBody'; +import { RecordTableBodyEffect } from './RecordTableBodyEffect'; +import { RecordTableHeader } from './RecordTableHeader'; +import { RecordTableInternalEffect } from './RecordTableInternalEffect'; + +const StyledObjectEmptyContainer = styled.div` + align-items: center; + align-self: stretch; + display: flex; + flex: 1 0 0; + flex-direction: column; + gap: ${({ theme }) => 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)}; +`; const StyledTable = styled.table` border-collapse: collapse; @@ -90,9 +124,26 @@ export const RecordTable = ({ }: RecordTableProps) => { const tableBodyRef = useRef(null); - const { resetTableRowSelection, setRowSelectedState } = useRecordTable({ + const numberOfTableRows = useRecoilValue(numberOfTableRowsState); + + const { + scopeId: objectNamePlural, + resetTableRowSelection, + setRowSelectedState, + } = useRecordTable({ recordTableScopeId: recordTableId, }); + + const { objectNameSingular } = useObjectNameSingularFromPlural({ + objectNamePlural, + }); + + const { objectMetadataItem: foundObjectMetadataItem } = useObjectMetadataItem( + { + objectNameSingular, + }, + ); + const { persistViewFields } = useViewFields(viewBarId); return ( @@ -119,6 +170,22 @@ export const RecordTable = ({ /> + {numberOfTableRows === 0 && ( + + + No {foundObjectMetadataItem?.namePlural} + + + Create one: + +