From c3d6451dd03ab562b0904df21a7f00c141652108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Fri, 25 Aug 2023 12:43:21 +0200 Subject: [PATCH] feat: create view from selected filters and sorts + switch to newly created view on view creation (#1301) * feat: create view from selected filters and sorts Closes #1292 * refactor: use selector to obtain table filters where query option * refactor: activate exhaustive deps eslint rule for useRecoilCallback * feat: switch to newly created view on view creation Closes #1297 * refactor: code review - use `useCallback` instead of `useRecoilCallback` - rename `useTableViews` to `useViews` - move filter-n-sort selectors to /states/selector subfolder --- front/.eslintrc.js | 5 ++ front/src/generated/graphql.tsx | 80 +++++++++---------- .../table/components/CompanyTable.tsx | 29 ++++--- .../people/hooks/useSetPeopleEntityTable.ts | 2 +- .../people/table/components/PeopleTable.tsx | 29 ++++--- .../ui/board/hooks/useCurrentCardSelected.ts | 9 +-- ....ts => canPersistFiltersScopedSelector.ts} | 4 +- ...te.ts => canPersistSortsScopedSelector.ts} | 4 +- .../selectors/filtersWhereScopedSelector.ts | 13 +++ .../savedFiltersByKeyScopedSelector.ts | 5 +- .../savedSortsByKeyScopedSelector.ts | 5 +- .../sortsOrderByScopedSelector.ts | 5 +- .../ui/table/components/EntityTableHeader.tsx | 2 +- .../ui/table/hooks/useLeaveTableFocus.ts | 5 +- .../ui/table/hooks/useSetEntityTableData.ts | 2 +- .../TableOptionsDropdownContent.tsx | 74 +++++++++++------ .../components/TableUpdateViewButtonGroup.tsx | 2 +- .../components/TableViewsDropdownButton.tsx | 19 +++-- .../hotkey/hooks/usePreviousHotkeyScope.ts | 4 +- .../{deleteView.ts => deleteViews.ts} | 0 .../src/modules/views/hooks/useViewFilters.ts | 10 +-- front/src/modules/views/hooks/useViewSorts.ts | 10 +-- .../hooks/{useTableViews.ts => useViews.ts} | 77 ++++++++++++------ 23 files changed, 233 insertions(+), 162 deletions(-) rename front/src/modules/ui/filter-n-sort/states/selectors/{canPersistFiltersScopedState.ts => canPersistFiltersScopedSelector.ts} (80%) rename front/src/modules/ui/filter-n-sort/states/selectors/{canPersistSortsScopedState.ts => canPersistSortsScopedSelector.ts} (80%) create mode 100644 front/src/modules/ui/filter-n-sort/states/selectors/filtersWhereScopedSelector.ts rename front/src/modules/ui/filter-n-sort/states/{ => selectors}/savedFiltersByKeyScopedSelector.ts (75%) rename front/src/modules/ui/filter-n-sort/states/{ => selectors}/savedSortsByKeyScopedSelector.ts (74%) rename front/src/modules/ui/filter-n-sort/states/{ => selectors}/sortsOrderByScopedSelector.ts (69%) rename front/src/modules/views/graphql/mutations/{deleteView.ts => deleteViews.ts} (100%) rename front/src/modules/views/hooks/{useTableViews.ts => useViews.ts} (58%) diff --git a/front/.eslintrc.js b/front/.eslintrc.js index c86cd6f4f..fae639631 100644 --- a/front/.eslintrc.js +++ b/front/.eslintrc.js @@ -52,6 +52,11 @@ module.exports = { 'func-style':['error', 'declaration', { 'allowArrowFunctions': true }], "@typescript-eslint/no-unused-vars": "off", "no-unused-vars": "off", + "react-hooks/exhaustive-deps": [ + "warn", { + "additionalHooks": "useRecoilCallback" + } + ], "unused-imports/no-unused-imports": "warn", "unused-imports/no-unused-vars": [ "warn", diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index 2fc34cbe5..a784a978f 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -3415,13 +3415,6 @@ export type CreateViewsMutationVariables = Exact<{ export type CreateViewsMutation = { __typename?: 'Mutation', createManyView: { __typename?: 'AffectedRows', count: number } }; -export type DeleteViewsMutationVariables = Exact<{ - where: ViewWhereInput; -}>; - - -export type DeleteViewsMutation = { __typename?: 'Mutation', deleteManyView: { __typename?: 'AffectedRows', count: number } }; - export type DeleteViewFiltersMutationVariables = Exact<{ where: ViewFilterWhereInput; }>; @@ -3436,6 +3429,13 @@ export type DeleteViewSortsMutationVariables = Exact<{ export type DeleteViewSortsMutation = { __typename?: 'Mutation', deleteManyViewSort: { __typename?: 'AffectedRows', count: number } }; +export type DeleteViewsMutationVariables = Exact<{ + where: ViewWhereInput; +}>; + + +export type DeleteViewsMutation = { __typename?: 'Mutation', deleteManyView: { __typename?: 'AffectedRows', count: number } }; + export type UpdateViewMutationVariables = Exact<{ data: ViewUpdateInput; where: ViewWhereUniqueInput; @@ -6247,39 +6247,6 @@ export function useCreateViewsMutation(baseOptions?: Apollo.MutationHookOptions< export type CreateViewsMutationHookResult = ReturnType; export type CreateViewsMutationResult = Apollo.MutationResult; export type CreateViewsMutationOptions = Apollo.BaseMutationOptions; -export const DeleteViewsDocument = gql` - mutation DeleteViews($where: ViewWhereInput!) { - deleteManyView(where: $where) { - count - } -} - `; -export type DeleteViewsMutationFn = Apollo.MutationFunction; - -/** - * __useDeleteViewsMutation__ - * - * To run a mutation, you first call `useDeleteViewsMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useDeleteViewsMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [deleteViewsMutation, { data, loading, error }] = useDeleteViewsMutation({ - * variables: { - * where: // value for 'where' - * }, - * }); - */ -export function useDeleteViewsMutation(baseOptions?: Apollo.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(DeleteViewsDocument, options); - } -export type DeleteViewsMutationHookResult = ReturnType; -export type DeleteViewsMutationResult = Apollo.MutationResult; -export type DeleteViewsMutationOptions = Apollo.BaseMutationOptions; export const DeleteViewFiltersDocument = gql` mutation DeleteViewFilters($where: ViewFilterWhereInput!) { deleteManyViewFilter(where: $where) { @@ -6346,6 +6313,39 @@ export function useDeleteViewSortsMutation(baseOptions?: Apollo.MutationHookOpti export type DeleteViewSortsMutationHookResult = ReturnType; export type DeleteViewSortsMutationResult = Apollo.MutationResult; export type DeleteViewSortsMutationOptions = Apollo.BaseMutationOptions; +export const DeleteViewsDocument = gql` + mutation DeleteViews($where: ViewWhereInput!) { + deleteManyView(where: $where) { + count + } +} + `; +export type DeleteViewsMutationFn = Apollo.MutationFunction; + +/** + * __useDeleteViewsMutation__ + * + * To run a mutation, you first call `useDeleteViewsMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteViewsMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deleteViewsMutation, { data, loading, error }] = useDeleteViewsMutation({ + * variables: { + * where: // value for 'where' + * }, + * }); + */ +export function useDeleteViewsMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(DeleteViewsDocument, options); + } +export type DeleteViewsMutationHookResult = ReturnType; +export type DeleteViewsMutationResult = Apollo.MutationResult; +export type DeleteViewsMutationOptions = Apollo.BaseMutationOptions; export const UpdateViewDocument = gql` mutation UpdateView($data: ViewUpdateInput!, $where: ViewWhereUniqueInput!) { updateOneView(data: $data, where: $where) { diff --git a/front/src/modules/companies/table/components/CompanyTable.tsx b/front/src/modules/companies/table/components/CompanyTable.tsx index 7252ea024..91fc61c07 100644 --- a/front/src/modules/companies/table/components/CompanyTable.tsx +++ b/front/src/modules/companies/table/components/CompanyTable.tsx @@ -1,20 +1,19 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; import { companyViewFields } from '@/companies/constants/companyViewFields'; import { useCompanyTableActionBarEntries } from '@/companies/hooks/useCompanyTableActionBarEntries'; import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries'; import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport'; -import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState'; -import { sortsOrderByScopedSelector } from '@/ui/filter-n-sort/states/sortsOrderByScopedSelector'; -import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause'; +import { filtersWhereScopedSelector } from '@/ui/filter-n-sort/states/selectors/filtersWhereScopedSelector'; +import { sortsOrderByScopedSelector } from '@/ui/filter-n-sort/states/selectors/sortsOrderByScopedSelector'; import { EntityTable } from '@/ui/table/components/EntityTable'; import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData'; import { useUpsertEntityTableItem } from '@/ui/table/hooks/useUpsertEntityTableItem'; import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext'; import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; import { useTableViewFields } from '@/views/hooks/useTableViewFields'; -import { useTableViews } from '@/views/hooks/useTableViews'; import { useViewFilters } from '@/views/hooks/useViewFilters'; +import { useViews } from '@/views/hooks/useViews'; import { useViewSorts } from '@/views/hooks/useViewSorts'; import { SortOrder, @@ -30,11 +29,20 @@ export function CompanyTable() { sortsOrderByScopedSelector, TableRecoilScopeContext, ); + const whereFilters = useRecoilScopedValue( + filtersWhereScopedSelector, + TableRecoilScopeContext, + ); + const [updateEntityMutation] = useUpdateOneCompanyMutation(); const upsertEntityTableItem = useUpsertEntityTableItem(); const objectId = 'company'; - const { handleViewsChange } = useTableViews({ objectId }); + const { handleViewsChange } = useViews({ + availableFilters: companiesFilters, + availableSorts, + objectId, + }); const { handleColumnsChange } = useTableViewFields({ objectName: objectId, viewFieldDefinitions: companyViewFields, @@ -46,15 +54,6 @@ export function CompanyTable() { const { persistSorts } = useViewSorts({ availableSorts }); const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport(); - const filters = useRecoilScopedValue( - filtersScopedState, - TableRecoilScopeContext, - ); - - const whereFilters = useMemo(() => { - return { AND: filters.map(turnFilterIntoWhereClause) }; - }, [filters]) as any; - const { setContextMenuEntries } = useCompanyTableContextMenuEntries(); const { setActionBarEntries } = useCompanyTableActionBarEntries(); diff --git a/front/src/modules/people/hooks/useSetPeopleEntityTable.ts b/front/src/modules/people/hooks/useSetPeopleEntityTable.ts index b2dd3df25..22b2754cc 100644 --- a/front/src/modules/people/hooks/useSetPeopleEntityTable.ts +++ b/front/src/modules/people/hooks/useSetPeopleEntityTable.ts @@ -132,6 +132,6 @@ export function useSetPeopleEntityTable() { set(isFetchingEntityTableDataState, false); }, - [], + [currentLocation, resetTableRowSelection, tableContextScopeId], ); } diff --git a/front/src/modules/people/table/components/PeopleTable.tsx b/front/src/modules/people/table/components/PeopleTable.tsx index 29e2c40b9..17460939e 100644 --- a/front/src/modules/people/table/components/PeopleTable.tsx +++ b/front/src/modules/people/table/components/PeopleTable.tsx @@ -1,20 +1,19 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; import { peopleViewFields } from '@/people/constants/peopleViewFields'; import { usePersonTableContextMenuEntries } from '@/people/hooks/usePeopleTableContextMenuEntries'; import { usePersonTableActionBarEntries } from '@/people/hooks/usePersonTableActionBarEntries'; import { useSpreadsheetPersonImport } from '@/people/hooks/useSpreadsheetPersonImport'; -import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState'; -import { sortsOrderByScopedSelector } from '@/ui/filter-n-sort/states/sortsOrderByScopedSelector'; -import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause'; +import { filtersWhereScopedSelector } from '@/ui/filter-n-sort/states/selectors/filtersWhereScopedSelector'; +import { sortsOrderByScopedSelector } from '@/ui/filter-n-sort/states/selectors/sortsOrderByScopedSelector'; import { EntityTable } from '@/ui/table/components/EntityTable'; import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData'; import { useUpsertEntityTableItem } from '@/ui/table/hooks/useUpsertEntityTableItem'; import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext'; import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; import { useTableViewFields } from '@/views/hooks/useTableViewFields'; -import { useTableViews } from '@/views/hooks/useTableViews'; import { useViewFilters } from '@/views/hooks/useViewFilters'; +import { useViews } from '@/views/hooks/useViews'; import { useViewSorts } from '@/views/hooks/useViewSorts'; import { SortOrder, @@ -30,12 +29,21 @@ export function PeopleTable() { sortsOrderByScopedSelector, TableRecoilScopeContext, ); + const whereFilters = useRecoilScopedValue( + filtersWhereScopedSelector, + TableRecoilScopeContext, + ); + const [updateEntityMutation] = useUpdateOnePersonMutation(); const upsertEntityTableItem = useUpsertEntityTableItem(); const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport(); const objectId = 'person'; - const { handleViewsChange } = useTableViews({ objectId }); + const { handleViewsChange } = useViews({ + availableFilters: peopleFilters, + availableSorts, + objectId, + }); const { handleColumnsChange } = useTableViewFields({ objectName: objectId, viewFieldDefinitions: peopleViewFields, @@ -45,15 +53,6 @@ export function PeopleTable() { }); const { persistSorts } = useViewSorts({ availableSorts }); - const filters = useRecoilScopedValue( - filtersScopedState, - TableRecoilScopeContext, - ); - - const whereFilters = useMemo(() => { - return { AND: filters.map(turnFilterIntoWhereClause) }; - }, [filters]) as any; - const { setContextMenuEntries } = usePersonTableContextMenuEntries(); const { setActionBarEntries } = usePersonTableActionBarEntries(); diff --git a/front/src/modules/ui/board/hooks/useCurrentCardSelected.ts b/front/src/modules/ui/board/hooks/useCurrentCardSelected.ts index 2f13c04fe..38fb0c07f 100644 --- a/front/src/modules/ui/board/hooks/useCurrentCardSelected.ts +++ b/front/src/modules/ui/board/hooks/useCurrentCardSelected.ts @@ -1,5 +1,5 @@ import { useContext } from 'react'; -import { useRecoilCallback, useRecoilState, useSetRecoilState } from 'recoil'; +import { useRecoilCallback, useRecoilValue } from 'recoil'; import { actionBarOpenState } from '@/ui/action-bar/states/actionBarIsOpenState'; @@ -9,10 +9,9 @@ import { isCardSelectedFamilyState } from '../states/isCardSelectedFamilyState'; export function useCurrentCardSelected() { const currentCardId = useContext(BoardCardIdContext); - const [isCardSelected] = useRecoilState( + const isCardSelected = useRecoilValue( isCardSelectedFamilyState(currentCardId ?? ''), ); - const setActionBarOpenState = useSetRecoilState(actionBarOpenState); const setCurrentCardSelected = useRecoilCallback( ({ set }) => @@ -20,9 +19,9 @@ export function useCurrentCardSelected() { if (!currentCardId) return; set(isCardSelectedFamilyState(currentCardId), selected); - setActionBarOpenState(true); + set(actionBarOpenState, true); }, - [], + [currentCardId], ); return { diff --git a/front/src/modules/ui/filter-n-sort/states/selectors/canPersistFiltersScopedState.ts b/front/src/modules/ui/filter-n-sort/states/selectors/canPersistFiltersScopedSelector.ts similarity index 80% rename from front/src/modules/ui/filter-n-sort/states/selectors/canPersistFiltersScopedState.ts rename to front/src/modules/ui/filter-n-sort/states/selectors/canPersistFiltersScopedSelector.ts index 27e205dcd..76bc17d79 100644 --- a/front/src/modules/ui/filter-n-sort/states/selectors/canPersistFiltersScopedState.ts +++ b/front/src/modules/ui/filter-n-sort/states/selectors/canPersistFiltersScopedSelector.ts @@ -5,8 +5,8 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { filtersScopedState } from '../filtersScopedState'; import { savedFiltersScopedState } from '../savedFiltersScopedState'; -export const canPersistFiltersScopedState = selectorFamily({ - key: 'canPersistFiltersScopedState', +export const canPersistFiltersScopedSelector = selectorFamily({ + key: 'canPersistFiltersScopedSelector', get: ([scopeId, viewId]: [string, string | undefined]) => ({ get }) => diff --git a/front/src/modules/ui/filter-n-sort/states/selectors/canPersistSortsScopedState.ts b/front/src/modules/ui/filter-n-sort/states/selectors/canPersistSortsScopedSelector.ts similarity index 80% rename from front/src/modules/ui/filter-n-sort/states/selectors/canPersistSortsScopedState.ts rename to front/src/modules/ui/filter-n-sort/states/selectors/canPersistSortsScopedSelector.ts index 12c420b39..2b50ebce5 100644 --- a/front/src/modules/ui/filter-n-sort/states/selectors/canPersistSortsScopedState.ts +++ b/front/src/modules/ui/filter-n-sort/states/selectors/canPersistSortsScopedSelector.ts @@ -5,8 +5,8 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { savedSortsScopedState } from '../savedSortsScopedState'; import { sortsScopedState } from '../sortsScopedState'; -export const canPersistSortsScopedState = selectorFamily({ - key: 'canPersistSortsScopedState', +export const canPersistSortsScopedSelector = selectorFamily({ + key: 'canPersistSortsScopedSelector', get: ([scopeId, viewId]: [string, string | undefined]) => ({ get }) => diff --git a/front/src/modules/ui/filter-n-sort/states/selectors/filtersWhereScopedSelector.ts b/front/src/modules/ui/filter-n-sort/states/selectors/filtersWhereScopedSelector.ts new file mode 100644 index 000000000..e23d517d0 --- /dev/null +++ b/front/src/modules/ui/filter-n-sort/states/selectors/filtersWhereScopedSelector.ts @@ -0,0 +1,13 @@ +import { selectorFamily } from 'recoil'; + +import { turnFilterIntoWhereClause } from '../../utils/turnFilterIntoWhereClause'; +import { filtersScopedState } from '../filtersScopedState'; + +export const filtersWhereScopedSelector = selectorFamily({ + key: 'filtersWhereScopedSelector', + get: + (param: string) => + ({ get }) => ({ + AND: get(filtersScopedState(param)).map(turnFilterIntoWhereClause), + }), +}); diff --git a/front/src/modules/ui/filter-n-sort/states/savedFiltersByKeyScopedSelector.ts b/front/src/modules/ui/filter-n-sort/states/selectors/savedFiltersByKeyScopedSelector.ts similarity index 75% rename from front/src/modules/ui/filter-n-sort/states/savedFiltersByKeyScopedSelector.ts rename to front/src/modules/ui/filter-n-sort/states/selectors/savedFiltersByKeyScopedSelector.ts index 0f797d22e..253e1d15d 100644 --- a/front/src/modules/ui/filter-n-sort/states/savedFiltersByKeyScopedSelector.ts +++ b/front/src/modules/ui/filter-n-sort/states/selectors/savedFiltersByKeyScopedSelector.ts @@ -1,8 +1,7 @@ import { selectorFamily } from 'recoil'; -import type { Filter } from '../types/Filter'; - -import { savedFiltersScopedState } from './savedFiltersScopedState'; +import type { Filter } from '../../types/Filter'; +import { savedFiltersScopedState } from '../savedFiltersScopedState'; export const savedFiltersByKeyScopedSelector = selectorFamily({ key: 'savedFiltersByKeyScopedSelector', diff --git a/front/src/modules/ui/filter-n-sort/states/savedSortsByKeyScopedSelector.ts b/front/src/modules/ui/filter-n-sort/states/selectors/savedSortsByKeyScopedSelector.ts similarity index 74% rename from front/src/modules/ui/filter-n-sort/states/savedSortsByKeyScopedSelector.ts rename to front/src/modules/ui/filter-n-sort/states/selectors/savedSortsByKeyScopedSelector.ts index 5e9971fe5..83873e92c 100644 --- a/front/src/modules/ui/filter-n-sort/states/savedSortsByKeyScopedSelector.ts +++ b/front/src/modules/ui/filter-n-sort/states/selectors/savedSortsByKeyScopedSelector.ts @@ -1,8 +1,7 @@ import { selectorFamily } from 'recoil'; -import type { SelectedSortType } from '../types/interface'; - -import { savedSortsScopedState } from './savedSortsScopedState'; +import type { SelectedSortType } from '../../types/interface'; +import { savedSortsScopedState } from '../savedSortsScopedState'; export const savedSortsByKeyScopedSelector = selectorFamily({ key: 'savedSortsByKeyScopedSelector', diff --git a/front/src/modules/ui/filter-n-sort/states/sortsOrderByScopedSelector.ts b/front/src/modules/ui/filter-n-sort/states/selectors/sortsOrderByScopedSelector.ts similarity index 69% rename from front/src/modules/ui/filter-n-sort/states/sortsOrderByScopedSelector.ts rename to front/src/modules/ui/filter-n-sort/states/selectors/sortsOrderByScopedSelector.ts index 7ae4e80f1..dc2e2e8b0 100644 --- a/front/src/modules/ui/filter-n-sort/states/sortsOrderByScopedSelector.ts +++ b/front/src/modules/ui/filter-n-sort/states/selectors/sortsOrderByScopedSelector.ts @@ -1,8 +1,7 @@ import { selectorFamily } from 'recoil'; -import { reduceSortsToOrderBy } from '../helpers'; - -import { sortsScopedState } from './sortsScopedState'; +import { reduceSortsToOrderBy } from '../../helpers'; +import { sortsScopedState } from '../sortsScopedState'; export const sortsOrderByScopedSelector = selectorFamily({ key: 'sortsOrderByScopedSelector', diff --git a/front/src/modules/ui/table/components/EntityTableHeader.tsx b/front/src/modules/ui/table/components/EntityTableHeader.tsx index a5000b8bd..d5b1b25c2 100644 --- a/front/src/modules/ui/table/components/EntityTableHeader.tsx +++ b/front/src/modules/ui/table/components/EntityTableHeader.tsx @@ -136,7 +136,7 @@ export function EntityTableHeader({ onColumnsChange }: EntityTableHeaderProps) { setInitialPointerPositionX(null); setResizedFieldId(null); }, - [resizedFieldId, columnsById, setResizedFieldId], + [resizedFieldId, columnsById, columns, onColumnsChange, setColumns], ); useTrackPointer({ diff --git a/front/src/modules/ui/table/hooks/useLeaveTableFocus.ts b/front/src/modules/ui/table/hooks/useLeaveTableFocus.ts index a551f0961..0ec996ed8 100644 --- a/front/src/modules/ui/table/hooks/useLeaveTableFocus.ts +++ b/front/src/modules/ui/table/hooks/useLeaveTableFocus.ts @@ -1,6 +1,5 @@ import { useRecoilCallback } from 'recoil'; -import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState'; @@ -13,8 +12,6 @@ export function useLeaveTableFocus() { const disableSoftFocus = useDisableSoftFocus(); const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode(); - const setHotkeyScope = useSetHotkeyScope(); - return useRecoilCallback( ({ snapshot }) => () => { @@ -37,6 +34,6 @@ export function useLeaveTableFocus() { closeCurrentCellInEditMode(); disableSoftFocus(); }, - [setHotkeyScope, closeCurrentCellInEditMode, disableSoftFocus], + [closeCurrentCellInEditMode, disableSoftFocus], ); } diff --git a/front/src/modules/ui/table/hooks/useSetEntityTableData.ts b/front/src/modules/ui/table/hooks/useSetEntityTableData.ts index e0d6a5716..d769de562 100644 --- a/front/src/modules/ui/table/hooks/useSetEntityTableData.ts +++ b/front/src/modules/ui/table/hooks/useSetEntityTableData.ts @@ -50,6 +50,6 @@ export function useSetEntityTableData() { set(isFetchingEntityTableDataState, false); }, - [], + [resetTableRowSelection, tableContextScopeId], ); } diff --git a/front/src/modules/ui/table/options/components/TableOptionsDropdownContent.tsx b/front/src/modules/ui/table/options/components/TableOptionsDropdownContent.tsx index 3f4073c9b..4c951e0f6 100644 --- a/front/src/modules/ui/table/options/components/TableOptionsDropdownContent.tsx +++ b/front/src/modules/ui/table/options/components/TableOptionsDropdownContent.tsx @@ -1,6 +1,6 @@ import { type FormEvent, useCallback, useRef, useState } from 'react'; import { useTheme } from '@emotion/react'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil'; import { Key } from 'ts-key-enum'; import { v4 } from 'uuid'; @@ -16,6 +16,10 @@ import type { ViewFieldDefinition, ViewFieldMetadata, } from '@/ui/editable-field/types/ViewField'; +import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState'; +import { savedFiltersScopedState } from '@/ui/filter-n-sort/states/savedFiltersScopedState'; +import { savedSortsScopedState } from '@/ui/filter-n-sort/states/savedSortsScopedState'; +import { sortsScopedState } from '@/ui/filter-n-sort/states/sortsScopedState'; import { IconChevronLeft, IconFileImport, @@ -29,11 +33,12 @@ import { visibleTableColumnsState, } from '@/ui/table/states/tableColumnsState'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; -import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState'; +import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId'; import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext'; import { + currentTableViewIdState, type TableView, tableViewEditModeState, tableViewsByIdState, @@ -60,6 +65,8 @@ export function TableOptionsDropdownContent({ }: TableOptionsDropdownButtonProps) { const theme = useTheme(); + const tableScopeId = useContextScopeId(TableRecoilScopeContext); + const { closeDropdownButton } = useDropdownButton({ key: 'options' }); const [selectedOption, setSelectedOption] = useState