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:
@ -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">
|
||||
|
||||
@ -13,7 +13,7 @@ const meta: Meta<typeof PhoneInput> = {
|
||||
autoFocus: true,
|
||||
},
|
||||
parameters: {
|
||||
recoilScopeContext: TableRecoilScopeContext,
|
||||
customRecoilScopeContext: TableRecoilScopeContext,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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 }) =>
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -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 }) =>
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)),
|
||||
),
|
||||
});
|
||||
|
||||
@ -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>
|
||||
|
||||
Reference in New Issue
Block a user