diff --git a/packages/twenty-front/public/images/placeholders/background/no_deleted_record_bg.png b/packages/twenty-front/public/images/placeholders/background/no_deleted_record_bg.png new file mode 100644 index 000000000..f69676ba7 Binary files /dev/null and b/packages/twenty-front/public/images/placeholders/background/no_deleted_record_bg.png differ diff --git a/packages/twenty-front/public/images/placeholders/dark-background/no_deleted_record_bg.png b/packages/twenty-front/public/images/placeholders/dark-background/no_deleted_record_bg.png new file mode 100644 index 000000000..3a7dd1cab Binary files /dev/null and b/packages/twenty-front/public/images/placeholders/dark-background/no_deleted_record_bg.png differ diff --git a/packages/twenty-front/public/images/placeholders/dark-background/no_match_record_bg.png b/packages/twenty-front/public/images/placeholders/dark-background/no_match_record_bg.png index da554e159..bb55a0b9c 100644 Binary files a/packages/twenty-front/public/images/placeholders/dark-background/no_match_record_bg.png and b/packages/twenty-front/public/images/placeholders/dark-background/no_match_record_bg.png differ diff --git a/packages/twenty-front/public/images/placeholders/dark-moving-image/no_deleted_record.png b/packages/twenty-front/public/images/placeholders/dark-moving-image/no_deleted_record.png new file mode 100644 index 000000000..3e52331a1 Binary files /dev/null and b/packages/twenty-front/public/images/placeholders/dark-moving-image/no_deleted_record.png differ diff --git a/packages/twenty-front/public/images/placeholders/moving-image/no_deleted_record.png b/packages/twenty-front/public/images/placeholders/moving-image/no_deleted_record.png new file mode 100644 index 000000000..9ee5863d4 Binary files /dev/null and b/packages/twenty-front/public/images/placeholders/moving-image/no_deleted_record.png differ diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectIsRemote.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectIsRemote.ts new file mode 100644 index 000000000..0f3295dc5 --- /dev/null +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectIsRemote.ts @@ -0,0 +1,5 @@ +import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; + +export const useObjectIsRemote = (objectMetadataItem: ObjectMetadataItem) => { + return objectMetadataItem.isRemote ?? false; +}; diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/useObjectLabel.ts b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectLabel.ts new file mode 100644 index 000000000..7ef0881d6 --- /dev/null +++ b/packages/twenty-front/src/modules/object-metadata/hooks/useObjectLabel.ts @@ -0,0 +1,5 @@ +import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; + +export const useObjectLabel = (objectMetadataItem: ObjectMetadataItem) => { + return objectMetadataItem?.labelSingular ?? ''; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx index bd412f910..8bca15108 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexBoardContainer.tsx @@ -14,7 +14,6 @@ type RecordIndexBoardContainerProps = { recordBoardId: string; viewBarId: string; objectNameSingular: string; - createRecord: () => Promise; }; export const RecordIndexBoardContainer = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx index 833f92060..e8cdaa20f 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx @@ -4,14 +4,12 @@ import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; -import { lastShowPageRecordIdState } from '@/object-record/record-field/states/lastShowPageRecordId'; import { RecordIndexBoardContainer } from '@/object-record/record-index/components/RecordIndexBoardContainer'; import { RecordIndexBoardDataLoader } from '@/object-record/record-index/components/RecordIndexBoardDataLoader'; import { RecordIndexBoardDataLoaderEffect } from '@/object-record/record-index/components/RecordIndexBoardDataLoaderEffect'; import { RecordIndexTableContainer } from '@/object-record/record-index/components/RecordIndexTableContainer'; import { RecordIndexTableContainerEffect } from '@/object-record/record-index/components/RecordIndexTableContainerEffect'; import { RecordIndexViewBarEffect } from '@/object-record/record-index/components/RecordIndexViewBarEffect'; -import { RecordIndexEventContext } from '@/object-record/record-index/contexts/RecordIndexEventContext'; import { RecordIndexOptionsDropdown } from '@/object-record/record-index/options/components/RecordIndexOptionsDropdown'; import { recordIndexFieldDefinitionsState } from '@/object-record/record-index/states/recordIndexFieldDefinitionsState'; import { recordIndexFiltersState } from '@/object-record/record-index/states/recordIndexFiltersState'; @@ -21,7 +19,7 @@ import { recordIndexSortsState } from '@/object-record/record-index/states/recor import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState'; import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper'; -import { useHandleIndexIdentifierClick } from '@/object-record/record-index/hooks/useHandleIndexIdentifierClick'; +import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext'; import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; @@ -31,6 +29,7 @@ import { ViewType } from '@/views/types/ViewType'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts'; +import { useContext } from 'react'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; const StyledContainer = styled.div` @@ -46,20 +45,15 @@ const StyledContainerWithPadding = styled.div<{ fullHeight?: boolean }>` padding-left: ${({ theme }) => theme.table.horizontalCellPadding}; `; -type RecordIndexContainerProps = { - recordIndexId: string; - objectNamePlural: string; - createRecord: () => Promise; -}; - -export const RecordIndexContainer = ({ - createRecord, - recordIndexId, - objectNamePlural, -}: RecordIndexContainerProps) => { +export const RecordIndexContainer = () => { const [recordIndexViewType, setRecordIndexViewType] = useRecoilState( recordIndexViewTypeState, ); + + const { objectNamePlural, recordIndexId } = useContext( + RecordIndexRootPropsContext, + ); + const { objectNameSingular } = useObjectNameSingularFromPlural({ objectNamePlural, }); @@ -110,20 +104,6 @@ export const RecordIndexContainer = ({ [columnDefinitions, setTableColumns], ); - const { handleIndexIdentifierClick } = useHandleIndexIdentifierClick({ - objectMetadataItem, - recordIndexId, - }); - - const handleIndexRecordsLoaded = useRecoilCallback( - ({ set }) => - () => { - // TODO: find a better way to reset this state ? - set(lastShowPageRecordIdState, null); - }, - [], - ); - return ( @@ -170,46 +150,37 @@ export const RecordIndexContainer = ({ /> - - {recordIndexViewType === ViewType.Table && ( - <> - - - - )} - {recordIndexViewType === ViewType.Kanban && ( - - - - - - )} - + + {recordIndexViewType === ViewType.Table && ( + <> + + + + )} + {recordIndexViewType === ViewType.Kanban && ( + + + + + + )} ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx index b2296a6f3..bb8c0197a 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx @@ -3,27 +3,23 @@ import { useIcons } from 'twenty-ui'; import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; import { RecordIndexPageKanbanAddButton } from '@/object-record/record-index/components/RecordIndexPageKanbanAddButton'; +import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext'; import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState'; import { PageAddButton } from '@/ui/layout/page/PageAddButton'; import { PageHeader } from '@/ui/layout/page/PageHeader'; import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect'; import { ViewType } from '@/views/types/ViewType'; +import { useContext } from 'react'; import { capitalize } from '~/utils/string/capitalize'; -type RecordIndexPageHeaderProps = { - createRecord: () => void; - recordIndexId: string; - objectNamePlural: string; -}; - -export const RecordIndexPageHeader = ({ - createRecord, - recordIndexId, - objectNamePlural, -}: RecordIndexPageHeaderProps) => { +export const RecordIndexPageHeader = () => { const { findObjectMetadataItemByNamePlural } = useFilteredObjectMetadataItems(); + const { objectNamePlural, onCreateRecord } = useContext( + RecordIndexRootPropsContext, + ); + const objectMetadataItem = findObjectMetadataItemByNamePlural(objectNamePlural); @@ -40,16 +36,17 @@ export const RecordIndexPageHeader = ({ const pageHeaderTitle = objectMetadataItem?.labelPlural ?? capitalize(objectNamePlural); + const handleAddButtonClick = () => { + onCreateRecord(); + }; + return ( - + {isTable ? ( - + ) : ( - + )} ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddButton.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddButton.tsx index 6299546e0..679896c32 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddButton.tsx @@ -2,6 +2,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition'; import { RecordIndexPageKanbanAddMenuItem } from '@/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem'; +import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext'; import { useRecordIndexPageKanbanAddButton } from '@/object-record/record-index/hooks/useRecordIndexPageKanbanAddButton'; import { SingleEntitySelect } from '@/object-record/relation-picker/components/SingleEntitySelect'; import { useEntitySelectSearch } from '@/object-record/relation-picker/hooks/useEntitySelectSearch'; @@ -14,7 +15,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; import styled from '@emotion/styled'; -import { useCallback, useState } from 'react'; +import { useCallback, useContext, useState } from 'react'; import { useRecoilValue } from 'recoil'; import { IconPlus, isDefined } from 'twenty-ui'; @@ -26,20 +27,16 @@ const StyledDropDownMenu = styled(DropdownMenu)` width: 200px; `; -type RecordIndexPageKanbanAddButtonProps = { - recordIndexId: string; - objectNamePlural: string; -}; - -export const RecordIndexPageKanbanAddButton = ({ - recordIndexId, - objectNamePlural, -}: RecordIndexPageKanbanAddButtonProps) => { +export const RecordIndexPageKanbanAddButton = () => { const dropdownId = `record-index-page-add-button-dropdown`; const [isSelectingCompany, setIsSelectingCompany] = useState(false); const [selectedColumnDefinition, setSelectedColumnDefinition] = useState(); + const { recordIndexId, objectNamePlural } = useContext( + RecordIndexRootPropsContext, + ); + const { columnIdsState } = useRecordBoardStates(recordIndexId); const columnIds = useRecoilValue(columnIdsState); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx index f5af2e96f..50bb639f5 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx @@ -1,23 +1,23 @@ import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { RecordUpdateHookParams } from '@/object-record/record-field/contexts/FieldContext'; import { RecordIndexRemoveSortingModal } from '@/object-record/record-index/components/RecordIndexRemoveSortingModal'; +import { RecordIndexRootPropsContext } from '@/object-record/record-index/contexts/RecordIndexRootPropsContext'; 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'; +import { useContext } from 'react'; type RecordIndexTableContainerProps = { recordTableId: string; viewBarId: string; - objectNameSingular: string; - createRecord: () => Promise; }; export const RecordIndexTableContainer = ({ recordTableId, viewBarId, - objectNameSingular, - createRecord, }: RecordIndexTableContainerProps) => { + const { objectNameSingular } = useContext(RecordIndexRootPropsContext); + const { updateOneRecord } = useUpdateOneRecord({ objectNameSingular, }); @@ -36,7 +36,6 @@ export const RecordIndexTableContainer = ({ objectNameSingular={objectNameSingular} viewBarId={viewBarId} updateRecordMutation={updateEntity} - createRecord={createRecord} /> diff --git a/packages/twenty-front/src/modules/object-record/record-index/contexts/RecordIndexRootPropsContext.ts b/packages/twenty-front/src/modules/object-record/record-index/contexts/RecordIndexRootPropsContext.ts new file mode 100644 index 000000000..6de7cd552 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-index/contexts/RecordIndexRootPropsContext.ts @@ -0,0 +1,13 @@ +import { createRootPropsContext } from '~/utils/createRootPropsContext'; + +export type RecordIndexRootPropsContextProps = { + onIndexIdentifierClick: (recordId: string) => void; + onIndexRecordsLoaded: () => void; + onCreateRecord: () => void; + objectNamePlural: string; + objectNameSingular: string; + recordIndexId: string; +}; + +export const RecordIndexRootPropsContext = + createRootPropsContext(); diff --git a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts index 033773b96..bbe862c0a 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-index/hooks/useHandleToggleTrashColumnFilter.ts @@ -5,8 +5,10 @@ import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/u import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; +import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { useCombinedViewFilters } from '@/views/hooks/useCombinedViewFilters'; import { ViewFilterOperand } from '@/views/types/ViewFilterOperand'; +import { useRecoilCallback } from 'recoil'; import { isDefined } from '~/utils/isDefined'; type UseHandleToggleTrashColumnFilterProps = { @@ -26,6 +28,7 @@ export const useHandleToggleTrashColumnFilter = ({ useColumnDefinitionsFromFieldMetadata(objectMetadataItem); const { upsertCombinedViewFilter } = useCombinedViewFilters(viewBarId); + const { isSoftDeleteActiveState } = useRecordTableStates(viewBarId); const handleToggleTrashColumnFilter = useCallback(() => { const trashFieldMetadata = objectMetadataItem.fields.find( @@ -63,5 +66,15 @@ export const useHandleToggleTrashColumnFilter = ({ upsertCombinedViewFilter(newFilter); }, [columnDefinitions, objectMetadataItem, upsertCombinedViewFilter]); - return handleToggleTrashColumnFilter; + const toggleSoftDeleteFilterState = useRecoilCallback( + ({ set }) => + (currentState: boolean) => { + set(isSoftDeleteActiveState, currentState); + }, + [isSoftDeleteActiveState], + ); + return { + handleToggleTrashColumnFilter, + toggleSoftDeleteFilterState, + }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx index 2386009de..a884eda85 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx @@ -90,10 +90,11 @@ export const RecordIndexOptionsDropdownContent = ({ hiddenTableColumns, } = useRecordIndexOptionsForTable(recordIndexId); - const handleToggleTrashColumnFilter = useHandleToggleTrashColumnFilter({ - objectNameSingular, - viewBarId: recordIndexId, - }); + const { handleToggleTrashColumnFilter, toggleSoftDeleteFilterState } = + useHandleToggleTrashColumnFilter({ + objectNameSingular, + viewBarId: recordIndexId, + }); const { visibleBoardFields, @@ -163,6 +164,7 @@ export const RecordIndexOptionsDropdownContent = ({ { handleToggleTrashColumnFilter(); + toggleSoftDeleteFilterState(true); closeDropdown(); }} LeftIcon={IconRotate2} diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx index 5e3b8c23a..7f76f10a5 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx @@ -1,9 +1,8 @@ import styled from '@emotion/styled'; import { isNonEmptyString, isNull } from '@sniptt/guards'; -import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { RecordTableContextProvider } from '@/object-record/record-table/components/RecordTableContextProvider'; -import { RecordTableEmptyState } from '@/object-record/record-table/components/RecordTableEmptyState'; +import { RecordTableEmptyState } from '@/object-record/record-table/empty-state/components/RecordTableEmptyState'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { RecordTableBody } from '@/object-record/record-table/record-table-body/components/RecordTableBody'; import { RecordTableBodyEffect } from '@/object-record/record-table/record-table-body/components/RecordTableBodyEffect'; @@ -25,7 +24,6 @@ type RecordTableProps = { recordTableId: string; objectNameSingular: string; onColumnsChange: (columns: any) => void; - createRecord: () => void; }; export const RecordTable = ({ @@ -33,7 +31,6 @@ export const RecordTable = ({ recordTableId, objectNameSingular, onColumnsChange, - createRecord, }: RecordTableProps) => { const { scopeId } = useRecordTableStates(recordTableId); @@ -51,12 +48,10 @@ export const RecordTable = ({ const pendingRecordId = useRecoilValue(pendingRecordIdState); - const { objectMetadataItem: foundObjectMetadataItem } = useObjectMetadataItem( - { objectNameSingular }, - ); - - const objectLabel = foundObjectMetadataItem?.labelSingular; - const isRemote = foundObjectMetadataItem?.isRemote ?? false; + const recordTableIsEmpty = + !isRecordTableInitialLoading && + tableRowIds.length === 0 && + isNull(pendingRecordId); if (!isNonEmptyString(objectNameSingular)) { return <>; @@ -73,18 +68,11 @@ export const RecordTable = ({ viewBarId={viewBarId} > - {!isRecordTableInitialLoading && - tableRowIds.length === 0 && - isNull(pendingRecordId) ? ( - + {recordTableIsEmpty ? ( + ) : ( - + )} diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableEmptyState.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableEmptyState.tsx deleted file mode 100644 index 18aef6779..000000000 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableEmptyState.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { useNavigate } from 'react-router-dom'; -import { IconPlus, IconSettings } from 'twenty-ui'; - -import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; -import { Button } from '@/ui/input/button/components/Button'; -import AnimatedPlaceholder from '@/ui/layout/animated-placeholder/components/AnimatedPlaceholder'; -import { - AnimatedPlaceholderEmptyContainer, - AnimatedPlaceholderEmptySubTitle, - AnimatedPlaceholderEmptyTextContainer, - AnimatedPlaceholderEmptyTitle, -} from '@/ui/layout/animated-placeholder/components/EmptyPlaceholderStyled'; - -type RecordTableEmptyStateProps = { - objectNameSingular: string; - objectLabel: string; - createRecord: () => void; - isRemote: boolean; -}; - -export const RecordTableEmptyState = ({ - objectNameSingular, - objectLabel, - createRecord, - isRemote, -}: RecordTableEmptyStateProps) => { - const navigate = useNavigate(); - const { totalCount } = useFindManyRecords({ objectNameSingular, limit: 1 }); - const noExistingRecords = totalCount === 0; - - const [title, subTitle, Icon, onClick, buttonTitle] = isRemote - ? [ - 'No Data Available for Remote Table', - 'If this is unexpected, please verify your settings.', - IconSettings, - () => navigate('/settings/integrations'), - 'Go to Settings', - ] - : [ - noExistingRecords - ? `Add your first ${objectLabel}` - : `No ${objectLabel} found`, - noExistingRecords - ? `Use our API or add your first ${objectLabel} manually` - : 'No records matching the filter criteria were found.', - IconPlus, - createRecord, - `Add a ${objectLabel}`, - ]; - - return ( - - - - {title} - - {subTitle} - - -