diff --git a/apps/trading/client-pages/markets/proposed.tsx b/apps/trading/client-pages/markets/proposed.tsx index 3c4a4d529..25f5a5252 100644 --- a/apps/trading/client-pages/markets/proposed.tsx +++ b/apps/trading/client-pages/markets/proposed.tsx @@ -12,7 +12,7 @@ export const Proposed = () => { const externalLink = tokenLink(TOKEN_NEW_MARKET_PROPOSAL); return ( <> -
+
diff --git a/libs/proposals/src/components/proposals-list/proposal-list.spec.tsx b/libs/proposals/src/components/proposals-list/proposal-list.spec.tsx index 512d971f5..5bef72d3c 100644 --- a/libs/proposals/src/components/proposals-list/proposal-list.spec.tsx +++ b/libs/proposals/src/components/proposals-list/proposal-list.spec.tsx @@ -5,57 +5,74 @@ import { waitFor, getAllByRole, } from '@testing-library/react'; +import merge from 'lodash/merge'; +import type { MockedResponse } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing'; import { ProposalsList } from './proposals-list'; -import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider'; import * as Types from '@vegaprotocol/types'; - -const votesMock = { - yes: { - totalTokens: '5000', - }, - no: { - totalTokens: '2000', - }, -}; -let marketsProposalMock: ProposalListFieldsFragment[] | null = [ - { - id: 'id-1', - state: Types.ProposalState.STATE_OPEN, - votes: { ...votesMock }, - }, - { - id: 'id-2', - state: Types.ProposalState.STATE_PASSED, - votes: { ...votesMock }, - }, - { - id: 'id-3', - state: Types.ProposalState.STATE_WAITING_FOR_NODE_VOTE, - votes: { ...votesMock }, - }, -] as ProposalListFieldsFragment[]; - -const useDataProvider = () => { - return { - data: marketsProposalMock, - loading: false, - error: false, - }; -}; -jest.mock('@vegaprotocol/data-provider', () => ({ - ...jest.requireActual('@vegaprotocol/data-provider'), - useDataProvider: jest.fn(() => useDataProvider()), -})); +import { createProposalListFieldsFragment } from '../../lib/proposals-data-provider/proposals.mock'; +import type { ProposalsListQuery } from '../../lib'; +import { ProposalsListDocument } from '../../lib'; +import type { PartialDeep } from 'type-fest'; describe('ProposalsList', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); + const createProposalsMock = (override?: PartialDeep) => { + const defaultProposalEdges = [ + { + __typename: 'ProposalEdge' as const, + node: createProposalListFieldsFragment({ + id: 'id-1', + state: Types.ProposalState.STATE_OPEN, + }), + }, + { + __typename: 'ProposalEdge' as const, + node: createProposalListFieldsFragment({ + id: 'id-2', + state: Types.ProposalState.STATE_PASSED, + }), + }, + { + __typename: 'ProposalEdge' as const, + node: createProposalListFieldsFragment({ + id: 'id-3', + state: Types.ProposalState.STATE_WAITING_FOR_NODE_VOTE, + }), + }, + ]; + const data = merge( + { + proposalsConnection: { + __typename: 'ProposalsConnection' as const, + edges: defaultProposalEdges, + }, + }, + override + ); + + const mock: MockedResponse = { + request: { + query: ProposalsListDocument, + variables: { + proposalType: Types.ProposalType.TYPE_NEW_MARKET, + }, + }, + result: { + data, + }, + }; + + return mock; + }; it('should be properly rendered', async () => { + const mock = createProposalsMock(); await act(() => { - render(, { wrapper: MockedProvider }); + render( + + + + ); }); const container = document.querySelector('.ag-center-cols-container'); await waitFor(() => { @@ -65,15 +82,25 @@ describe('ProposalsList', () => { }); it('some of states should be filtered out', async () => { - marketsProposalMock = [ - { - ...(marketsProposalMock as ProposalListFieldsFragment[])[0], - state: Types.ProposalState.STATE_ENACTED, + const mock = createProposalsMock({ + proposalsConnection: { + edges: [ + { + __typename: 'ProposalEdge', + node: createProposalListFieldsFragment({ + id: 'id-1', + state: Types.ProposalState.STATE_ENACTED, + }), + }, + ], }, - ...(marketsProposalMock as ProposalListFieldsFragment[]).slice(1), - ]; + }); await act(() => { - render(, { wrapper: MockedProvider }); + render( + + + + ); }); const container = document.querySelector('.ag-center-cols-container'); await waitFor(() => { @@ -83,9 +110,12 @@ describe('ProposalsList', () => { }); it('empty response should causes no data message display', async () => { - marketsProposalMock = null; await act(() => { - render(, { wrapper: MockedProvider }); + render( + + + + ); }); const container = document.querySelector('.ag-center-cols-container'); await waitFor(() => { diff --git a/libs/proposals/src/components/proposals-list/proposals-list.tsx b/libs/proposals/src/components/proposals-list/proposals-list.tsx index 063f95b15..5521e735b 100644 --- a/libs/proposals/src/components/proposals-list/proposals-list.tsx +++ b/libs/proposals/src/components/proposals-list/proposals-list.tsx @@ -1,13 +1,13 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid'; -import { useDataProvider } from '@vegaprotocol/data-provider'; import { t } from '@vegaprotocol/i18n'; import * as Types from '@vegaprotocol/types'; -import { proposalsDataProvider } from '../../lib/proposals-data-provider'; import type { AgGridReact } from 'ag-grid-react'; import { useColumnDefs } from './use-column-defs'; import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals'; +import { useProposalsListQuery } from '../../lib/proposals-data-provider/__generated__/Proposals'; +import { removePaginationWrapper } from '@vegaprotocol/utils'; export const getNewMarketProposals = (data: ProposalListFieldsFragment[]) => data.filter((proposal) => @@ -21,13 +21,15 @@ export const getNewMarketProposals = (data: ProposalListFieldsFragment[]) => export const ProposalsList = () => { const gridRef = useRef(null); const [dataCount, setDataCount] = useState(0); - const { data, loading, error, reload } = useDataProvider({ - dataProvider: proposalsDataProvider, + const { data, loading, error, refetch } = useProposalsListQuery({ variables: { proposalType: Types.ProposalType.TYPE_NEW_MARKET, }, + errorPolicy: 'all', // currently there are some proposals failing due to proposals existing without settlement asset ids }); - const filteredData = getNewMarketProposals(data || []); + const filteredData = getNewMarketProposals( + removePaginationWrapper(data?.proposalsConnection?.edges) + ); const { columnDefs, defaultColDef } = useColumnDefs(); useEffect(() => { setDataCount(gridRef.current?.api?.getModel().getRowCount() ?? 0); @@ -36,11 +38,10 @@ export const ProposalsList = () => { setDataCount(gridRef.current?.api?.getModel().getRowCount() ?? 0); }, []); return ( -
+
{ suppressNoRowsOverlay onFilterChanged={onFilterChanged} storeKey="proposedMarkets" + getRowId={({ data }) => data.id} + style={{ width: '100%', height: '100%' }} />
{ data={filteredData} noDataMessage={t('No markets')} noDataCondition={() => !dataCount} - reload={reload} + reload={refetch} />
diff --git a/libs/proposals/src/lib/proposals-data-provider/proposals.mock.ts b/libs/proposals/src/lib/proposals-data-provider/proposals.mock.ts index ebbd1b9ca..e2fea532f 100644 --- a/libs/proposals/src/lib/proposals-data-provider/proposals.mock.ts +++ b/libs/proposals/src/lib/proposals-data-provider/proposals.mock.ts @@ -11,6 +11,7 @@ export const proposalListQuery = ( ): ProposalsListQuery => { const defaultResult: ProposalsListQuery = { proposalsConnection: { + __typename: 'ProposalsConnection', edges: proposalListFields.map((node) => ({ __typename: 'ProposalEdge', node, @@ -104,8 +105,10 @@ export const marketUpdateProposal: ProposalListFieldsFragment = { }, }; -const proposalListFields: ProposalListFieldsFragment[] = [ - { +export const createProposalListFieldsFragment = ( + override?: PartialDeep +): ProposalListFieldsFragment => { + const defaultProposal: ProposalListFieldsFragment = { id: 'e9ec6d5c46a7e7bcabf9ba7a893fa5a5eeeec08b731f06f7a6eb7bf0e605b829', reference: 'injected_at_runtime', state: Schema.ProposalState.STATE_OPEN, @@ -194,7 +197,12 @@ const proposalListFields: ProposalListFieldsFragment[] = [ __typename: 'ProposalTerms', }, __typename: 'Proposal', - }, + }; + return merge(defaultProposal, override); +}; + +const proposalListFields: ProposalListFieldsFragment[] = [ + createProposalListFieldsFragment(), { id: '1cd1deb532b97fbeb9262fe94499ecec5835e60ae564b7c5af530c90a13c29cb', reference: 'injected_at_runtime',