From edf79bee1819189fa8f8b5fa3921b25535010b42 Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Mon, 2 Sep 2024 16:12:59 +1000 Subject: [PATCH] feat: Enable JD new home page and route changes Hook up the job distributor new hoome page with the new route. update existing route to include manager id as we now support more than 1 job distributor. Update logic in components related to hardcoding of reading the first manager returned from graphql JIRA: https://smartcontract-it.atlassian.net/browse/OPCORE-858 --- .changeset/forty-doors-whisper.md | 5 ++ ...s => useFeedsManagerWithProposalsQuery.ts} | 31 +++++---- src/pages/feeds_manager/index.tsx | 27 +++++--- .../EditFeedsManagerScreen.test.tsx | 50 +++----------- .../EditFeedsManagerScreen.tsx | 39 +++++------ .../EditFeedsManager/EditFeedsManagerView.tsx | 2 +- .../FeedsManager/FeedsManagerCard.test.tsx | 4 +- src/screens/FeedsManager/FeedsManagerCard.tsx | 2 +- .../FeedsManager/FeedsManagerScreen.test.tsx | 66 ++++++++++++++----- .../FeedsManager/FeedsManagerScreen.tsx | 49 +++++++------- .../FeedsManager/SupportedChainsCard.tsx | 36 +++++----- 11 files changed, 163 insertions(+), 148 deletions(-) create mode 100644 .changeset/forty-doors-whisper.md rename src/hooks/queries/{useFeedsManagersWithProposalsQuery.ts => useFeedsManagerWithProposalsQuery.ts} (69%) diff --git a/.changeset/forty-doors-whisper.md b/.changeset/forty-doors-whisper.md new file mode 100644 index 00000000..f1a87b8a --- /dev/null +++ b/.changeset/forty-doors-whisper.md @@ -0,0 +1,5 @@ +--- +'@smartcontractkit/operator-ui': minor +--- + +Enable job distributor new home page and route changes diff --git a/src/hooks/queries/useFeedsManagersWithProposalsQuery.ts b/src/hooks/queries/useFeedsManagerWithProposalsQuery.ts similarity index 69% rename from src/hooks/queries/useFeedsManagersWithProposalsQuery.ts rename to src/hooks/queries/useFeedsManagerWithProposalsQuery.ts index 9cc6e066..1581e201 100644 --- a/src/hooks/queries/useFeedsManagersWithProposalsQuery.ts +++ b/src/hooks/queries/useFeedsManagerWithProposalsQuery.ts @@ -65,7 +65,7 @@ export const FEEDS_MANAGER__JOB_PROPOSAL_FIELDS = gql` } ` -export const FEEDS_MANAGERS_PAYLOAD__RESULTS_FIELDS = gql` +export const FEEDS_MANAGER_PAYLOAD__RESULTS_FIELDS = gql` ${FEEDS_MANAGER_FIELDS} ${FEEDS_MANAGER__JOB_PROPOSAL_FIELDS} fragment FeedsManagerPayload_ResultsFields on FeedsManager { @@ -76,22 +76,27 @@ export const FEEDS_MANAGERS_PAYLOAD__RESULTS_FIELDS = gql` } ` -export const FEEDS_MANAGERS_WITH_PROPOSALS_QUERY = gql` - ${FEEDS_MANAGERS_PAYLOAD__RESULTS_FIELDS} - query FetchFeedManagersWithProposals { - feedsManagers { - results { - ...FeedsManagerPayload_ResultsFields +export const FEEDS_MANAGER_WITH_PROPOSALS_QUERY = gql` + ${FEEDS_MANAGER_PAYLOAD__RESULTS_FIELDS} + query FetchFeedManagerWithProposals($id: ID!) { + feedsManager(id: $id) { + ...FeedsManagerPayload_ResultsFields + ... on NotFoundError { + message + code } } } ` -export const useFeedsManagersWithProposalsQuery = ( - opts: QueryHookOptions = {}, +export const useFeedsManagerWithProposalsQuery = ( + opts: QueryHookOptions< + FetchFeedManagerWithProposals, + FetchFeedManagerWithProposalsVariables + > = {}, ) => { - return useQuery( - FEEDS_MANAGERS_WITH_PROPOSALS_QUERY, - opts, - ) + return useQuery< + FetchFeedManagerWithProposals, + FetchFeedManagerWithProposalsVariables + >(FEEDS_MANAGER_WITH_PROPOSALS_QUERY, opts) } diff --git a/src/pages/feeds_manager/index.tsx b/src/pages/feeds_manager/index.tsx index dda840ab..83c7d22c 100644 --- a/src/pages/feeds_manager/index.tsx +++ b/src/pages/feeds_manager/index.tsx @@ -1,7 +1,8 @@ import React from 'react' -import { Route, useRouteMatch } from 'react-router-dom' +import { Route, Switch, useRouteMatch } from 'react-router-dom' import Content from 'components/Content' +import { JobDistributorsScreen } from 'src/screens/JobDistributors/JobDistributorsScreen' import { EditFeedsManagerScreen } from '../../screens/EditFeedsManager/EditFeedsManagerScreen' import { FeedsManagerScreen } from '../../screens/FeedsManager/FeedsManagerScreen' import { NewFeedsManagerScreen } from '../../screens/NewFeedsManager/NewFeedsManagerScreen' @@ -11,17 +12,23 @@ export const FeedsManagerPage = function () { return ( - - - + + + + - - - + + + - - - + + + + + + + + ) } diff --git a/src/screens/EditFeedsManager/EditFeedsManagerScreen.test.tsx b/src/screens/EditFeedsManager/EditFeedsManagerScreen.test.tsx index 52956f81..dc9ceda3 100644 --- a/src/screens/EditFeedsManager/EditFeedsManagerScreen.test.tsx +++ b/src/screens/EditFeedsManager/EditFeedsManagerScreen.test.tsx @@ -1,22 +1,22 @@ import * as React from 'react' +import { MockedProvider, MockedResponse } from '@apollo/client/testing' +import userEvent from '@testing-library/user-event' +import { GraphQLError } from 'graphql' import { Route } from 'react-router-dom' import { renderWithRouter, screen, waitForElementToBeRemoved, } from 'support/test-utils' -import userEvent from '@testing-library/user-event' -import { MockedProvider, MockedResponse } from '@apollo/client/testing' +import Notifications from 'pages/Notifications' +import { FEEDS_MANAGERS_QUERY } from 'src/hooks/queries/useFeedsManagersQuery' import { buildFeedsManager } from 'support/factories/gql/fetchFeedsManagers' import { - UPDATE_FEEDS_MANAGER_MUTATION, EditFeedsManagerScreen, + UPDATE_FEEDS_MANAGER_MUTATION, } from './EditFeedsManagerScreen' -import { FEEDS_MANAGERS_QUERY } from 'src/hooks/queries/useFeedsManagersQuery' -import Notifications from 'pages/Notifications' -import { GraphQLError } from 'graphql' const { findByText, findByTestId, getByRole, queryByRole } = screen @@ -24,19 +24,17 @@ function renderComponent(mocks: MockedResponse[]) { renderWithRouter( <> - + - - New Redirect Success - Root Redirect Success , + { initialEntries: ['/job_distributors/1/edit'] }, ) } @@ -85,7 +83,7 @@ describe('EditFeedsManagerScreen', () => { await waitForElementToBeRemoved(() => queryByRole('progressbar')) - expect(await findByText('New Redirect Success')).toBeInTheDocument() + expect(await findByText('Root Redirect Success')).toBeInTheDocument() }) it('submits the form', async () => { @@ -129,24 +127,6 @@ describe('EditFeedsManagerScreen', () => { }, }, }, - { - request: { - query: FEEDS_MANAGERS_QUERY, - }, - result: { - data: { - feedsManagers: { - results: [ - buildFeedsManager({ - name: 'updated', - uri: 'localhost:80812', - publicKey: '22222', - }), - ], - }, - }, - }, - }, ] renderComponent(mocks) @@ -263,18 +243,6 @@ describe('EditFeedsManagerScreen', () => { }, }, }, - { - request: { - query: FEEDS_MANAGERS_QUERY, - }, - result: { - data: { - feedsManagers: { - results: [mgr], - }, - }, - }, - }, ] renderComponent(mocks) diff --git a/src/screens/EditFeedsManager/EditFeedsManagerScreen.tsx b/src/screens/EditFeedsManager/EditFeedsManagerScreen.tsx index 2fcb1f01..cb6b1d35 100644 --- a/src/screens/EditFeedsManager/EditFeedsManagerScreen.tsx +++ b/src/screens/EditFeedsManager/EditFeedsManagerScreen.tsx @@ -1,21 +1,18 @@ import React from 'react' -import { useMutation, gql } from '@apollo/client' +import { gql, useMutation } from '@apollo/client' import { FormikHelpers } from 'formik' import { useDispatch } from 'react-redux' -import { Redirect, useLocation, useHistory } from 'react-router-dom' +import { Redirect, useHistory, useParams } from 'react-router-dom' -import { notifySuccessMsg, notifyErrorMsg } from 'actionCreators' -import { EditFeedsManagerView } from './EditFeedsManagerView' -import { GraphqlErrorHandler } from 'src/components/ErrorHandler/GraphqlErrorHandler' -import { FormValues } from 'components/Form/FeedsManagerForm' -import { parseInputErrors } from 'src/utils/inputErrors' +import { notifyErrorMsg, notifySuccessMsg } from 'actionCreators' import { Loading } from 'components/Feedback/Loading' -import { - useFeedsManagersQuery, - FEEDS_MANAGERS_QUERY, -} from 'src/hooks/queries/useFeedsManagersQuery' +import { FormValues } from 'components/Form/FeedsManagerForm' +import { GraphqlErrorHandler } from 'src/components/ErrorHandler/GraphqlErrorHandler' +import { useFeedsManagersQuery } from 'src/hooks/queries/useFeedsManagersQuery' import { useMutationErrorHandler } from 'src/hooks/useMutationErrorHandler' +import { parseInputErrors } from 'src/utils/inputErrors' +import { EditFeedsManagerView } from './EditFeedsManagerView' export const UPDATE_FEEDS_MANAGER_MUTATION = gql` mutation UpdateFeedsManager($id: ID!, $input: UpdateFeedsManagerInput!) { @@ -45,18 +42,20 @@ export const UPDATE_FEEDS_MANAGER_MUTATION = gql` } ` +interface RouteParams { + id: string +} + export const EditFeedsManagerScreen: React.FC = () => { + const { id } = useParams() const history = useHistory() - const location = useLocation() const dispatch = useDispatch() const { handleMutationError } = useMutationErrorHandler() const { data, loading, error } = useFeedsManagersQuery() const [updateFeedsManager] = useMutation< UpdateFeedsManager, UpdateFeedsManagerVariables - >(UPDATE_FEEDS_MANAGER_MUTATION, { - refetchQueries: [FEEDS_MANAGERS_QUERY], - }) + >(UPDATE_FEEDS_MANAGER_MUTATION) if (loading) { return @@ -66,19 +65,13 @@ export const EditFeedsManagerScreen: React.FC = () => { return } - // We currently only support a single feeds manager, but plan to support more - // in the future. - const manager = - data != undefined && data.feedsManagers.results[0] - ? data.feedsManagers.results[0] - : undefined + const manager = data?.feedsManagers.results.filter((x) => x.id === id)[0] if (!manager) { return ( ) diff --git a/src/screens/EditFeedsManager/EditFeedsManagerView.tsx b/src/screens/EditFeedsManager/EditFeedsManagerView.tsx index 30007980..2d8b6bd7 100644 --- a/src/screens/EditFeedsManager/EditFeedsManagerView.tsx +++ b/src/screens/EditFeedsManager/EditFeedsManagerView.tsx @@ -11,7 +11,7 @@ import { } from 'components/Form/FeedsManagerForm' type Props = { - data: FetchFeedsManagers['feedsManagers']['results'][number] + data: FetchFeedsManagersPayload_ResultsFields } & Pick export const EditFeedsManagerView: React.FC = ({ data, onSubmit }) => { diff --git a/src/screens/FeedsManager/FeedsManagerCard.test.tsx b/src/screens/FeedsManager/FeedsManagerCard.test.tsx index 7b3915f2..6789092c 100644 --- a/src/screens/FeedsManager/FeedsManagerCard.test.tsx +++ b/src/screens/FeedsManager/FeedsManagerCard.test.tsx @@ -16,7 +16,9 @@ function renderComponent(manager: FeedsManagerFields) { - Redirect Success + + Redirect Success + , ) } diff --git a/src/screens/FeedsManager/FeedsManagerCard.tsx b/src/screens/FeedsManager/FeedsManagerCard.tsx index 372ba135..4b510c93 100644 --- a/src/screens/FeedsManager/FeedsManagerCard.tsx +++ b/src/screens/FeedsManager/FeedsManagerCard.tsx @@ -45,7 +45,7 @@ export const FeedsManagerCard = ({ manager }: Props) => { open={Boolean(anchorEl)} onClose={handleClose} > - + diff --git a/src/screens/FeedsManager/FeedsManagerScreen.test.tsx b/src/screens/FeedsManager/FeedsManagerScreen.test.tsx index 5554b4b6..e9e157c6 100644 --- a/src/screens/FeedsManager/FeedsManagerScreen.test.tsx +++ b/src/screens/FeedsManager/FeedsManagerScreen.test.tsx @@ -1,27 +1,32 @@ import * as React from 'react' import { GraphQLError } from 'graphql' -import { Route } from 'react-router-dom' +import { Route, Switch } from 'react-router-dom' import { renderWithRouter, screen } from 'support/test-utils' import { MockedProvider, MockedResponse } from '@apollo/client/testing' import { FeedsManagerScreen } from './FeedsManagerScreen' import { buildFeedsManagerResultFields } from 'support/factories/gql/fetchFeedsManagersWithProposals' -import { FEEDS_MANAGERS_WITH_PROPOSALS_QUERY } from 'src/hooks/queries/useFeedsManagersWithProposalsQuery' +import { FEEDS_MANAGER_WITH_PROPOSALS_QUERY } from 'src/hooks/queries/useFeedsManagerWithProposalsQuery' -const { findByText } = screen +const { findByText, findByTestId } = screen function renderComponent(mocks: MockedResponse[]) { renderWithRouter( - <> - - + + + - Redirect Success - , + + job_distributors + + , + { + initialEntries: ['/job_distributors/1'], + }, ) } @@ -30,13 +35,12 @@ describe('FeedsManagerScreen', () => { const mocks: MockedResponse[] = [ { request: { - query: FEEDS_MANAGERS_WITH_PROPOSALS_QUERY, + query: FEEDS_MANAGER_WITH_PROPOSALS_QUERY, + variables: { id: '1' }, }, result: { data: { - feedsManagers: { - results: [buildFeedsManagerResultFields()], - }, + feedsManager: buildFeedsManagerResultFields(), }, }, }, @@ -48,16 +52,41 @@ describe('FeedsManagerScreen', () => { expect(await findByText('Job Proposals')).toBeInTheDocument() }) - it('redirects when a manager does not exists', async () => { + it('should render not found page when a manager is not found', async () => { + const mocks: MockedResponse[] = [ + { + request: { + query: FEEDS_MANAGER_WITH_PROPOSALS_QUERY, + variables: { id: '1' }, + }, + result: { + data: { + feedsManager: { + __typename: 'NotFoundError', + message: 'Not Found', + code: '404', + }, + }, + }, + }, + ] + + renderComponent(mocks) + + expect(await findByTestId('not-found-page')).toBeInTheDocument() + }) + + it('should redirect to /job_distributors when result type is unknown', async () => { const mocks: MockedResponse[] = [ { request: { - query: FEEDS_MANAGERS_WITH_PROPOSALS_QUERY, + query: FEEDS_MANAGER_WITH_PROPOSALS_QUERY, + variables: { id: '1' }, }, result: { data: { - feedsManagers: { - results: [], + feedsManager: { + __typename: 'Unknown', }, }, }, @@ -66,14 +95,15 @@ describe('FeedsManagerScreen', () => { renderComponent(mocks) - expect(await findByText('Redirect Success')).toBeInTheDocument() + expect(await findByText('job_distributors')).toBeInTheDocument() }) it('renders GQL errors', async () => { const mocks: MockedResponse[] = [ { request: { - query: FEEDS_MANAGERS_WITH_PROPOSALS_QUERY, + query: FEEDS_MANAGER_WITH_PROPOSALS_QUERY, + variables: { id: '1' }, }, result: { errors: [new GraphQLError('Error!')], diff --git a/src/screens/FeedsManager/FeedsManagerScreen.tsx b/src/screens/FeedsManager/FeedsManagerScreen.tsx index 1a259682..5ed028f7 100644 --- a/src/screens/FeedsManager/FeedsManagerScreen.tsx +++ b/src/screens/FeedsManager/FeedsManagerScreen.tsx @@ -1,16 +1,21 @@ import React from 'react' -import { Redirect, useLocation } from 'react-router-dom' - +import { Redirect, useParams } from 'react-router-dom' import { GraphqlErrorHandler } from 'src/components/ErrorHandler/GraphqlErrorHandler' -import { FeedsManagerView } from './FeedsManagerView' import { Loading } from 'src/components/Feedback/Loading' -import { useFeedsManagersWithProposalsQuery } from 'src/hooks/queries/useFeedsManagersWithProposalsQuery' +import { useFeedsManagerWithProposalsQuery } from 'src/hooks/queries/useFeedsManagerWithProposalsQuery' +import NotFound from 'src/pages/NotFound' +import { FeedsManagerView } from './FeedsManagerView' + +interface RouteParams { + id: string +} export const FeedsManagerScreen: React.FC = () => { - const location = useLocation() + const { id } = useParams() - const { data, loading, error } = useFeedsManagersWithProposalsQuery({ + const { data, loading, error } = useFeedsManagerWithProposalsQuery({ + variables: { id }, fetchPolicy: 'cache-and-network', }) @@ -22,23 +27,19 @@ export const FeedsManagerScreen: React.FC = () => { return } - // We currently only support a single feeds manager, but plan to support more - // in the future. - const manager = - data != undefined && data.feedsManagers.results.length > 0 - ? data.feedsManagers.results[0] - : undefined - - if (data && manager) { - return + const payload = data?.feedsManager + switch (payload?.__typename) { + case 'NotFoundError': + return + case 'FeedsManager': + return + default: + return ( + + ) } - - return ( - - ) } diff --git a/src/screens/FeedsManager/SupportedChainsCard.tsx b/src/screens/FeedsManager/SupportedChainsCard.tsx index db4912a4..2afe7c96 100644 --- a/src/screens/FeedsManager/SupportedChainsCard.tsx +++ b/src/screens/FeedsManager/SupportedChainsCard.tsx @@ -36,7 +36,7 @@ import { NewSupportedChainDialog } from './NewSupportedChainDialog' import { useMutationErrorHandler } from 'src/hooks/useMutationErrorHandler' import Button from 'src/components/Button' import { EditSupportedChainDialog } from './EditSupportedChainDialog' -import { FEEDS_MANAGERS_WITH_PROPOSALS_QUERY } from 'src/hooks/queries/useFeedsManagersWithProposalsQuery' +import { FEEDS_MANAGER_WITH_PROPOSALS_QUERY } from 'src/hooks/queries/useFeedsManagerWithProposalsQuery' export const CREATE_FEEDS_MANAGER_CHAIN_CONFIG_MUTATION = gql` mutation CreateFeedsManagerChainConfig( @@ -291,21 +291,21 @@ export const SupportedChainsCard = withStyles(styles)( CreateFeedsManagerChainConfig, CreateFeedsManagerChainConfigVariables >(CREATE_FEEDS_MANAGER_CHAIN_CONFIG_MUTATION, { - refetchQueries: [FEEDS_MANAGERS_WITH_PROPOSALS_QUERY], + refetchQueries: [FEEDS_MANAGER_WITH_PROPOSALS_QUERY], }) const [deleteChainConfig] = useMutation< DeleteFeedsManagerChainConfig, DeleteFeedsManagerChainConfigVariables >(DELETE_FEEDS_MANAGER_CHAIN_CONFIG_MUTATION, { - refetchQueries: [FEEDS_MANAGERS_WITH_PROPOSALS_QUERY], + refetchQueries: [FEEDS_MANAGER_WITH_PROPOSALS_QUERY], }) const [updateChainConfig] = useMutation< UpdateFeedsManagerChainConfig, UpdateFeedsManagerChainConfigVariables >(UPDATE_FEEDS_MANAGER_CHAIN_CONFIG_MUTATION, { - refetchQueries: [FEEDS_MANAGERS_WITH_PROPOSALS_QUERY], + refetchQueries: [FEEDS_MANAGER_WITH_PROPOSALS_QUERY], }) const handleCreateSubmit = async (values: FormValues) => { @@ -537,18 +537,22 @@ export const SupportedChainsCard = withStyles(styles)( ))} - setNewDialogOpen(false)} - onSubmit={handleCreateSubmit} - /> - - + {newDialogOpen && ( + setNewDialogOpen(false)} + onSubmit={handleCreateSubmit} + /> + )} + + {isEditDialogOpen() && ( + + )} ) },