Refactor/context and scopes (#1602)

* Put onImport in a context

* Refactored RecoilScopeContexts

* Refactored naming

* Fix tests

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Lucas Bordeau
2023-09-15 21:51:46 +02:00
committed by GitHub
parent d07474ece7
commit 0a7a0ac6cb
102 changed files with 639 additions and 552 deletions

View File

@ -14,10 +14,7 @@ import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
import { useResetTableRowSelection } from '../hooks/useResetTableRowSelection';
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
import {
TableHeader,
type TableHeaderProps,
} from '../table-header/components/TableHeader';
import { TableHeader } from '../table-header/components/TableHeader';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { EntityTableBody } from './EntityTableBody';
@ -87,9 +84,9 @@ const StyledTableContainer = styled.div`
type OwnProps = {
updateEntityMutation: any;
} & Pick<TableHeaderProps, 'onImport'>;
};
export function EntityTable({ onImport, updateEntityMutation }: OwnProps) {
export function EntityTable({ updateEntityMutation }: OwnProps) {
const tableBodyRef = useRef<HTMLDivElement>(null);
const setRowSelectedState = useSetRowSelectedState();
@ -126,7 +123,7 @@ export function EntityTable({ onImport, updateEntityMutation }: OwnProps) {
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
<StyledTableWithHeader>
<StyledTableContainer ref={tableBodyRef}>
<TableHeader onImport={onImport} />
<TableHeader />
<ScrollWrapper>
<div>
<StyledTable className="entity-table-cell">

View File

@ -13,7 +13,7 @@ const meta: Meta<typeof PhoneInput> = {
autoFocus: true,
},
parameters: {
recoilScopeContext: TableRecoilScopeContext,
customRecoilScopeContext: TableRecoilScopeContext,
},
};

View File

@ -1,6 +1,6 @@
import { useRecoilCallback } from 'recoil';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
@ -11,7 +11,7 @@ import { useSetSoftFocusPosition } from './useSetSoftFocusPosition';
// TODO: stories
export function useMoveSoftFocus() {
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
const tableScopeId = useRecoilScopeId(TableRecoilScopeContext);
const setSoftFocusPosition = useSetSoftFocusPosition();
const moveUp = useRecoilCallback(

View File

@ -4,7 +4,7 @@ import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSele
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { tableEntitiesFamilyState } from '@/ui/table/states/tableEntitiesFamilyState';
import { tableRowIdsState } from '@/ui/table/states/tableRowIdsState';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { availableFiltersScopedState } from '@/ui/view-bar/states/availableFiltersScopedState';
import { availableSortsScopedState } from '@/ui/view-bar/states/availableSortsScopedState';
import { FilterDefinition } from '@/ui/view-bar/types/FilterDefinition';
@ -16,7 +16,7 @@ import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
export function useSetEntityTableData() {
const resetTableRowSelection = useResetTableRowSelection();
const tableContextScopeId = useContextScopeId(TableRecoilScopeContext);
const tableContextScopeId = useRecoilScopeId(TableRecoilScopeContext);
return useRecoilCallback(
({ set, snapshot }) =>

View File

@ -10,12 +10,10 @@ import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
type TableOptionsDropdownProps = {
onImport?: () => void;
customHotkeyScope: HotkeyScope;
};
export function TableOptionsDropdown({
onImport,
customHotkeyScope,
}: TableOptionsDropdownProps) {
const resetViewEditMode = useResetRecoilState(viewEditModeState);
@ -25,7 +23,7 @@ export function TableOptionsDropdown({
buttonComponents={<TableOptionsDropdownButton />}
dropdownHotkeyScope={customHotkeyScope}
dropdownId={TableOptionsDropdownId}
dropdownComponents={<TableOptionsDropdownContent onImport={onImport} />}
dropdownComponents={<TableOptionsDropdownContent />}
onClickOutside={resetViewEditMode}
/>
);

View File

@ -1,4 +1,4 @@
import { useRef, useState } from 'react';
import { useContext, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { useRecoilCallback, useRecoilValue, useResetRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
@ -13,9 +13,10 @@ import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { rgba } from '@/ui/theme/constants/colors';
import { textInputStyle } from '@/ui/theme/constants/effects';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewFieldsVisibilityDropdownSection } from '@/ui/view-bar/components/ViewFieldsVisibilityDropdownSection';
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
import { useUpsertView } from '@/ui/view-bar/hooks/useUpsertView';
import { currentViewScopedSelector } from '@/ui/view-bar/states/selectors/currentViewScopedSelector';
import { viewsByIdScopedSelector } from '@/ui/view-bar/states/selectors/viewsByIdScopedSelector';
@ -30,10 +31,6 @@ import { visibleTableColumnsScopedSelector } from '../../states/selectors/visibl
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
type TableOptionsDropdownButtonProps = {
onImport?: () => void;
};
type TableOptionsMenu = 'fields';
const StyledInputContainer = styled.div`
@ -59,11 +56,10 @@ const StyledViewNameInput = styled.input`
}
`;
export function TableOptionsDropdownContent({
onImport,
}: TableOptionsDropdownButtonProps) {
const scopeId = useContextScopeId(TableRecoilScopeContext);
export function TableOptionsDropdownContent() {
const scopeId = useRecoilScopeId(TableRecoilScopeContext);
const { onImport } = useContext(ViewBarContext);
const { closeDropdownButton } = useDropdownButton({
dropdownId: TableOptionsDropdownId,
});
@ -95,9 +91,7 @@ export function TableOptionsDropdownContent({
const { handleColumnVisibilityChange } = useTableColumns();
const { upsertView } = useUpsertView({
scopeContext: TableRecoilScopeContext,
});
const { upsertView } = useUpsertView();
const handleViewNameSubmit = useRecoilCallback(
({ set, snapshot }) =>

View File

@ -3,6 +3,7 @@ import { userEvent, within } from '@storybook/testing-library';
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { TableRecoilScopeContext } from '../../../states/recoil-scope-contexts/TableRecoilScopeContext';
@ -13,10 +14,16 @@ const meta: Meta<typeof TableOptionsDropdown> = {
component: TableOptionsDropdown,
decorators: [
(Story) => (
<RecoilScope SpecificContext={TableRecoilScopeContext}>
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
<Story />
</RecoilScope>
<RecoilScope CustomRecoilScopeContext={TableRecoilScopeContext}>
<ViewBarContext.Provider
value={{
ViewBarRecoilScopeContext: TableRecoilScopeContext,
}}
>
<RecoilScope CustomRecoilScopeContext={DropdownRecoilScopeContext}>
<Story />
</RecoilScope>
</ViewBarContext.Provider>
</RecoilScope>
),
ComponentDecorator,

View File

@ -8,10 +8,16 @@ import { tableColumnsScopedState } from '../tableColumnsScopedState';
export const canPersistTableColumnsScopedFamilySelector = selectorFamily({
key: 'canPersistTableColumnsScopedFamilySelector',
get:
([scopeId, viewId]: [string, string | undefined]) =>
({
recoilScopeId,
viewId,
}: {
recoilScopeId: string;
viewId: string | undefined;
}) =>
({ get }) =>
!isDeeplyEqual(
get(savedTableColumnsFamilyState(viewId)),
get(tableColumnsScopedState(scopeId)),
get(tableColumnsScopedState(recoilScopeId)),
),
});

View File

@ -3,9 +3,9 @@ import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewBar } from '@/ui/view-bar/components/ViewBar';
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
@ -18,21 +18,20 @@ import { canPersistTableColumnsScopedFamilySelector } from '../../states/selecto
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
export type TableHeaderProps = {
onImport?: () => void;
};
export function TableHeader({ onImport }: TableHeaderProps) {
export function TableHeader() {
const { onCurrentViewSubmit, ...viewBarContextProps } =
useContext(ViewBarContext);
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
const tableRecoilScopeId = useRecoilScopeId(TableRecoilScopeContext);
const currentViewId = useRecoilScopedValue(
currentViewIdScopedState,
TableRecoilScopeContext,
);
const canPersistTableColumns = useRecoilValue(
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
canPersistTableColumnsScopedFamilySelector({
recoilScopeId: tableRecoilScopeId,
viewId: currentViewId,
}),
);
const [tableColumns, setTableColumns] = useRecoilScopedState(
tableColumnsScopedState,
@ -50,9 +49,9 @@ export function TableHeader({ onImport }: TableHeaderProps) {
const savedTableColumns = await snapshot.getPromise(
savedTableColumnsFamilyState(viewId),
);
set(tableColumnsScopedState(tableScopeId), savedTableColumns);
set(tableColumnsScopedState(tableRecoilScopeId), savedTableColumns);
},
[tableScopeId],
[tableRecoilScopeId],
);
async function handleCurrentViewSubmit() {
@ -64,7 +63,7 @@ export function TableHeader({ onImport }: TableHeaderProps) {
}
return (
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
<RecoilScope CustomRecoilScopeContext={DropdownRecoilScopeContext}>
<ViewBarContext.Provider
value={{
...viewBarContextProps,
@ -77,12 +76,10 @@ export function TableHeader({ onImport }: TableHeaderProps) {
<ViewBar
optionsDropdownButton={
<TableOptionsDropdown
onImport={onImport}
customHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
/>
}
optionsDropdownKey={TableOptionsDropdownId}
scopeContext={TableRecoilScopeContext}
/>
</ViewBarContext.Provider>
</RecoilScope>