From a9bc74d071aa7e6f72151bdbf5a08aecc103fa77 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <p.gawron@atcomp.pl> Date: Tue, 31 Dec 2024 14:32:47 +0100 Subject: [PATCH] use new publication endpoint --- .../PublicationsModal/PublicationsModal.tsx | 12 +- ...PublicationsModalLayout.component.test.tsx | 20 +- .../utils/getBasePublications.test.ts | 16 +- .../utils/getBasePublications.ts | 16 +- .../utils/getStandarizedPublications.ts | 8 +- .../mapBasePublicationToStandarized.test.ts | 14 +- .../utils/mapBasePublicationToStandarized.ts | 7 +- .../utils/useDownloadPublicationsAsCSVFile.ts | 4 +- .../FilterBySubmapHeader.test.tsx | 4 +- src/models/mocks/publicationsResponseMock.ts | 351 +++++++++--------- src/models/pageableSchema.ts | 2 +- src/models/publicationsResponseSchema.ts | 10 - src/models/publicationsSchema.ts | 8 +- .../publications/publications.selectors.ts | 11 +- src/redux/publications/publications.thunks.ts | 18 +- src/redux/publications/publications.types.ts | 4 +- src/types/models.ts | 6 +- 17 files changed, 248 insertions(+), 263 deletions(-) delete mode 100644 src/models/publicationsResponseSchema.ts diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx index 69cbc09b..e37d378e 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx @@ -19,13 +19,13 @@ export const PublicationsModal = (): JSX.Element => { const parsedData: PublicationsTableData[] | undefined = useMemo(() => { const dd = data?.map(item => ({ - pubmedId: item.publication.article.pubmedId, - title: item.publication.article.title, - authors: item.publication.article.authors, - journal: item.publication.article.journal, - year: item.publication.article.year, + pubmedId: item.article.pubmedId, + title: item.article.title, + authors: item.article.authors, + journal: item.article.journal, + year: item.article.year, elementsOnMap: JSON.stringify(item.elements) || EMPTY_ARRAY_STRING, // table data accepts only string | string[] - submaps: mapsNames[item.elements[FIRST_ARRAY_ELEMENT].modelId], + submaps: mapsNames[item.elements[FIRST_ARRAY_ELEMENT].model], })); return dd || []; }, [data, mapsNames]); diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/PublicationsModalLayout.component.test.tsx b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/PublicationsModalLayout.component.test.tsx index aa7755b5..95bf0cd7 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/PublicationsModalLayout.component.test.tsx +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/PublicationsModalLayout.component.test.tsx @@ -8,7 +8,7 @@ import { apiPath } from '@/redux/apiPath'; import { downloadFileFromBlob } from '@/redux/export/export.utils'; import { StoreType } from '@/redux/store'; import { BioEntityContent, Publication } from '@/types/models'; -import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { InitialStoreState, getReduxWrapperWithStore, @@ -28,7 +28,7 @@ const THIRD_ELEMENT_ID = 300; const FOURTH_ELEMENT_ID = 400; const BASE_PUBLICATION: Publication = - PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK.data[FIRST_ARRAY_ELEMENT]; + PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK.content[FIRST_ARRAY_ELEMENT]; const BASE_ELEMENT = BASE_PUBLICATION.elements[FIRST_ARRAY_ELEMENT]; const PUBLICATION: Publication = { ...BASE_PUBLICATION, @@ -36,22 +36,22 @@ const PUBLICATION: Publication = { { ...BASE_ELEMENT, id: FIRST_ELEMENT_ID, - modelId: FIRST_MODEL_ID, + model: FIRST_MODEL_ID, }, { ...BASE_ELEMENT, id: SECOND_ELEMENT_ID, - modelId: SECOND_MODEL_ID, + model: SECOND_MODEL_ID, }, { ...BASE_ELEMENT, id: THIRD_ELEMENT_ID, - modelId: THIRD_MODEL_ID, // model id duplicate + model: THIRD_MODEL_ID, // model id duplicate }, { ...BASE_ELEMENT, id: FOURTH_ELEMENT_ID, - modelId: THIRD_MODEL_ID, // model id duplicate + model: THIRD_MODEL_ID, // model id duplicate }, ], }; @@ -77,7 +77,7 @@ jest.mock('../utils/fetchElementData'); })[id] as BioEntityContent, ); -const mockedAxiosClient = mockNetworkResponse(); +const mockedAxiosNewClient = mockNetworkNewAPIResponse(); const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => { const { Wrapper, store } = getReduxWrapperWithStore(initialStore); @@ -96,11 +96,11 @@ const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } describe('PublicationsModalLayout - component', () => { const length = 1; - mockedAxiosClient + mockedAxiosNewClient .onGet(apiPath.getPublications({ params: { length } })) .reply(HttpStatusCode.Ok, { ...PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK, - data: [PUBLICATION], + content: [PUBLICATION], }); it('should render download csv button', () => { @@ -114,7 +114,7 @@ describe('PublicationsModalLayout - component', () => { publications: { data: { ...PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK, - data: [PUBLICATION], + content: [PUBLICATION], filteredSize: length, }, loading: 'succeeded', diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.test.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.test.ts index ffa8191a..ca246ead 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.test.ts +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.test.ts @@ -1,11 +1,11 @@ import { apiPath } from '@/redux/apiPath'; -import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { HttpStatusCode } from 'axios'; import { showToast } from '@/utils/showToast'; import { PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK } from '../../../../../../models/mocks/publicationsResponseMock'; import { getBasePublications } from './getBasePublications'; -const mockedAxiosClient = mockNetworkResponse(); +const mockedAxiosNewClient = mockNetworkNewAPIResponse(); jest.mock('./../../../../../../utils/showToast'); @@ -13,17 +13,19 @@ describe('getBasePublications - util', () => { const length = 10; it('should return valid data if provided', async () => { - mockedAxiosClient + mockedAxiosNewClient .onGet(apiPath.getPublications({ params: { length } })) - .reply(HttpStatusCode.Ok, PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK); + .reply(HttpStatusCode.Ok, JSON.stringify(PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK)); const result = await getBasePublications({ length }); - expect(result).toStrictEqual(PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK.data); + expect(result).toStrictEqual( + JSON.parse(JSON.stringify(PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK.content)), + ); }); it('should return empty array if data structure is invalid', async () => { - mockedAxiosClient + mockedAxiosNewClient .onGet(apiPath.getPublications({ params: { length } })) .reply(HttpStatusCode.Ok, { randomObject: true }); @@ -33,7 +35,7 @@ describe('getBasePublications - util', () => { }); it('should return empty array and show toast error if http error', async () => { - mockedAxiosClient + mockedAxiosNewClient .onGet(apiPath.getPublications({ params: { length } })) .reply(HttpStatusCode.BadRequest); diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.ts index d149d031..e58c2f9f 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.ts +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getBasePublications.ts @@ -1,11 +1,12 @@ -import { publicationsResponseSchema } from '@/models/publicationsResponseSchema'; import { apiPath } from '@/redux/apiPath'; import { PUBLICATIONS_FETCHING_ERROR_PREFIX } from '@/redux/publications/publications.constatns'; -import { axiosInstance } from '@/services/api/utils/axiosInstance'; -import { Publication, PublicationsResponse } from '@/types/models'; +import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; +import { FilteredPageOf, Publication } from '@/types/models'; import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; import { getErrorMessage } from '@/utils/getErrorMessage'; import { showToast } from '@/utils/showToast'; +import { pageableSchema } from '@/models/pageableSchema'; +import { publicationSchema } from '@/models/publicationsSchema'; interface Args { length: number; @@ -13,13 +14,16 @@ interface Args { export const getBasePublications = async ({ length }: Args): Promise<Publication[]> => { try { - const response = await axiosInstance.get<PublicationsResponse>( + const response = await axiosInstanceNewAPI.get<FilteredPageOf<Publication>>( apiPath.getPublications({ params: { length } }), ); - const isDataValid = validateDataUsingZodSchema(response.data, publicationsResponseSchema); + const isDataValid = validateDataUsingZodSchema( + response.data, + pageableSchema(publicationSchema), + ); - return isDataValid ? response.data.data : []; + return isDataValid ? response.data.content : []; } catch (error) { const errorMessage = getErrorMessage({ error, prefix: PUBLICATIONS_FETCHING_ERROR_PREFIX }); showToast({ diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getStandarizedPublications.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getStandarizedPublications.ts index c59d2e00..894f194b 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getStandarizedPublications.ts +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/getStandarizedPublications.ts @@ -14,17 +14,17 @@ export const getStandarizedPublications = async ({ publications, modelNameIdMap, }: Args): Promise<StandarizedPublication[]> => { - const getStandarizedPublicationsFuncs = publications.map( + const getStandardizedPublicationsFuncs = publications.map( publication => () => mapBasePublicationToStandarized(publication, { modelNameIdMap, }), ); - const standarizedPublications = await runInSequence<StandarizedPublication>( - getStandarizedPublicationsFuncs, + const standardizedPublications = await runInSequence<StandarizedPublication>( + getStandardizedPublicationsFuncs, SEQUENCE_CHUNK_SIZE, ); - return standarizedPublications; + return standardizedPublications; }; diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.test.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.test.ts index 3a556eff..05cbe84f 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.test.ts +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.test.ts @@ -23,7 +23,7 @@ const MODEL_NAME_ID_MAP: Record<number, string> = { }; const BASE_PUBLICATION: Publication = - PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK.data[FIRST_ARRAY_ELEMENT]; + PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK.content[FIRST_ARRAY_ELEMENT]; const BASE_ELEMENT = BASE_PUBLICATION.elements[FIRST_ARRAY_ELEMENT]; const PUBLICATION: Publication = { ...BASE_PUBLICATION, @@ -31,22 +31,22 @@ const PUBLICATION: Publication = { { ...BASE_ELEMENT, id: FIRST_ELEMENT_ID, - modelId: FIRST_MODEL_ID, + model: FIRST_MODEL_ID, }, { ...BASE_ELEMENT, id: SECOND_ELEMENT_ID, - modelId: SECOND_MODEL_ID, + model: SECOND_MODEL_ID, }, { ...BASE_ELEMENT, id: THIRD_ELEMENT_ID, - modelId: THIRD_MODEL_ID, // model id duplicate + model: THIRD_MODEL_ID, // model id duplicate }, { ...BASE_ELEMENT, id: FOURTH_ELEMENT_ID, - modelId: THIRD_MODEL_ID, // model id duplicate + model: THIRD_MODEL_ID, // model id duplicate }, ], }; @@ -80,7 +80,7 @@ const getFuncResult = async ( describe('mapBasePublicationToStandarized - util', () => { it('should return valid pubmedId, journal, year and title', async () => { const results = await getFuncResult(PUBLICATION); - const { pubmedId, journal, year, title } = PUBLICATION.publication.article; + const { pubmedId, journal, year, title } = PUBLICATION.article; expect(results.pubmedId).toBe(pubmedId); expect(results.journal).toBe(journal); @@ -90,7 +90,7 @@ describe('mapBasePublicationToStandarized - util', () => { it('should return joined authors', async () => { const results = await getFuncResult(PUBLICATION); - const { authors } = PUBLICATION.publication.article; + const { authors } = PUBLICATION.article; expect(results.authors).toBe(authors.join(',')); }); diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.ts index 84b7d269..dea109c1 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.ts +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/mapBasePublicationToStandarized.ts @@ -13,13 +13,10 @@ export const mapBasePublicationToStandarized = async ( publication: Publication, options: Options, ): Promise<StandarizedPublication> => { - const { - publication: { article }, - elements, - } = publication; + const { article, elements } = publication; const { modelNameIdMap } = options; const { title, authors, journal, year, pubmedId } = article; - const modelNames = elements.map(({ modelId }) => modelNameIdMap[modelId]); + const modelNames = elements.map(({ model }) => modelNameIdMap[model]); const elementsData = await Promise.all(elements.map(async ({ id }) => fetchElementData(`${id}`))); const elementsIds = elementsData .filter((element): element is BioEntityContent => element !== undefined) diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/useDownloadPublicationsAsCSVFile.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/useDownloadPublicationsAsCSVFile.ts index 531faf9c..cdd58d24 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/useDownloadPublicationsAsCSVFile.ts +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModalLayout/utils/useDownloadPublicationsAsCSVFile.ts @@ -41,12 +41,12 @@ export const useDownloadPublicationsAsCSVFile = (): UseDownloadPublicationsAsCSV ? searchedPublicationsList : await getAllBasePublications(); - const standarizedPublications = await getStandarizedPublications({ + const standardizedPublications = await getStandarizedPublications({ publications, modelNameIdMap, }); - return standarizedPublications; + return standardizedPublications; }; const downloadPublicationsAsCSVFile = async (): Promise<void> => { diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/FilterBySubmapHeader/FilterBySubmapHeader.test.tsx b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/FilterBySubmapHeader/FilterBySubmapHeader.test.tsx index f238cef3..237c4c98 100644 --- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/FilterBySubmapHeader/FilterBySubmapHeader.test.tsx +++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/FilterBySubmapHeader/FilterBySubmapHeader.test.tsx @@ -3,7 +3,7 @@ import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { act } from 'react-dom/test-utils'; -import { mockNetworkResponse } from '@/utils/mockNetworkResponse'; +import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse'; import { InitialStoreState, getReduxWrapperWithStore, @@ -16,7 +16,7 @@ import { MODELS_MOCK } from '@/models/mocks/modelsMock'; import { FIRST_ARRAY_ELEMENT, ZERO } from '@/constants/common'; import { FilterBySubmapHeader } from './FilterBySubmapHeader.component'; -mockNetworkResponse(); +mockNetworkNewAPIResponse(); const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => { const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState); diff --git a/src/models/mocks/publicationsResponseMock.ts b/src/models/mocks/publicationsResponseMock.ts index c165eb98..01240a65 100644 --- a/src/models/mocks/publicationsResponseMock.ts +++ b/src/models/mocks/publicationsResponseMock.ts @@ -1,283 +1,266 @@ -import { PublicationsResponse } from '@/types/models'; +import { FilteredPageOf, Publication } from '@/types/models'; +import { bioEntityFixture } from '@/models/fixtures/bioEntityFixture'; -export const PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK: PublicationsResponse = { - data: [ +export const PUBLICATIONS_DEFAULT_SEARCH_FIRST_10_MOCK: FilteredPageOf<Publication> = { + content: [ { elements: [ { + ...bioEntityFixture, id: 19519, - modelId: 52, - type: 'REACTION', + model: 52, }, ], - publication: { - article: { - title: 'The glutamate receptor ion channels.', - authors: ['Dingledine R', ' Borges K', ' Bowie D', ' Traynelis SF.'], - journal: 'Pharmacological reviews', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10049997', - pubmedId: '10049997', - citationCount: 2458, - }, + article: { + title: 'The glutamate receptor ion channels.', + authors: ['Dingledine R', ' Borges K', ' Bowie D', ' Traynelis SF.'], + journal: 'Pharmacological reviews', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10049997', + pubmedId: '10049997', + citationCount: 2458, }, }, { elements: [ { + ...bioEntityFixture, id: 16167, - modelId: 61, - type: 'REACTION', + model: 61, }, ], - publication: { - article: { - title: 'Regulation of JNK signaling by GSTp.', - authors: [ - 'Adler V', - ' Yin Z', - ' Fuchs SY', - ' Benezra M', - ' Rosario L', - ' Tew KD', - ' Pincus MR', - ' Sardana M', - ' Henderson CJ', - ' Wolf CR', - ' Davis RJ', - ' Ronai Z.', - ], - journal: 'The EMBO journal', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10064598', - pubmedId: '10064598', - citationCount: 656, - }, + article: { + title: 'Regulation of JNK signaling by GSTp.', + authors: [ + 'Adler V', + ' Yin Z', + ' Fuchs SY', + ' Benezra M', + ' Rosario L', + ' Tew KD', + ' Pincus MR', + ' Sardana M', + ' Henderson CJ', + ' Wolf CR', + ' Davis RJ', + ' Ronai Z.', + ], + journal: 'The EMBO journal', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10064598', + pubmedId: '10064598', + citationCount: 656, }, }, { elements: [ { + ...bioEntityFixture, id: 17823, - modelId: 52, - type: 'REACTION', + model: 52, }, { + ...bioEntityFixture, id: 19461, - modelId: 52, - type: 'REACTION', + model: 52, }, ], - publication: { - article: { - title: - 'Generic signals and specific outcomes: signaling through Ca2+, calcineurin, and NF-AT.', - authors: ['Crabtree GR.'], - journal: 'Cell', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10089876', - pubmedId: '10089876', - citationCount: 454, - }, + article: { + title: + 'Generic signals and specific outcomes: signaling through Ca2+, calcineurin, and NF-AT.', + authors: ['Crabtree GR.'], + journal: 'Cell', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10089876', + pubmedId: '10089876', + citationCount: 454, }, }, { elements: [ { + ...bioEntityFixture, id: 18189, - modelId: 52, - type: 'REACTION', + model: 52, }, { + ...bioEntityFixture, id: 18729, - modelId: 52, - type: 'REACTION', + model: 52, }, ], - publication: { - article: { - title: 'G protein regulation of adenylate cyclase.', - authors: ['Simonds WF.'], - journal: 'Trends in pharmacological sciences', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10101967', - pubmedId: '10101967', - citationCount: 139, - }, + article: { + title: 'G protein regulation of adenylate cyclase.', + authors: ['Simonds WF.'], + journal: 'Trends in pharmacological sciences', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10101967', + pubmedId: '10101967', + citationCount: 139, }, }, { elements: [ { + ...bioEntityFixture, id: 16077, - modelId: 58, - type: 'REACTION', + model: 58, }, { + ...bioEntityFixture, id: 16135, - modelId: 58, - type: 'REACTION', + model: 58, }, ], - publication: { - article: { - title: - 'Akt promotes cell survival by phosphorylating and inhibiting a Forkhead transcription factor.', - authors: [ - 'Brunet A', - ' Bonni A', - ' Zigmond MJ', - ' Lin MZ', - ' Juo P', - ' Hu LS', - ' Anderson MJ', - ' Arden KC', - ' Blenis J', - ' Greenberg ME.', - ], - journal: 'Cell', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10102273', - pubmedId: '10102273', - citationCount: 4019, - }, + article: { + title: + 'Akt promotes cell survival by phosphorylating and inhibiting a Forkhead transcription factor.', + authors: [ + 'Brunet A', + ' Bonni A', + ' Zigmond MJ', + ' Lin MZ', + ' Juo P', + ' Hu LS', + ' Anderson MJ', + ' Arden KC', + ' Blenis J', + ' Greenberg ME.', + ], + journal: 'Cell', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10102273', + pubmedId: '10102273', + citationCount: 4019, }, }, { elements: [ { + ...bioEntityFixture, id: 15955, - modelId: 55, - type: 'REACTION', + model: 55, }, ], - publication: { - article: { - title: 'Ca2+-induced apoptosis through calcineurin dephosphorylation of BAD.', - authors: [ - 'Wang HG', - ' Pathan N', - ' Ethell IM', - ' Krajewski S', - ' Yamaguchi Y', - ' Shibasaki F', - ' McKeon F', - ' Bobo T', - ' Franke TF', - ' Reed JC.', - ], - journal: 'Science (New York, N.Y.)', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10195903', - pubmedId: '10195903', - citationCount: 708, - }, + article: { + title: 'Ca2+-induced apoptosis through calcineurin dephosphorylation of BAD.', + authors: [ + 'Wang HG', + ' Pathan N', + ' Ethell IM', + ' Krajewski S', + ' Yamaguchi Y', + ' Shibasaki F', + ' McKeon F', + ' Bobo T', + ' Franke TF', + ' Reed JC.', + ], + journal: 'Science (New York, N.Y.)', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10195903', + pubmedId: '10195903', + citationCount: 708, }, }, { elements: [ { + ...bioEntityFixture, id: 15937, - modelId: 55, - type: 'REACTION', + model: 55, }, { + ...bioEntityFixture, id: 15955, - modelId: 55, - type: 'REACTION', + model: 55, }, ], - publication: { - article: { - title: - 'The proapoptotic activity of the Bcl-2 family member Bim is regulated by interaction with the dynein motor complex.', - authors: ['Puthalakath H', ' Huang DC', " O'Reilly LA", ' King SM', ' Strasser A.'], - journal: 'Molecular cell', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10198631', - pubmedId: '10198631', - citationCount: 662, - }, + article: { + title: + 'The proapoptotic activity of the Bcl-2 family member Bim is regulated by interaction with the dynein motor complex.', + authors: ['Puthalakath H', ' Huang DC', " O'Reilly LA", ' King SM', ' Strasser A.'], + journal: 'Molecular cell', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10198631', + pubmedId: '10198631', + citationCount: 662, }, }, { elements: [ { + ...bioEntityFixture, id: 15948, - modelId: 55, - type: 'REACTION', + model: 55, }, ], - publication: { - article: { - title: - 'An APAF-1.cytochrome c multimeric complex is a functional apoptosome that activates procaspase-9.', - authors: ['Zou H', ' Li Y', ' Liu X', ' Wang X.'], - journal: 'The Journal of biological chemistry', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10206961', - pubmedId: '10206961', - citationCount: 1162, - }, + article: { + title: + 'An APAF-1.cytochrome c multimeric complex is a functional apoptosome that activates procaspase-9.', + authors: ['Zou H', ' Li Y', ' Liu X', ' Wang X.'], + journal: 'The Journal of biological chemistry', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10206961', + pubmedId: '10206961', + citationCount: 1162, }, }, { elements: [ { + ...bioEntityFixture, id: 16286, - modelId: 62, - type: 'REACTION', + model: 62, }, ], - publication: { - article: { - title: - 'Biochemical characterization and crystal structure determination of human heart short chain L-3-hydroxyacyl-CoA dehydrogenase provide insights into catalytic mechanism.', - authors: [ - 'Barycki JJ', - " O'Brien LK", - ' Bratt JM', - ' Zhang R', - ' Sanishvili R', - ' Strauss AW', - ' Banaszak LJ.', - ], - journal: 'Biochemistry', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10231530', - pubmedId: '10231530', - citationCount: 56, - }, + article: { + title: + 'Biochemical characterization and crystal structure determination of human heart short chain L-3-hydroxyacyl-CoA dehydrogenase provide insights into catalytic mechanism.', + authors: [ + 'Barycki JJ', + " O'Brien LK", + ' Bratt JM', + ' Zhang R', + ' Sanishvili R', + ' Strauss AW', + ' Banaszak LJ.', + ], + journal: 'Biochemistry', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10231530', + pubmedId: '10231530', + citationCount: 56, }, }, { elements: [ { + ...bioEntityFixture, id: 17780, - modelId: 52, - type: 'REACTION', + model: 52, }, { + ...bioEntityFixture, id: 17937, - modelId: 52, - type: 'REACTION', + model: 52, }, ], - publication: { - article: { - title: 'The Ca-calmodulin-dependent protein kinase cascade.', - authors: ['Soderling TR.'], - journal: 'Trends in biochemical sciences', - year: 1999, - link: 'https://www.ncbi.nlm.nih.gov/pubmed/10366852', - pubmedId: '10366852', - citationCount: 322, - }, + article: { + title: 'The Ca-calmodulin-dependent protein kinase cascade.', + authors: ['Soderling TR.'], + journal: 'Trends in biochemical sciences', + year: 1999, + link: 'https://www.ncbi.nlm.nih.gov/pubmed/10366852', + pubmedId: '10366852', + citationCount: 322, }, }, ], - totalSize: 159, + totalElements: 159, filteredSize: 1586, - length: 10, - page: 0, + size: 10, + number: 0, + numberOfElements: 10, + totalPages: 16, }; diff --git a/src/models/pageableSchema.ts b/src/models/pageableSchema.ts index 9ec3a540..4e772ffc 100644 --- a/src/models/pageableSchema.ts +++ b/src/models/pageableSchema.ts @@ -7,7 +7,7 @@ export const pageableSchema = <T extends ZodTypeAny>(type: T) => totalPages: z.number().nonnegative(), totalElements: z.number().nonnegative(), numberOfElements: z.number().nonnegative(), - size: z.number().positive(), + size: z.number().nonnegative(), number: z.number().nonnegative(), content: z.array(type), }); diff --git a/src/models/publicationsResponseSchema.ts b/src/models/publicationsResponseSchema.ts deleted file mode 100644 index 5bdcca5b..00000000 --- a/src/models/publicationsResponseSchema.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { z } from 'zod'; -import { publicationSchema } from './publicationsSchema'; - -export const publicationsResponseSchema = z.object({ - data: z.array(publicationSchema), - totalSize: z.number(), - filteredSize: z.number(), - length: z.number(), - page: z.number(), -}); diff --git a/src/models/publicationsSchema.ts b/src/models/publicationsSchema.ts index b1574088..14ac77ff 100644 --- a/src/models/publicationsSchema.ts +++ b/src/models/publicationsSchema.ts @@ -1,10 +1,8 @@ import { z } from 'zod'; -import { targetElementSchema } from './targetElementSchema'; +import { bioEntitySchema } from '@/models/bioEntitySchema'; import { articleSchema } from './articleSchema'; export const publicationSchema = z.object({ - elements: z.array(targetElementSchema), - publication: z.object({ - article: articleSchema, - }), + elements: z.array(bioEntitySchema), + article: articleSchema, }); diff --git a/src/redux/publications/publications.selectors.ts b/src/redux/publications/publications.selectors.ts index 8ed16fac..202156a9 100644 --- a/src/redux/publications/publications.selectors.ts +++ b/src/redux/publications/publications.selectors.ts @@ -11,20 +11,23 @@ export const publicationsDataSelector = createSelector( export const publicationsListDataSelector = createSelector( publicationsDataSelector, - data => data?.data, + data => data?.content, ); /** totalSize is number of pages */ -export const totalSizeSelector = createSelector(publicationsDataSelector, data => data?.totalSize); +export const totalSizeSelector = createSelector( + publicationsDataSelector, + data => data?.totalElements, +); export const filteredSizeSelector = createSelector( publicationsDataSelector, data => data?.filteredSize, ); -export const currentPageSelector = createSelector(publicationsDataSelector, data => data?.page); +export const currentPageSelector = createSelector(publicationsDataSelector, data => data?.number); export const paginationSelector = createSelector(publicationsDataSelector, data => ({ - pageIndex: data?.page || ZERO, + pageIndex: data?.number || ZERO, pageSize: 10, })); diff --git a/src/redux/publications/publications.thunks.ts b/src/redux/publications/publications.thunks.ts index 4c03def9..c173c620 100644 --- a/src/redux/publications/publications.thunks.ts +++ b/src/redux/publications/publications.thunks.ts @@ -1,23 +1,29 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema'; -import { axiosInstance } from '@/services/api/utils/axiosInstance'; -import { PublicationsResponse } from '@/types/models'; -import { publicationsResponseSchema } from '@/models/publicationsResponseSchema'; +import { axiosInstanceNewAPI } from '@/services/api/utils/axiosInstance'; import { ThunkConfig } from '@/types/store'; import { getError } from '@/utils/error-report/getError'; +import { FilteredPageOf, Publication } from '@/types/models'; +import { pageableSchema } from '@/models/pageableSchema'; +import { publicationSchema } from '@/models/publicationsSchema'; import { GetPublicationsParams } from './publications.types'; import { apiPath } from '../apiPath'; import { PUBLICATIONS_FETCHING_ERROR_PREFIX } from './publications.constatns'; export const getPublications = createAsyncThunk< - PublicationsResponse | undefined, + FilteredPageOf<Publication> | undefined, GetPublicationsParams, ThunkConfig >('publications/getPublications', async params => { try { - const response = await axiosInstance.get<PublicationsResponse>(apiPath.getPublications(params)); + const response = await axiosInstanceNewAPI.get<FilteredPageOf<Publication>>( + apiPath.getPublications(params), + ); - const isDataValid = validateDataUsingZodSchema(response.data, publicationsResponseSchema); + const isDataValid = validateDataUsingZodSchema( + response.data, + pageableSchema(publicationSchema), + ); return isDataValid ? response.data : undefined; } catch (error) { diff --git a/src/redux/publications/publications.types.ts b/src/redux/publications/publications.types.ts index 2654b800..792e7544 100644 --- a/src/redux/publications/publications.types.ts +++ b/src/redux/publications/publications.types.ts @@ -1,10 +1,10 @@ import { FetchDataState } from '@/types/fetchDataState'; -import { PublicationsResponse } from '@/types/models'; +import { FilteredPageOf, Publication } from '@/types/models'; export type SortColumn = '' | 'pubmedId' | 'title' | 'authors' | 'journal' | 'year' | 'level'; export type SortOrder = 'asc' | 'desc'; -export type PublicationsState = FetchDataState<PublicationsResponse> & { +export type PublicationsState = FetchDataState<FilteredPageOf<Publication>> & { sortColumn: SortColumn; sortOrder: SortOrder; selectedModelId?: string; diff --git a/src/types/models.ts b/src/types/models.ts index af20167b..b01270f9 100644 --- a/src/types/models.ts +++ b/src/types/models.ts @@ -49,7 +49,6 @@ import { import { overviewImageView } from '@/models/overviewImageView'; import { pluginSchema } from '@/models/pluginSchema'; import { projectSchema } from '@/models/projectSchema'; -import { publicationsResponseSchema } from '@/models/publicationsResponseSchema'; import { publicationSchema } from '@/models/publicationsSchema'; import { referenceSchema } from '@/models/referenceSchema'; import { sessionSchemaValid } from '@/models/sessionValidSchema'; @@ -150,7 +149,6 @@ export type Color = z.infer<typeof colorSchema>; export type Statistics = z.infer<typeof statisticsSchema>; export type CompartmentPathway = z.infer<typeof compartmentPathwaySchema>; export type CompartmentPathwayDetails = z.infer<typeof compartmentPathwayDetailsSchema>; -export type PublicationsResponse = z.infer<typeof publicationsResponseSchema>; export type Publication = z.infer<typeof publicationSchema>; export type ExportNetwork = z.infer<typeof exportNetworkchema>; export type ExportElements = z.infer<typeof exportElementsSchema>; @@ -180,4 +178,8 @@ export type PageOf<T> = { content: T[]; }; +export type FilteredPageOf<T> = PageOf<T> & { + filteredSize: number; +}; + export type OAuth = z.infer<typeof oauthSchema>; -- GitLab