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,7 +14,7 @@ const meta: Meta<typeof CompanyBoard> = {
component: CompanyBoard,
decorators: [
(Story) => (
<RecoilScope SpecificContext={CompanyBoardRecoilScopeContext}>
<RecoilScope CustomRecoilScopeContext={CompanyBoardRecoilScopeContext}>
<HooksCompanyBoardEffect />
<MemoryRouter>
<Story />

View File

@ -15,6 +15,7 @@ import { graphqlMocks } from '~/testing/graphqlMocks';
import { mockedPipelineProgressData } from '~/testing/mock-data/pipeline-progress';
import { HooksCompanyBoardEffect } from '../components/HooksCompanyBoardEffect';
import { BoardContext } from '../states/contexts/BoardContext';
import { CompanyBoardRecoilScopeContext } from '../states/recoil-scope-contexts/CompanyBoardRecoilScopeContext';
const meta: Meta<typeof CompanyBoardCard> = {
@ -24,7 +25,7 @@ const meta: Meta<typeof CompanyBoardCard> = {
(Story, context) => {
const [, setBoardCardFields] = useRecoilScopedState(
boardCardFieldsScopedState,
context.parameters.recoilScopeContext,
context.parameters.customRecoilScopeContext,
);
useEffect(() => {
@ -32,9 +33,14 @@ const meta: Meta<typeof CompanyBoardCard> = {
}, [setBoardCardFields]);
return (
<>
<HooksCompanyBoardEffect />
<RecoilScope SpecificContext={BoardColumnRecoilScopeContext}>
<RecoilScope CustomRecoilScopeContext={BoardColumnRecoilScopeContext}>
<BoardContext.Provider
value={{
BoardRecoilScopeContext:
context.parameters.customRecoilScopeContext,
}}
>
<HooksCompanyBoardEffect />
<BoardCardIdContext.Provider
value={mockedPipelineProgressData[1].id}
>
@ -42,18 +48,18 @@ const meta: Meta<typeof CompanyBoardCard> = {
<Story />
</MemoryRouter>
</BoardCardIdContext.Provider>
</RecoilScope>
</>
</BoardContext.Provider>
</RecoilScope>
);
},
ComponentWithRecoilScopeDecorator,
ComponentDecorator,
],
args: { scopeContext: CompanyBoardRecoilScopeContext },
argTypes: { scopeContext: { control: false } },
args: {},
argTypes: {},
parameters: {
msw: graphqlMocks,
recoilScopeContext: CompanyBoardRecoilScopeContext,
customRecoilScopeContext: CompanyBoardRecoilScopeContext,
},
};

View File

@ -1,3 +1,4 @@
import { BoardContext } from '@/companies/states/contexts/BoardContext';
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
import {
EntityBoard,
@ -22,35 +23,43 @@ export const CompanyBoard = ({
onColumnDelete,
onEditColumnTitle,
}: CompanyBoardProps) => {
// TODO: we can store objectId and fieldDefinitions in the ViewBarContext
// And then use the useBoardViews hook wherever we need it in the board
const { createView, deleteView, submitCurrentView, updateView } =
useBoardViews({
objectId: 'company',
scopeContext: CompanyBoardRecoilScopeContext,
RecoilScopeContext: CompanyBoardRecoilScopeContext,
fieldDefinitions: pipelineAvailableFieldDefinitions,
});
return (
<>
<HooksCompanyBoardEffect />
<ViewBarContext.Provider
<BoardContext.Provider
value={{
defaultViewName: 'All Opportunities',
onCurrentViewSubmit: submitCurrentView,
onViewCreate: createView,
onViewEdit: updateView,
onViewRemove: deleteView,
BoardRecoilScopeContext: CompanyBoardRecoilScopeContext,
}}
>
<EntityBoard
boardOptions={opportunitiesBoardOptions}
onColumnAdd={onColumnAdd}
onColumnDelete={onColumnDelete}
onEditColumnTitle={onEditColumnTitle}
scopeContext={CompanyBoardRecoilScopeContext}
/>
</ViewBarContext.Provider>
<EntityBoardActionBar />
<EntityBoardContextMenu />
<HooksCompanyBoardEffect />
<ViewBarContext.Provider
value={{
defaultViewName: 'All Opportunities',
onCurrentViewSubmit: submitCurrentView,
onViewCreate: createView,
onViewEdit: updateView,
onViewRemove: deleteView,
ViewBarRecoilScopeContext: CompanyBoardRecoilScopeContext,
}}
>
<EntityBoard
boardOptions={opportunitiesBoardOptions}
onColumnAdd={onColumnAdd}
onColumnDelete={onColumnDelete}
onEditColumnTitle={onEditColumnTitle}
/>
</ViewBarContext.Provider>
<EntityBoardActionBar />
<EntityBoardContextMenu />
</BoardContext.Provider>
</>
);
};

View File

@ -1,8 +1,9 @@
import { type Context, type ReactNode, useContext } from 'react';
import { type ReactNode, useContext } from 'react';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { BoardCardIdContext } from '@/ui/board/contexts/BoardCardIdContext';
import { useBoardContext } from '@/ui/board/hooks/useBoardContext';
import { useCurrentCardSelected } from '@/ui/board/hooks/useCurrentCardSelected';
import { visibleBoardCardFieldsScopedSelector } from '@/ui/board/states/selectors/visibleBoardCardFieldsScopedSelector';
import { EntityChipVariant } from '@/ui/chip/components/EntityChip';
@ -19,10 +20,6 @@ import { companyProgressesFamilyState } from '../states/companyProgressesFamilyS
import { CompanyChip } from './CompanyChip';
type OwnProps = {
scopeContext: Context<string | null>;
};
const StyledBoardCard = styled.div<{ selected: boolean }>`
background-color: ${({ theme, selected }) =>
selected ? theme.accent.quaternary : theme.background.secondary};
@ -103,7 +100,9 @@ const StyledFieldContainer = styled.div`
width: 100%;
`;
export function CompanyBoardCard({ scopeContext }: OwnProps) {
export function CompanyBoardCard() {
const { BoardRecoilScopeContext } = useBoardContext();
const { currentCardSelected, setCurrentCardSelected } =
useCurrentCardSelected();
const boardCardId = useContext(BoardCardIdContext);
@ -115,7 +114,7 @@ export function CompanyBoardCard({ scopeContext }: OwnProps) {
const visibleBoardCardFields = useRecoilScopedValue(
visibleBoardCardFieldsScopedSelector,
scopeContext,
BoardRecoilScopeContext,
);
// boardCardId check can be moved to a wrapper to avoid unnecessary logic above

View File

@ -1,26 +1,23 @@
import { Context } from 'react';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { FilterDropdownEntitySearchSelect } from '@/ui/view-bar/components/FilterDropdownEntitySearchSelect';
import { useViewBarContext } from '@/ui/view-bar/hooks/useViewBarContext';
import { filterDropdownSearchInputScopedState } from '@/ui/view-bar/states/filterDropdownSearchInputScopedState';
import { filterDropdownSelectedEntityIdScopedState } from '@/ui/view-bar/states/filterDropdownSelectedEntityIdScopedState';
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
export function FilterDropdownCompanySearchSelect({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownCompanySearchSelect() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const filterDropdownSearchInput = useRecoilScopedValue(
filterDropdownSearchInputScopedState,
context,
ViewBarRecoilScopeContext,
);
const [filterDropdownSelectedEntityId] = useRecoilScopedState(
filterDropdownSelectedEntityIdScopedState,
context,
ViewBarRecoilScopeContext,
);
const usersForSelect = useFilteredSearchCompanyQuery({
@ -31,9 +28,6 @@ export function FilterDropdownCompanySearchSelect({
});
return (
<FilterDropdownEntitySearchSelect
entitiesForSelect={usersForSelect}
context={context}
/>
<FilterDropdownEntitySearchSelect entitiesForSelect={usersForSelect} />
);
}

View File

@ -60,7 +60,7 @@ export function CompanyNameEditableField({ company }: OwnProps) {
}
return (
<RecoilScope SpecificContext={FieldRecoilScopeContext}>
<RecoilScope CustomRecoilScopeContext={FieldRecoilScopeContext}>
<StyledEditableTitleInput
autoComplete="off"
onChange={(event) => handleChange(event.target.value)}

View File

@ -0,0 +1,9 @@
import { createContext } from 'react';
import { RecoilScopeContext } from '@/types/RecoilScopeContext';
export const BoardContext = createContext<{
BoardRecoilScopeContext: RecoilScopeContext;
}>({
BoardRecoilScopeContext: createContext<string | null>(null),
});

View File

@ -0,0 +1,5 @@
import { createContext } from 'react';
export const CompanyBoardViewBarRecoilScopeContext = createContext<
string | null
>(null);

View File

@ -44,10 +44,6 @@ export function CompanyTable() {
const { setContextMenuEntries } = useCompanyTableContextMenuEntries();
const { setActionBarEntries } = useCompanyTableActionBarEntries();
function handleImport() {
openCompanySpreadsheetImport();
}
return (
<>
<EntityTableEffect
@ -70,10 +66,11 @@ export function CompanyTable() {
onViewCreate: createView,
onViewEdit: updateView,
onViewRemove: deleteView,
onImport: openCompanySpreadsheetImport,
ViewBarRecoilScopeContext: TableRecoilScopeContext,
}}
>
<EntityTable
onImport={handleImport}
updateEntityMutation={({
variables,
}: {

View File

@ -1,4 +1,5 @@
import { EntityTable } from '@/ui/table/components/EntityTable';
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
import { useUpdateOneCompanyMutation } from '~/generated/graphql';
@ -8,7 +9,12 @@ export function CompanyTableMockMode() {
return (
<>
<CompanyTableMockDataEffect />
<ViewBarContext.Provider value={{ defaultViewName: 'All Companies' }}>
<ViewBarContext.Provider
value={{
defaultViewName: 'All Companies',
ViewBarRecoilScopeContext: TableRecoilScopeContext,
}}
>
<EntityTable updateEntityMutation={[useUpdateOneCompanyMutation()]} />
</ViewBarContext.Provider>
</>