diff --git a/packages/twenty-front/src/modules/companies/components/HooksCompanyBoardEffect.tsx b/packages/twenty-front/src/modules/companies/components/HooksCompanyBoardEffect.tsx index df36cad89..7de6633ab 100644 --- a/packages/twenty-front/src/modules/companies/components/HooksCompanyBoardEffect.tsx +++ b/packages/twenty-front/src/modules/companies/components/HooksCompanyBoardEffect.tsx @@ -13,7 +13,6 @@ import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailab import { useSetRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useSetRecoilScopedStateV2'; import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewType } from '@/views/types/ViewType'; import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions'; type HooksCompanyBoardEffectProps = { @@ -30,7 +29,6 @@ export const HooksCompanyBoardEffect = ({ setAvailableSortDefinitions, setAvailableFieldDefinitions, setViewObjectMetadataId, - setViewType, } = useViewBar({ viewBarId }); const { objectMetadataItem } = useObjectMetadataItem({ @@ -75,8 +73,7 @@ export const HooksCompanyBoardEffect = ({ return; } setViewObjectMetadataId?.(objectMetadataItem.id); - setViewType?.(ViewType.Kanban); - }, [objectMetadataItem, setViewObjectMetadataId, setViewType]); + }, [objectMetadataItem, setViewObjectMetadataId]); const { currentViewFieldsState, 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 5b7cd7868..5a4dbc325 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 @@ -1,19 +1,19 @@ +import { useState } from 'react'; import styled from '@emotion/styled'; import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; 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 { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers'; +import { RecordIndexTableContainer } from '@/object-record/record-index/components/RecordIndexTableContainer'; +import { RecordIndexViewInitEffect } from '@/object-record/record-index/components/RecordIndexViewInitEffect'; 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'; import { useSpreadsheetPersonImport } from '@/people/hooks/useSpreadsheetPersonImport'; import { SpreadsheetImportProvider } from '@/spreadsheet-import/provider/components/SpreadsheetImportProvider'; import { ViewBar } from '@/views/components/ViewBar'; +import { ViewType } from '@/views/types/ViewType'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters'; import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts'; @@ -26,15 +26,21 @@ const StyledContainer = styled.div` padding-left: ${({ theme }) => theme.table.horizontalCellPadding}; `; -export const RecordIndexContainer = ({ - recordTableId, - objectNamePlural, - createRecord, -}: { - recordTableId: string; +type RecordIndexContainerProps = { + recordIndexId: string; objectNamePlural: string; - createRecord: () => void; -}) => { + createRecord: () => Promise; +}; + +export const RecordIndexContainer = ({ + createRecord, + recordIndexId, + objectNamePlural, +}: RecordIndexContainerProps) => { + const [recordIndexViewType, setRecordIndexViewType] = useState< + ViewType | undefined + >(undefined); + const { objectNameSingular } = useObjectNameSingularFromPlural({ objectNamePlural, }); @@ -46,26 +52,13 @@ export const RecordIndexContainer = ({ const { columnDefinitions } = useColumnDefinitionsFromFieldMetadata(objectMetadataItem); - const { updateOneRecord } = useUpdateOneRecord({ - objectNameSingular, - }); - const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport(); const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport(); - const viewBarId = objectNamePlural ?? ''; - const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({ - recordTableId, + recordTableId: recordIndexId, }); - const updateEntity = ({ variables }: RecordUpdateHookParams) => { - updateOneRecord?.({ - idToUpdate: variables.where.id as string, - updateOneRecordInput: variables.updateOneRecordInput, - }); - }; - const handleImport = () => { const openImport = objectNamePlural === 'companies' @@ -78,12 +71,12 @@ export const RecordIndexContainer = ({ { setTableSorts(mapViewSortsToSorts(viewSorts)); }} + onViewTypeChange={(viewType: ViewType) => { + setRecordIndexViewType(viewType); + }} /> - + )} + - ); 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 new file mode 100644 index 000000000..4cdd942bb --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexTableContainer.tsx @@ -0,0 +1,55 @@ +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'; + +type RecordIndexTableContainerProps = { + recordTableId: string; + viewBarId: string; + objectNamePlural: string; + createRecord: () => Promise; +}; + +export const RecordIndexTableContainer = ({ + recordTableId, + viewBarId, + objectNamePlural, + createRecord, +}: RecordIndexTableContainerProps) => { + const { objectNameSingular } = useObjectNameSingularFromPlural({ + objectNamePlural, + }); + + const { updateOneRecord } = useUpdateOneRecord({ + objectNameSingular, + }); + + const updateEntity = ({ variables }: RecordUpdateHookParams) => { + updateOneRecord?.({ + idToUpdate: variables.where.id as string, + updateOneRecordInput: variables.updateOneRecordInput, + }); + }; + + return ( + <> + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewInitEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewInitEffect.tsx new file mode 100644 index 000000000..8a93fd16c --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexViewInitEffect.tsx @@ -0,0 +1,53 @@ +import { useEffect } from 'react'; + +import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; +import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; +import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; +import { useViewBar } from '@/views/hooks/useViewBar'; + +export const RecordIndexViewInitEffect = ({ + objectNamePlural, + viewBarId, +}: { + objectNamePlural: string; + viewBarId: string; +}) => { + const { objectNameSingular } = useObjectNameSingularFromPlural({ + objectNamePlural, + }); + + const { objectMetadataItem } = useObjectMetadataItem({ + objectNameSingular, + }); + + const { columnDefinitions, filterDefinitions, sortDefinitions } = + useColumnDefinitionsFromFieldMetadata(objectMetadataItem); + + const { + setViewObjectMetadataId, + setAvailableSortDefinitions, + setAvailableFilterDefinitions, + setAvailableFieldDefinitions, + } = useViewBar({ viewBarId }); + + useEffect(() => { + if (!objectMetadataItem) { + return; + } + setViewObjectMetadataId?.(objectMetadataItem.id); + setAvailableSortDefinitions?.(sortDefinitions); + setAvailableFilterDefinitions?.(filterDefinitions); + setAvailableFieldDefinitions?.(columnDefinitions); + }, [ + setViewObjectMetadataId, + objectMetadataItem, + setAvailableSortDefinitions, + sortDefinitions, + setAvailableFilterDefinitions, + filterDefinitions, + setAvailableFieldDefinitions, + columnDefinitions, + ]); + + return <>; +}; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordTableEffect.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordTableEffect.tsx index b4725f2b6..8f8627e04 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordTableEffect.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordTableEffect.tsx @@ -7,7 +7,6 @@ import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecor import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns'; import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewType } from '@/views/types/ViewType'; export const RecordTableEffect = ({ objectNamePlural, @@ -39,14 +38,9 @@ export const RecordTableEffect = ({ const { columnDefinitions, filterDefinitions, sortDefinitions } = useColumnDefinitionsFromFieldMetadata(objectMetadataItem); - const { - setAvailableSortDefinitions, - setAvailableFilterDefinitions, - setAvailableFieldDefinitions, - setViewType, - setViewObjectMetadataId, - setEntityCountInCurrentView, - } = useViewBar({ viewBarId }); + const { setEntityCountInCurrentView } = useViewBar({ + viewBarId, + }); useEffect(() => { if (basePathToShowPage && labelIdentifierFieldMetadata) { @@ -63,28 +57,13 @@ export const RecordTableEffect = ({ ]); useEffect(() => { - if (!objectMetadataItem) { - return; - } - setViewObjectMetadataId?.(objectMetadataItem.id); - setViewType?.(ViewType.Table); - - setAvailableSortDefinitions?.(sortDefinitions); - setAvailableFilterDefinitions?.(filterDefinitions); - setAvailableFieldDefinitions?.(columnDefinitions); - const availableTableColumns = columnDefinitions.filter( filterAvailableTableColumns, ); setAvailableTableColumns(availableTableColumns); }, [ - setViewObjectMetadataId, - setViewType, columnDefinitions, - setAvailableSortDefinitions, - setAvailableFilterDefinitions, - setAvailableFieldDefinitions, objectMetadataItem, sortDefinitions, filterDefinitions, diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index 4b45219b7..1db63087e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -70,7 +70,7 @@ type RecordTableWithWrappersProps = { recordTableId: string; viewBarId: string; updateRecordMutation: (params: any) => void; - createRecord: () => void; + createRecord: () => Promise; }; export const RecordTableWithWrappers = ({ diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx index 8e18843fb..831b9956f 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainer.tsx @@ -36,7 +36,7 @@ export const SignInBackgroundMockContainer = () => { objectNamePlural={objectNamePlural} recordTableId={recordTableId} viewBarId={viewBarId} - createRecord={() => {}} + createRecord={async () => {}} updateRecordMutation={() => {}} /> diff --git a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx index 7d9622fc4..15b612541 100644 --- a/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx +++ b/packages/twenty-front/src/modules/sign-in-background-mock/components/SignInBackgroundMockContainerEffect.tsx @@ -12,7 +12,6 @@ import { } from '@/sign-in-background-mock/constants/signInBackgroundMockDefinitions'; import { signInBackgroundMockViewFields } from '@/sign-in-background-mock/constants/signInBackgroundMockViewFields'; import { useViewBar } from '@/views/hooks/useViewBar'; -import { ViewType } from '@/views/types/ViewType'; import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions'; type SignInBackgroundMockContainerEffectProps = { @@ -48,14 +47,12 @@ export const SignInBackgroundMockContainerEffect = ({ setAvailableSortDefinitions, setAvailableFilterDefinitions, setAvailableFieldDefinitions, - setViewType, setViewObjectMetadataId, setEntityCountInCurrentView, } = useViewBar({ viewBarId: viewId }); useEffect(() => { setViewObjectMetadataId?.(objectMetadataItem.id); - setViewType?.(ViewType.Table); setAvailableSortDefinitions?.(signInBackgroundMockSortDefinitions); setAvailableFilterDefinitions?.(signInBackgroundMockFilterDefinitions); @@ -75,7 +72,6 @@ export const SignInBackgroundMockContainerEffect = ({ ); }, [ setViewObjectMetadataId, - setViewType, setAvailableSortDefinitions, setAvailableFilterDefinitions, setAvailableFieldDefinitions, diff --git a/packages/twenty-front/src/modules/views/components/ViewBar.tsx b/packages/twenty-front/src/modules/views/components/ViewBar.tsx index 220c1af64..c695e77bf 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBar.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBar.tsx @@ -15,6 +15,7 @@ import { ViewScope } from '@/views/scopes/ViewScope'; import { ViewField } from '@/views/types/ViewField'; import { ViewFilter } from '@/views/types/ViewFilter'; import { ViewSort } from '@/views/types/ViewSort'; +import { ViewType } from '@/views/types/ViewType'; import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope'; @@ -30,6 +31,7 @@ export type ViewBarProps = { onViewSortsChange?: (sorts: ViewSort[]) => void | Promise; onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise; onViewFieldsChange?: (fields: ViewField[]) => void | Promise; + onViewTypeChange?: (viewType: ViewType) => void | Promise; }; export const ViewBar = ({ @@ -40,12 +42,13 @@ export const ViewBar = ({ onViewFieldsChange, onViewFiltersChange, onViewSortsChange, + onViewTypeChange, }: ViewBarProps) => { const { openDropdown: openOptionsDropdownButton } = useDropdown( optionsDropdownScopeId, ); const { upsertViewSort, upsertViewFilter } = useViewBar({ - viewBarId: viewBarId, + viewBarId, }); const { objectNamePlural } = useParams(); @@ -58,6 +61,7 @@ export const ViewBar = ({ onViewFieldsChange={onViewFieldsChange} onViewFiltersChange={onViewFiltersChange} onViewSortsChange={onViewSortsChange} + onViewTypeChange={onViewTypeChange} > { const [searchParams] = useSearchParams(); const currentViewIdFromUrl = searchParams.get('view'); - const { - viewTypeState, - viewObjectMetadataIdState, - viewsState, - currentViewIdState, - } = useViewScopedStates(); + const { viewObjectMetadataIdState, viewsState, currentViewIdState } = + useViewScopedStates(); const [views, setViews] = useRecoilState(viewsState); - const viewType = useRecoilValue(viewTypeState); const viewObjectMetadataId = useRecoilValue(viewObjectMetadataIdState); const setCurrentViewId = useSetRecoilState(currentViewIdState); @@ -38,7 +33,6 @@ export const ViewBarEffect = () => { skip: !viewObjectMetadataId, objectNameSingular: CoreObjectNameSingular.View, filter: { - type: { eq: viewType }, objectMetadataId: { eq: viewObjectMetadataId }, }, useRecordsWithoutConnection: true, @@ -80,10 +74,10 @@ export const ViewBarEffect = () => { ]); useEffect(() => { - if (!currentViewIdFromUrl) return; + if (!currentViewIdFromUrl || !newViews.length) return; loadView(currentViewIdFromUrl); - }, [currentViewIdFromUrl, loadView]); + }, [currentViewIdFromUrl, loadView, newViews]); return <>; }; diff --git a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx index d02864025..3170a5f27 100644 --- a/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx +++ b/packages/twenty-front/src/modules/views/hooks/__tests__/useViewBar.test.tsx @@ -22,8 +22,6 @@ import { ViewScope } from '@/views/scopes/ViewScope'; import { entityCountInCurrentViewScopedState } from '@/views/states/entityCountInCurrentViewScopedState'; import { viewEditModeScopedState } from '@/views/states/viewEditModeScopedState'; import { viewObjectMetadataIdScopeState } from '@/views/states/viewObjectMetadataIdScopeState'; -import { viewTypeScopedState } from '@/views/states/viewTypeScopedState'; -import { ViewType } from '@/views/types/ViewType'; jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => { return { @@ -225,25 +223,6 @@ describe('useViewBar', () => { expect(result.current.metadataId).toBe('newId'); }); - it('should update view type', async () => { - const { result } = renderHook( - () => ({ - viewBar: useViewBar({ viewBarId }), - ViewType: useRecoilState( - getScopedStateDeprecated(viewTypeScopedState, viewBarId), - )[0], - }), - renderHookConfig, - ); - - expect(result.current.ViewType).toBe('table'); - await act(async () => { - result.current.viewBar.setViewType(ViewType.Kanban); - }); - - expect(result.current.ViewType).toBe('kanban'); - }); - it('should update count in current view', async () => { const { result } = renderHook( () => ({ diff --git a/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts b/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts index bc2c90030..eb23061bc 100644 --- a/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts +++ b/packages/twenty-front/src/modules/views/hooks/internal/useViewScopedStates.ts @@ -40,6 +40,7 @@ export const useViewScopedStates = (args?: { viewScopeId?: string }) => { onViewFieldsChangeState, onViewFiltersChangeState, onViewSortsChangeState, + onViewTypeChangeState, savedViewFieldsByKeySelector, savedViewFieldsState, savedViewFiltersByKeySelector, @@ -72,6 +73,7 @@ export const useViewScopedStates = (args?: { viewScopeId?: string }) => { onViewFieldsChangeState, onViewFiltersChangeState, onViewSortsChangeState, + onViewTypeChangeState, savedViewFieldsByKeySelector, savedViewFieldsState, savedViewFiltersByKeySelector, diff --git a/packages/twenty-front/src/modules/views/hooks/useViewBar.ts b/packages/twenty-front/src/modules/views/hooks/useViewBar.ts index 73cc7cf92..a4b635457 100644 --- a/packages/twenty-front/src/modules/views/hooks/useViewBar.ts +++ b/packages/twenty-front/src/modules/views/hooks/useViewBar.ts @@ -43,7 +43,6 @@ export const useViewBar = (props?: UseViewProps) => { availableSortDefinitionsState, entityCountInCurrentViewState, viewObjectMetadataIdState, - viewTypeState, } = useViewScopedStates({ viewScopeId: scopeId, }); @@ -79,7 +78,6 @@ export const useViewBar = (props?: UseViewProps) => { const setViewEditMode = useSetRecoilState(viewEditModeState); const setViewObjectMetadataId = useSetRecoilState(viewObjectMetadataIdState); - const setViewType = useSetRecoilState(viewTypeState); const [_, setSearchParams] = useSearchParams(); @@ -237,16 +235,18 @@ export const useViewBar = (props?: UseViewProps) => { (viewId: string) => { setCurrentViewId?.(viewId); - const { currentView } = getViewScopedStateValuesFromSnapshot({ - snapshot, - viewScopeId: scopeId, - viewId, - }); + const { currentView, onViewTypeChange } = + getViewScopedStateValuesFromSnapshot({ + snapshot, + viewScopeId: scopeId, + viewId, + }); if (!currentView) { return; } + onViewTypeChange?.(currentView.type); loadViewFields(currentView.viewFields, viewId); loadViewFilters(currentView.viewFilters, viewId); loadViewSorts(currentView.viewSorts, viewId); @@ -418,7 +418,6 @@ export const useViewBar = (props?: UseViewProps) => { setViewEditMode, setViewObjectMetadataId, - setViewType, setEntityCountInCurrentView, setAvailableFieldDefinitions, diff --git a/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx b/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx index 287d95d7b..899d49ecc 100644 --- a/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx +++ b/packages/twenty-front/src/modules/views/scopes/ViewScope.tsx @@ -2,6 +2,7 @@ import { ReactNode } from 'react'; import { ViewFilter } from '@/views/types/ViewFilter'; import { ViewSort } from '@/views/types/ViewSort'; +import { ViewType } from '@/views/types/ViewType'; import { ViewField } from '../types/ViewField'; @@ -14,6 +15,7 @@ type ViewScopeProps = { onViewSortsChange?: (sorts: ViewSort[]) => void | Promise; onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise; onViewFieldsChange?: (fields: ViewField[]) => void | Promise; + onViewTypeChange?: (viewType: ViewType) => void | Promise; }; export const ViewScope = ({ @@ -22,6 +24,7 @@ export const ViewScope = ({ onViewSortsChange, onViewFiltersChange, onViewFieldsChange, + onViewTypeChange, }: ViewScopeProps) => { return ( {children} diff --git a/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx b/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx index 9199b4d7e..6ea16dbb2 100644 --- a/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx +++ b/packages/twenty-front/src/modules/views/scopes/init-effect/ViewScopeInitEffect.tsx @@ -5,40 +5,48 @@ import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates' import { ViewField } from '@/views/types/ViewField'; import { ViewFilter } from '@/views/types/ViewFilter'; import { ViewSort } from '@/views/types/ViewSort'; +import { ViewType } from '@/views/types/ViewType'; type ViewScopeInitEffectProps = { viewScopeId: string; onViewSortsChange?: (sorts: ViewSort[]) => void | Promise; onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise; onViewFieldsChange?: (fields: ViewField[]) => void | Promise; + onViewTypeChange?: (viewType: ViewType) => void | Promise; }; export const ViewScopeInitEffect = ({ onViewSortsChange, onViewFiltersChange, onViewFieldsChange, + onViewTypeChange, }: ViewScopeInitEffectProps) => { const { onViewFieldsChangeState, onViewFiltersChangeState, onViewSortsChangeState, + onViewTypeChangeState, } = useViewScopedStates(); const setOnViewSortsChange = useSetRecoilState(onViewSortsChangeState); const setOnViewFiltersChange = useSetRecoilState(onViewFiltersChangeState); const setOnViewFieldsChange = useSetRecoilState(onViewFieldsChangeState); + const setOnViewTypeChange = useSetRecoilState(onViewTypeChangeState); useEffect(() => { setOnViewSortsChange(() => onViewSortsChange); setOnViewFiltersChange(() => onViewFiltersChange); setOnViewFieldsChange(() => onViewFieldsChange); + setOnViewTypeChange(() => onViewTypeChange); }, [ onViewFieldsChange, onViewFiltersChange, onViewSortsChange, + onViewTypeChange, setOnViewFieldsChange, setOnViewFiltersChange, setOnViewSortsChange, + setOnViewTypeChange, ]); return <>; diff --git a/packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts b/packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts new file mode 100644 index 000000000..cc40b91ff --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/onViewTypeChangeScopedState.ts @@ -0,0 +1,9 @@ +import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap'; +import { ViewType } from '@/views/types/ViewType'; + +export const onViewTypeChangeScopedState = createStateScopeMap< + ((viewType: ViewType) => void | Promise) | undefined +>({ + key: 'onViewTypeChangeScopedState', + defaultValue: undefined, +}); diff --git a/packages/twenty-front/src/modules/views/types/GraphQLView.ts b/packages/twenty-front/src/modules/views/types/GraphQLView.ts index 4839989e6..5aa4d2e62 100644 --- a/packages/twenty-front/src/modules/views/types/GraphQLView.ts +++ b/packages/twenty-front/src/modules/views/types/GraphQLView.ts @@ -1,10 +1,12 @@ import { ViewField } from '@/views/types/ViewField'; import { ViewFilter } from '@/views/types/ViewFilter'; import { ViewSort } from '@/views/types/ViewSort'; +import { ViewType } from '@/views/types/ViewType'; export type GraphQLView = { id: string; name: string; + type: ViewType; objectMetadataId: string; viewFields: ViewField[]; viewFilters: ViewFilter[]; diff --git a/packages/twenty-front/src/modules/views/types/View.ts b/packages/twenty-front/src/modules/views/types/View.ts index e6506c2fa..7e9a043c0 100644 --- a/packages/twenty-front/src/modules/views/types/View.ts +++ b/packages/twenty-front/src/modules/views/types/View.ts @@ -1,5 +1,8 @@ +import { ViewType } from '@/views/types/ViewType'; + export type View = { id: string; name: string; objectMetadataId: string; + type: ViewType; }; diff --git a/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts b/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts index 7276dc306..4c01f475c 100644 --- a/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts +++ b/packages/twenty-front/src/modules/views/utils/getViewScopedStateValuesFromSnapshot.ts @@ -41,6 +41,7 @@ export const getViewScopedStateValuesFromSnapshot = ({ onViewFieldsChangeState, onViewFiltersChangeState, onViewSortsChangeState, + onViewTypeChangeState, savedViewFieldsByKeySelector, savedViewFieldsState, savedViewFiltersByKeySelector, @@ -85,6 +86,7 @@ export const getViewScopedStateValuesFromSnapshot = ({ onViewFieldsChange: getSnapshotValue(snapshot, onViewFieldsChangeState), onViewFiltersChange: getSnapshotValue(snapshot, onViewFiltersChangeState), onViewSortsChange: getSnapshotValue(snapshot, onViewSortsChangeState), + onViewTypeChange: getSnapshotValue(snapshot, onViewTypeChangeState), savedViewFieldsByKey: getSnapshotValue( snapshot, savedViewFieldsByKeySelector, diff --git a/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts b/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts index 12bf96b0c..42e0e4d01 100644 --- a/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts +++ b/packages/twenty-front/src/modules/views/utils/internal/getViewScopedStates.ts @@ -3,6 +3,7 @@ import { getScopedSelectorDeprecated } from '@/ui/utilities/recoil-scope/utils/g import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated'; import { currentViewIdScopedState } from '@/views/states/currentViewIdScopedState'; import { isPersistingViewScopedState } from '@/views/states/isPersistingViewScopedState'; +import { onViewTypeChangeScopedState } from '@/views/states/onViewTypeChangeScopedState'; import { currentViewScopedSelector } from '@/views/states/selectors/currentViewScopedSelector'; import { availableFieldDefinitionsScopedState } from '../../states/availableFieldDefinitionsScopedState'; @@ -164,6 +165,11 @@ export const getViewScopedStates = ({ viewScopeId, ); + const onViewTypeChangeState = getScopedStateDeprecated( + onViewTypeChangeScopedState, + viewScopeId, + ); + const currentViewIdState = getScopedStateDeprecated( currentViewIdScopedState, viewScopeId, @@ -207,5 +213,6 @@ export const getViewScopedStates = ({ onViewSortsChangeState, onViewFiltersChangeState, onViewFieldsChangeState, + onViewTypeChangeState, }; }; diff --git a/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx b/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx index 8bdac648a..5be68ead9 100644 --- a/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx +++ b/packages/twenty-front/src/pages/object-record/RecordIndexPage.tsx @@ -9,8 +9,6 @@ import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObj import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { RecordIndexContainer } from '@/object-record/record-index/components/RecordIndexContainer'; -import { RecordTableActionBar } from '@/object-record/record-table/action-bar/components/RecordTableActionBar'; -import { RecordTableContextMenu } from '@/object-record/record-table/context-menu/components/RecordTableContextMenu'; import { useSelectedTableCellEditMode } from '@/object-record/record-table/record-table-cell/hooks/useSelectedTableCellEditMode'; import { DEFAULT_CELL_SCOPE } from '@/object-record/record-table/record-table-cell/hooks/useTableCell'; import { useIcons } from '@/ui/display/icon/hooks/useIcons'; @@ -21,7 +19,7 @@ import { PageHeader } from '@/ui/layout/page/PageHeader'; import { PageHotkeysEffect } from '@/ui/layout/page/PageHotkeysEffect'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; -const StyledTableContainer = styled.div` +const StyledIndexContainer = styled.div` display: flex; height: 100%; width: 100%; @@ -59,12 +57,13 @@ export const RecordIndexPage = () => { objectNameSingular, }); - const recordTableId = objectNamePlural ?? ''; + const recordIndexId = objectNamePlural ?? ''; + + const setHotkeyScope = useSetHotkeyScope(); const { setSelectedTableCellEditMode } = useSelectedTableCellEditMode({ - scopeId: recordTableId, + scopeId: recordIndexId, }); - const setHotkeyScope = useSetHotkeyScope(); const handleAddButtonClick = async () => { await createOneObject?.({}); @@ -85,15 +84,13 @@ export const RecordIndexPage = () => { - + - - - + );