Skip to content

Commit

Permalink
282 on opportunities page data pipeline + companies + people is fetch…
Browse files Browse the repository at this point in the history
…ed from be (#285)

* feature: get pipelines columns from backend

* feature: display item not found instead of crashing

* feature: add BoardCard component

* feature: display items from the backend

* refactor: extract useBoard in a hook

* refactor: export only loading and error from useBoard

* refactor: create var pipelineStage

* feature: implement support for Company boards
  • Loading branch information
Samox authored Jun 14, 2023
1 parent eb8fc50 commit bf6fb0b
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 11 deletions.
49 changes: 49 additions & 0 deletions front/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,11 @@ export type DeleteCompaniesMutationVariables = Exact<{

export type DeleteCompaniesMutation = { __typename?: 'Mutation', deleteManyCompany: { __typename?: 'AffectedRows', count: number } };

export type GetPipelinesQueryVariables = Exact<{ [key: string]: never; }>;


export type GetPipelinesQuery = { __typename?: 'Query', findManyPipeline: Array<{ __typename?: 'Pipeline', id: string, name: string, pipelineStages?: Array<{ __typename?: 'PipelineStage', name: string, color: string, pipelineProgresses?: Array<{ __typename?: 'PipelineProgress', id: string, associableType: PipelineProgressableType, associableId: string }> | null }> | null }> };

export type GetPeopleQueryVariables = Exact<{
orderBy?: InputMaybe<Array<PersonOrderByWithRelationInput> | PersonOrderByWithRelationInput>;
where?: InputMaybe<PersonWhereInput>;
Expand Down Expand Up @@ -1623,6 +1628,50 @@ export function useDeleteCompaniesMutation(baseOptions?: Apollo.MutationHookOpti
export type DeleteCompaniesMutationHookResult = ReturnType<typeof useDeleteCompaniesMutation>;
export type DeleteCompaniesMutationResult = Apollo.MutationResult<DeleteCompaniesMutation>;
export type DeleteCompaniesMutationOptions = Apollo.BaseMutationOptions<DeleteCompaniesMutation, DeleteCompaniesMutationVariables>;
export const GetPipelinesDocument = gql`
query GetPipelines {
findManyPipeline(skip: 1) {
id
name
pipelineStages {
name
color
pipelineProgresses {
id
associableType
associableId
}
}
}
}
`;

/**
* __useGetPipelinesQuery__
*
* To run a query within a React component, call `useGetPipelinesQuery` and pass it any options that fit your needs.
* When your component renders, `useGetPipelinesQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetPipelinesQuery({
* variables: {
* },
* });
*/
export function useGetPipelinesQuery(baseOptions?: Apollo.QueryHookOptions<GetPipelinesQuery, GetPipelinesQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetPipelinesQuery, GetPipelinesQueryVariables>(GetPipelinesDocument, options);
}
export function useGetPipelinesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetPipelinesQuery, GetPipelinesQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetPipelinesQuery, GetPipelinesQueryVariables>(GetPipelinesDocument, options);
}
export type GetPipelinesQueryHookResult = ReturnType<typeof useGetPipelinesQuery>;
export type GetPipelinesLazyQueryHookResult = ReturnType<typeof useGetPipelinesLazyQuery>;
export type GetPipelinesQueryResult = Apollo.QueryResult<GetPipelinesQuery, GetPipelinesQueryVariables>;
export const GetPeopleDocument = gql`
query GetPeople($orderBy: [PersonOrderByWithRelationInput!], $where: PersonWhereInput, $limit: Int) {
people: findManyPerson(orderBy: $orderBy, where: $where, take: $limit) {
Expand Down
14 changes: 9 additions & 5 deletions front/src/modules/opportunities/components/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
import { BoardItem } from '../../ui/components/board/BoardItem';
import { NewButton } from '../../ui/components/board/BoardNewButton';

import { BoardCard } from './BoardCard';

type BoardProps = {
initialBoard: Column[];
items: Items;
Expand All @@ -41,8 +43,8 @@ export const Board = ({ initialBoard, items }: BoardProps) => {
);

return (
<DragDropContext onDragEnd={onDragEnd}>
<StyledBoard>
<StyledBoard>
<DragDropContext onDragEnd={onDragEnd}>
{board.map((column) => (
<Droppable key={column.id} droppableId={column.id}>
{(droppableProvided) => (
Expand All @@ -59,7 +61,9 @@ export const Board = ({ initialBoard, items }: BoardProps) => {
>
{(draggableProvided) => (
<BoardItem draggableProvided={draggableProvided}>
<p>{items[itemKey].content}</p>
<BoardCard>
{items[itemKey]?.id || 'Item not found'}
</BoardCard>
</BoardItem>
)}
</Draggable>
Expand All @@ -70,7 +74,7 @@ export const Board = ({ initialBoard, items }: BoardProps) => {
)}
</Droppable>
))}
</StyledBoard>
</DragDropContext>
</DragDropContext>
</StyledBoard>
);
};
5 changes: 5 additions & 0 deletions front/src/modules/opportunities/components/BoardCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from '@emotion/styled';

export const BoardCard = styled.p`
color: ${(props) => props.theme.text80};
`;
75 changes: 75 additions & 0 deletions front/src/modules/opportunities/hooks/useBoard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
GetCompaniesQuery,
GetPeopleQuery,
useGetCompaniesQuery,
useGetPeopleQuery,
useGetPipelinesQuery,
} from '../../../generated/graphql';
import { BoardItemKey, Column, Items } from '../../ui/components/board/Board';

type Entities = GetCompaniesQuery | GetPeopleQuery;

function isGetCompaniesQuery(
entities: Entities,
): entities is GetCompaniesQuery {
return (entities as GetCompaniesQuery).companies !== undefined;
}

function isGetPeopleQuery(entities: Entities): entities is GetPeopleQuery {
return (entities as GetPeopleQuery).people !== undefined;
}

export const useBoard = () => {
const pipelines = useGetPipelinesQuery();
const pipelineStages = pipelines.data?.findManyPipeline[0].pipelineStages;
const initialBoard: Column[] =
pipelineStages?.map((pipelineStage) => ({
id: pipelineStage.name,
title: pipelineStage.name,
colorCode: pipelineStage.color,
itemKeys:
pipelineStage.pipelineProgresses?.map(
(item) => `item-${item.associableId}` as BoardItemKey,
) || [],
})) || [];

const pipelineEntityIds = pipelineStages?.reduce(
(acc, pipelineStage) => [
...acc,
...(pipelineStage.pipelineProgresses?.map((item) => item.associableId) ||
[]),
],
[] as string[],
);

const pipelineEntityType: 'Person' | 'Company' | undefined =
pipelineStages?.[0].pipelineProgresses?.[0].associableType;
console.log(pipelineEntityType);

const query =
pipelineEntityType === 'Person' ? useGetPeopleQuery : useGetCompaniesQuery;

const entitiesQueryResult = query({
variables: { where: { id: { in: pipelineEntityIds } } },
});

const indexByIdReducer = (acc: Items, entity: { id: string }) => ({
...acc,
[`item-${entity.id}`]: entity,
});

const items: Items | undefined = entitiesQueryResult.data
? isGetCompaniesQuery(entitiesQueryResult.data)
? entitiesQueryResult.data.companies.reduce(indexByIdReducer, {} as Items)
: isGetPeopleQuery(entitiesQueryResult.data)
? entitiesQueryResult.data.people.reduce(indexByIdReducer, {} as Items)
: undefined
: undefined;

return {
initialBoard,
items,
loading: pipelines.loading || entitiesQueryResult.loading,
error: pipelines.error || entitiesQueryResult.error,
};
};
19 changes: 19 additions & 0 deletions front/src/modules/opportunities/queries/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { gql } from '@apollo/client';

export const GET_PIPELINES = gql`
query GetPipelines {
findManyPipeline(skip: 1) {
id
name
pipelineStages {
name
color
pipelineProgresses {
id
associableType
associableId
}
}
}
}
`;
4 changes: 2 additions & 2 deletions front/src/modules/ui/components/board/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export const StyledBoard = styled.div`
height: 100%;
`;

export type BoardItemKey = `item-${number}`;
export type BoardItemKey = `item-${number | string}`;
export interface Item {
id: string;
content: string;
content?: string;
}
export interface Items {
[key: string]: Item;
Expand Down
11 changes: 7 additions & 4 deletions front/src/pages/opportunities/Opportunities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { IconTarget } from '@/ui/icons/index';
import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer';
import { AppPage } from '~/AppPage';

import {
initialBoard,
items,
} from '../../modules/opportunities/components/__stories__/mock-data';
import { Board } from '../../modules/opportunities/components/Board';
import { useBoard } from '../../modules/opportunities/hooks/useBoard';

export function Opportunities() {
const { initialBoard, items, loading, error } = useBoard();

if (loading) return <div>Loading...</div>;
if (error) return <div>Error...</div>;
if (!initialBoard || !items)
return <div>Initial board or items not found</div>;
return (
<AppPage>
<WithTopBarContainer title="Opportunities" icon={<IconTarget />}>
Expand Down

0 comments on commit bf6fb0b

Please sign in to comment.