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,7 +14,7 @@ const meta: Meta<typeof CompanyBoard> = {
|
||||
component: CompanyBoard,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<RecoilScope SpecificContext={CompanyBoardRecoilScopeContext}>
|
||||
<RecoilScope CustomRecoilScopeContext={CompanyBoardRecoilScopeContext}>
|
||||
<HooksCompanyBoardEffect />
|
||||
<MemoryRouter>
|
||||
<Story />
|
||||
|
||||
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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} />
|
||||
);
|
||||
}
|
||||
|
||||
@ -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)}
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import { RecoilScopeContext } from '@/types/RecoilScopeContext';
|
||||
|
||||
export const BoardContext = createContext<{
|
||||
BoardRecoilScopeContext: RecoilScopeContext;
|
||||
}>({
|
||||
BoardRecoilScopeContext: createContext<string | null>(null),
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
export const CompanyBoardViewBarRecoilScopeContext = createContext<
|
||||
string | null
|
||||
>(null);
|
||||
@ -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,
|
||||
}: {
|
||||
|
||||
@ -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>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user