From 371dd484e233a1148bf62e929e2199e83e38c33b Mon Sep 17 00:00:00 2001 From: Florent Date: Wed, 27 Sep 2023 16:06:38 +0200 Subject: [PATCH 1/9] refactor: add useAddDataToBatches and normalizeBatchesWithData --- .../src/hooks/batches/useAddDataToBatches.tsx | 130 ++++++++++++++++++ web-marketplace/src/lib/ecocredit/api.ts | 3 +- .../batches/normalizeBatchesWithData.ts | 79 +++++++++++ .../getAddDataToBatchesQuery.ts | 1 + 4 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 web-marketplace/src/hooks/batches/useAddDataToBatches.tsx create mode 100644 web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts diff --git a/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx b/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx new file mode 100644 index 0000000000..aafa0e970b --- /dev/null +++ b/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx @@ -0,0 +1,130 @@ +import { useQueries, useQuery } from '@tanstack/react-query'; + +import { client as sanityClient } from 'lib/clients/sanity'; +import { AddDataToBatchesParams } from 'lib/ecocredit/api'; +import { + ECOCREDIT_MESSAGE_TYPES, + messageActionEquals, +} from 'lib/ecocredit/constants'; +import { normalizeBatchesWithData } from 'lib/normalizers/batches/normalizeBatchesWithData'; +import { getGetTxsEventQuery } from 'lib/queries/react-query/cosmos/bank/getTxsEventQuery/getTxsEventQuery'; +import { getClassQuery } from 'lib/queries/react-query/ecocredit/getClassQuery/getClassQuery'; +import { getProjectQuery } from 'lib/queries/react-query/ecocredit/getProjectQuery/getProjectQuery'; +import { getSupplyQuery } from 'lib/queries/react-query/ecocredit/getSupplyQuery/getSupplyQuery'; +import { getMetadataQuery } from 'lib/queries/react-query/registry-server/getMetadataQuery/getMetadataQuery'; +import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; + +type Props = AddDataToBatchesParams; + +export const useAddDataToBatches = ({ + txClient, + batches, + ecocreditClient, + dataClient, + withAllData, +}: Props) => { + const { + data: sanityCreditClassData, + isFetching: isLoadingSanityCreditClass, + } = useQuery( + getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), + ); + + const { data: createBatchTxs, isFetching: isLoadingCreateBatchTxs } = + useQuery( + getGetTxsEventQuery({ + client: txClient, + enabled: !!txClient, + request: { + events: [ + `${messageActionEquals}'${ECOCREDIT_MESSAGE_TYPES.CREATE_BATCH.message}'`, + ], + }, + }), + ); + const { + data: createBatchAlphaTxs, + isFetching: isLoadingCreateBatchAlphaTxs, + } = useQuery( + getGetTxsEventQuery({ + client: txClient, + enabled: !!txClient, + request: { + events: [ + `${messageActionEquals}'${ECOCREDIT_MESSAGE_TYPES.CREATE_BATCH_ALPHA.message}'`, + ], + }, + }), + ); + + const batchesSupplyResult = useQueries({ + queries: batches.map(batch => + getSupplyQuery({ + request: { batchDenom: batch.denom }, + }), + ), + }); + + const batchesProjectDataResult = useQueries({ + queries: batches.map(batch => + getProjectQuery({ + request: { projectId: batch.projectId }, + client: ecocreditClient, + enabled: !!ecocreditClient && withAllData, + }), + ), + }); + + const batchesProjectMetadataResult = useQueries({ + queries: batches.map((batch, index) => { + const project = batchesProjectDataResult?.[index].data?.project; + return getMetadataQuery({ + iri: project?.metadata, + dataClient, + enabled: !!dataClient && !!project?.metadata && withAllData, + }); + }), + }); + + const batchesClassResult = useQueries({ + queries: batches.map((batch, index) => { + const project = batchesProjectDataResult?.[index].data?.project; + return getClassQuery({ + request: { classId: project?.classId }, + client: ecocreditClient, + enabled: !!ecocreditClient && !!project?.classId && withAllData, + }); + }), + }); + + const batchesClassMetadataResult = useQueries({ + queries: batches.map((batch, index) => { + const creditClass = batchesClassResult?.[index].data?.class; + + return getMetadataQuery({ + iri: creditClass?.metadata, + dataClient, + enabled: !!dataClient && !!creditClass?.metadata && withAllData, + }); + }), + }); + + const batchesWithData = normalizeBatchesWithData({ + batches, + batchesClassMetadataResult, + batchesProjectDataResult, + batchesProjectMetadataResult, + batchesSupplyResult, + createBatchAlphaTxs, + createBatchTxs, + sanityCreditClassData, + }); + + return { + batchesWithData, + isLoadingBatchesWithData: + isLoadingSanityCreditClass || + isLoadingCreateBatchAlphaTxs || + isLoadingCreateBatchTxs, + }; +}; diff --git a/web-marketplace/src/lib/ecocredit/api.ts b/web-marketplace/src/lib/ecocredit/api.ts index 43581af3fb..f99611bad1 100644 --- a/web-marketplace/src/lib/ecocredit/api.ts +++ b/web-marketplace/src/lib/ecocredit/api.ts @@ -315,6 +315,7 @@ export type AddDataToBatchesParams = { withAllData?: boolean; dataClient?: DataQueryClientImpl; ecocreditClient?: EcocreditQueryClientImpl; + txClient?: ServiceClientImpl; reactQueryClient?: QueryClient; }; @@ -386,7 +387,7 @@ export const addDataToBatches = async ({ } }; -const getTxHashForBatch = ( +export const getTxHashForBatch = ( txResponses: TxResponse[], log: string, ): string | undefined => { diff --git a/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts b/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts new file mode 100644 index 0000000000..8e8304607a --- /dev/null +++ b/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts @@ -0,0 +1,79 @@ +import { GetTxsEventResponse } from '@regen-network/api/lib/generated/cosmos/tx/v1beta1/service'; +import { + BatchInfo, + QueryProjectResponse, + QuerySupplyResponse, +} from '@regen-network/api/lib/generated/regen/ecocredit/v1/query'; +import { UseQueryResult } from '@tanstack/react-query'; + +import { AllCreditClassQuery } from 'generated/sanity-graphql'; +import { + AnchoredProjectMetadataLD, + CreditClassMetadataLD, +} from 'lib/db/types/json-ld'; +import { getTxHashForBatch } from 'lib/ecocredit/api'; +import { v1Alpha1BatchDenomMapping } from 'lib/ecocredit/ecocredit.config'; + +import { findSanityCreditClass } from 'components/templates/ProjectDetails/ProjectDetails.utils'; + +type Props = { + sanityCreditClassData?: AllCreditClassQuery; + batches: BatchInfo[]; + createBatchTxs?: GetTxsEventResponse | null; + createBatchAlphaTxs?: GetTxsEventResponse | null; + batchesSupplyResult?: UseQueryResult[]; + batchesProjectDataResult?: UseQueryResult[]; + batchesProjectMetadataResult?: UseQueryResult< + AnchoredProjectMetadataLD | CreditClassMetadataLD + >[]; + batchesClassMetadataResult: UseQueryResult< + AnchoredProjectMetadataLD | CreditClassMetadataLD + >[]; +}; + +export const normalizeBatchesWithData = ({ + batches, + batchesClassMetadataResult, + batchesProjectDataResult, + batchesProjectMetadataResult, + batchesSupplyResult, + createBatchAlphaTxs, + createBatchTxs, + sanityCreditClassData, +}: Props) => { + const normalizedBatches = batches.map((batch, index) => { + const txhash = + getTxHashForBatch(createBatchTxs?.txResponses ?? [], batch.denom) ?? + getTxHashForBatch( + createBatchAlphaTxs?.txResponses ?? [], + v1Alpha1BatchDenomMapping[batch.denom], + ); + + const supplyData = batchesSupplyResult?.[index] ?? {}; + const project = batchesProjectDataResult?.[index].data?.project; + const classMetadata = batchesClassMetadataResult?.[index]; + const projectMetadata = batchesProjectMetadataResult?.[index]; + + const creditClassSanity = findSanityCreditClass({ + sanityCreditClassData, + creditClassIdOrUrl: project?.classId ?? '', + }); + + const classProjectInfo = { + classId: project?.classId, + className: + classMetadata?.data?.['schema:name'] ?? creditClassSanity?.nameRaw, + projectName: projectMetadata?.data?.['schema:name'] ?? batch.projectId, + projectLocation: project?.jurisdiction, + }; + + return { + ...batch, + ...classProjectInfo, + ...supplyData, + txhash, + }; + }); + + return normalizedBatches; +}; diff --git a/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts b/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts index 4e5ba40189..dc80139d05 100644 --- a/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts +++ b/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts @@ -10,6 +10,7 @@ export const getAddDataToBatchesQuery = ({ sanityCreditClassData, reactQueryClient, dataClient, + txClient, ecocreditClient, ...params }: ReactQueryAddDataToBatchesParams): ReactQueryAddDataToBatchesResponse => ({ From bdadbf709a117ea222a312737ec84314044a4da4 Mon Sep 17 00:00:00 2001 From: Florent Date: Wed, 27 Sep 2023 17:18:33 +0200 Subject: [PATCH 2/9] refactor: replace addDataToBatches everywhere --- .../organisms/CreditBatches/CreditBatches.tsx | 1 - .../hooks/useFetchCreditBatches.tsx | 29 ++-- .../ProjectDetails/hooks/useBatches.ts | 49 ------- .../hooks/batches/useBatchesWithSupply.tsx | 136 ------------------ .../src/hooks/batches/usePaginatedBatches.ts | 23 ++- .../batches/usePaginatedBatchesByIssuer.ts | 67 +++++++-- .../batches/usePaginatedBatchesByProject.ts | 24 ++-- web-marketplace/src/lib/ecocredit/api.ts | 92 +----------- .../batches/normalizeBatchesWithData.ts | 6 +- .../getAddDataToBatchesQuery.ts | 32 ----- .../getAddDataToBatchesQuery.types.ts | 18 --- .../getBatchesByIssuerQuery.constants.ts | 16 +++ .../getBatchesByIssuerQuery.ts | 24 ++++ .../getBatchesByIssuerQuery.types.ts | 16 +++ .../MyCreditBatches/MyCreditBatches.tsx | 4 +- 15 files changed, 155 insertions(+), 382 deletions(-) delete mode 100644 web-marketplace/src/components/templates/ProjectDetails/hooks/useBatches.ts delete mode 100644 web-marketplace/src/hooks/batches/useBatchesWithSupply.tsx delete mode 100644 web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts delete mode 100644 web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.types.ts create mode 100644 web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.constants.ts create mode 100644 web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.ts create mode 100644 web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.types.ts diff --git a/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx b/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx index 2f23ec84d6..ebd2db06a3 100644 --- a/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx +++ b/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx @@ -62,7 +62,6 @@ const CreditBatches: React.FC> = ({ creditBatches, creditClassId, }); - let columnsToShow = [...creditBatchesHeadCells]; // We hide the classId column if creditClassId provided (redundant) diff --git a/web-marketplace/src/components/organisms/CreditBatches/hooks/useFetchCreditBatches.tsx b/web-marketplace/src/components/organisms/CreditBatches/hooks/useFetchCreditBatches.tsx index d5db0b1e60..5117e5a45f 100644 --- a/web-marketplace/src/components/organisms/CreditBatches/hooks/useFetchCreditBatches.tsx +++ b/web-marketplace/src/components/organisms/CreditBatches/hooks/useFetchCreditBatches.tsx @@ -3,11 +3,12 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; import { useLedger } from 'ledger'; import { client as sanityClient } from 'lib/clients/sanity'; -import { getAddDataToBatchesQuery } from 'lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery'; import { getBatchesByClassQuery } from 'lib/queries/react-query/ecocredit/getBatchesByClass/getBatchesByClass'; import { getBatchesQuery } from 'lib/queries/react-query/ecocredit/getBatchesQuery/getBatchesQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; +import { useAddDataToBatches } from 'hooks/batches/useAddDataToBatches'; + type Params = { creditClassId?: string | null; creditBatches?: BatchInfoWithSupply[]; @@ -39,30 +40,26 @@ export const useFetchCreditBatches = ({ }), ); - const batches = batchesData?.batches ?? batchesByClassData?.batches; + const batches = batchesData?.batches ?? batchesByClassData?.batches ?? []; const sanityCreditClassDataResult = useQuery( getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), ); - const { data: batchesWithSupplyData, isFetching: isLoadingAddDataToBatches } = - useQuery( - getAddDataToBatchesQuery({ - batches, - sanityCreditClassData: sanityCreditClassDataResult.data, - enabled: !!sanityCreditClassDataResult.data, - reactQueryClient, - dataClient, - ecocreditClient, - withAllData, - }), - ); + const { batchesWithData, isLoadingBatchesWithData } = useAddDataToBatches({ + batches, + sanityCreditClassData: sanityCreditClassDataResult.data, + reactQueryClient, + dataClient, + ecocreditClient, + withAllData, + }); - const batchesWithSupply = batchesWithSupplyData ?? creditBatches; + const batchesWithSupply = creditBatches ?? batchesWithData; return { batchesWithSupply, isLoading: - isLoadingAddDataToBatches || isLoadingBatches || isLoadingBatchesByClass, + isLoadingBatchesWithData || isLoadingBatches || isLoadingBatchesByClass, }; }; diff --git a/web-marketplace/src/components/templates/ProjectDetails/hooks/useBatches.ts b/web-marketplace/src/components/templates/ProjectDetails/hooks/useBatches.ts deleted file mode 100644 index a70b7e825c..0000000000 --- a/web-marketplace/src/components/templates/ProjectDetails/hooks/useBatches.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { useEffect, useState } from 'react'; - -import { Maybe } from '../../../../generated/graphql'; -import { useLedger } from '../../../../ledger'; -import { - getBatchesByProjectWithSupply, - getBatchesTotal, -} from '../../../../lib/ecocredit/api'; -import { - BatchInfoWithSupply, - BatchTotalsForProject, -} from '../../../../types/ledger/ecocredit'; - -interface InputProps { - projectId: Maybe | undefined; -} -export default function useBatches({ projectId }: InputProps): { - batchData: BatchInfoWithSupply[]; - batchTotals: BatchTotalsForProject | undefined; -} { - const [batchData, setBatchData] = useState([]); - const [batchTotals, setBatchTotals] = useState(); - const { dataClient, ecocreditClient } = useLedger(); - - useEffect(() => { - const fetchData = async (): Promise => { - try { - let batches: BatchInfoWithSupply[] = []; - if (projectId) { - const { data } = await getBatchesByProjectWithSupply( - projectId, - dataClient, - ecocreditClient, - ); - batches = data; - } - - const { totals } = await getBatchesTotal(batches); - setBatchData(batches); - setBatchTotals(totals); - } catch (err) { - console.error(err); // eslint-disable-line no-console - } - }; - fetchData(); - }, [dataClient, ecocreditClient, projectId]); - - return { batchData, batchTotals }; -} diff --git a/web-marketplace/src/hooks/batches/useBatchesWithSupply.tsx b/web-marketplace/src/hooks/batches/useBatchesWithSupply.tsx deleted file mode 100644 index fe15a22647..0000000000 --- a/web-marketplace/src/hooks/batches/useBatchesWithSupply.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { useEffect, useState } from 'react'; -import { BatchInfo } from '@regen-network/api/lib/generated/regen/ecocredit/v1/query'; - -import { TablePaginationParams } from 'web-components/lib/components/table/ActionsTable'; - -import { useAllCreditClassQuery } from 'generated/sanity-graphql'; -import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; -import { addDataToBatches } from 'lib/ecocredit/api'; - -import { useLedger } from '../../ledger'; -import { client as sanityClient } from '../../lib/clients/sanity'; - -type Props = { - batches?: BatchInfo[]; - paginationParams?: TablePaginationParams; -}; - -export const useBatchesWithSupply = ({ - batches, - paginationParams, -}: Props): BatchInfoWithSupply[] | undefined => { - const [batchesWithSupply, setBatchesWithSupply] = useState< - BatchInfoWithSupply[] | undefined - >(); - const { dataClient, ecocreditClient } = useLedger(); - - const { data: sanityCreditClassData } = useAllCreditClassQuery({ - client: sanityClient, - }); - - useEffect(() => { - // Initialize batches with empty supply to render components consuming data right away - if (batches && !batchesWithSupply) { - const batchesWithDefaultSupply: BatchInfoWithSupply[] = batches.map( - batch => ({ - ...batch, - cancelledAmount: '', - retiredAmount: '', - tradableAmount: '', - }), - ); - - setBatchesWithSupply(batchesWithDefaultSupply); - } - }, [batches, batchesWithSupply]); - - useEffect(() => { - // this variable is used to prevent race condition - let ignore = false; - const addSupplyToBatches = async (): Promise => { - // Fetch one page of batches - if ( - batches && - batchesWithSupply && - paginationParams && - sanityCreditClassData - ) { - const { offset, rowsPerPage } = paginationParams; - // current page batches - const displayedBatches = batches.slice(offset, offset + rowsPerPage); - try { - // add supply to page batches - const newBatchesWithData = await addDataToBatches({ - batches: displayedBatches, - sanityCreditClassData, - dataClient, - ecocreditClient, - }); - if (!ignore) { - // merge new batches into state variable - setBatchesWithSupply([ - ...batchesWithSupply.slice(0, offset), - ...newBatchesWithData, - ...batchesWithSupply.slice( - offset + rowsPerPage, - batchesWithSupply.length, - ), - ]); - } - } catch { - // eslint-disable-next-line no-console - console.error('error while fetching batch supply with pagination'); - } - } else if (batches) { - // Fetch all batches - try { - const batchesWithSupply = await addDataToBatches({ - batches, - dataClient, - ecocreditClient, - }); - if (!ignore) { - setBatchesWithSupply(batchesWithSupply); - } - } catch { - // eslint-disable-next-line no-console - console.error('error while fetching batch supply'); - } - } - }; - - let shouldFetch = false; - - if (paginationParams && batchesWithSupply) { - // Fetch only one page of batches if current page has at least one row without supply - const { offset, rowsPerPage } = paginationParams; - const displayedBatches = batchesWithSupply.slice( - offset, - offset + rowsPerPage, - ); - shouldFetch = displayedBatches.some(batch => batch.tradableAmount === ''); - } else if (batchesWithSupply) { - // Fetch all batches if at least one row without supply - shouldFetch = batchesWithSupply.some( - batch => batch.tradableAmount === '', - ); - } - - if (shouldFetch) { - addSupplyToBatches(); - } - - return () => { - ignore = true; - }; - }, [ - batches, - batchesWithSupply, - dataClient, - ecocreditClient, - paginationParams, - sanityCreditClassData, - ]); - - return batchesWithSupply; -}; diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatches.ts b/web-marketplace/src/hooks/batches/usePaginatedBatches.ts index 246f4ae8ac..0a7fa5fe63 100644 --- a/web-marketplace/src/hooks/batches/usePaginatedBatches.ts +++ b/web-marketplace/src/hooks/batches/usePaginatedBatches.ts @@ -7,11 +7,11 @@ import { TablePaginationParams } from 'web-components/lib/components/table/Actio import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; import { UseStateSetter } from 'types/react/use-state'; import { useLedger } from 'ledger'; -import { getAddDataToBatchesQuery } from 'lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery'; import { getBatchesQuery } from 'lib/queries/react-query/ecocredit/getBatchesQuery/getBatchesQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; import { client as sanityClient } from '../../lib/clients/sanity'; +import { useAddDataToBatches } from './useAddDataToBatches'; export const PAGINATED_BATCHES_ROWS_PER_PAGE = 10; @@ -55,17 +55,15 @@ export const usePaginatedBatches = (): { /* Fetch current page batches supplies */ - const batches = batchesResult.data?.batches; - const batchesWithSupplyResult = useQuery( - getAddDataToBatchesQuery({ - batches, - sanityCreditClassData: sanityCreditClassDataResult.data, - enabled: !!sanityCreditClassDataResult.data, - reactQueryClient, - dataClient, - ecocreditClient, - }), - ); + const batches = batchesResult.data?.batches ?? []; + const { batchesWithData: batchesWithSupply } = useAddDataToBatches({ + batches, + sanityCreditClassData: sanityCreditClassDataResult.data, + reactQueryClient, + dataClient, + ecocreditClient, + withAllData: true, + }); /* Format hook returned variables */ @@ -78,7 +76,6 @@ export const usePaginatedBatches = (): { retiredAmount: '', tradableAmount: '', })); - const batchesWithSupply = batchesWithSupplyResult.data; return { batchesWithSupply: batchesWithSupply ?? batchesWithDefaultSupply, diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts b/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts index 4182093c93..0beabcaa8b 100644 --- a/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts +++ b/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts @@ -1,15 +1,17 @@ import { useState } from 'react'; -import { QueryBatchesByIssuerResponse } from '@regen-network/api/lib/generated/regen/ecocredit/v1/query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { TablePaginationParams } from 'web-components/lib/components/table/ActionsTable'; import { DEFAULT_ROWS_PER_PAGE } from 'web-components/src/components/table/Table.constants'; import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; import { UseStateSetter } from 'types/react/use-state'; +import { useLedger } from 'ledger'; +import { getBatchesByIssuerQuery } from 'lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery'; +import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; -import useEcocreditQuery from 'hooks/useEcocreditQuery'; - -import { useBatchesWithSupply } from './useBatchesWithSupply'; +import { client as sanityClient } from '../../lib/clients/sanity'; +import { useAddDataToBatches } from './useAddDataToBatches'; type Props = { address?: string }; @@ -18,21 +20,62 @@ export const usePaginatedBatchesByIssuer = ({ }: Props): { batchesWithSupply: BatchInfoWithSupply[] | undefined; setPaginationParams: UseStateSetter; + paginationParams: TablePaginationParams; } => { + const { ecocreditClient, dataClient } = useLedger(); + const reactQueryClient = useQueryClient(); const [paginationParams, setPaginationParams] = useState({ page: 0, rowsPerPage: DEFAULT_ROWS_PER_PAGE, offset: 0, }); - const batchesResponse = useEcocreditQuery({ - params: { issuer: address }, - query: 'batchesByIssuer', - }); - const batchesWithSupply = useBatchesWithSupply({ - batches: batchesResponse?.data?.batches, - paginationParams, + const { rowsPerPage, page } = paginationParams; + + const sanityCreditClassDataResult = useQuery( + getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), + ); + + const batchesByIssuerResult = useQuery( + getBatchesByIssuerQuery({ + client: ecocreditClient, + request: { + pagination: { + offset: page * rowsPerPage, + limit: rowsPerPage, + countTotal: true, + }, + issuer: address, + }, + keepPreviousData: true, + enabled: !!ecocreditClient && !!address, + }), + ); + + const batches = batchesByIssuerResult.data?.batches ?? []; + + const { batchesWithData: batchesWithSupply } = useAddDataToBatches({ + batches, + sanityCreditClassData: sanityCreditClassDataResult.data, + reactQueryClient, + dataClient, + ecocreditClient, + withAllData: true, }); - return { batchesWithSupply, setPaginationParams }; + const batchesPagination = batchesByIssuerResult.data?.pagination; + const allBatchesCount = Number(batchesPagination?.total ?? 0); + const batchesWithDefaultSupply: BatchInfoWithSupply[] | undefined = + batches?.map(batch => ({ + ...batch, + cancelledAmount: '', + retiredAmount: '', + tradableAmount: '', + })); + + return { + batchesWithSupply: batchesWithSupply ?? batchesWithDefaultSupply, + setPaginationParams, + paginationParams: { ...paginationParams, count: allBatchesCount }, + }; }; diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts b/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts index 64b3d74802..6321988215 100644 --- a/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts +++ b/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts @@ -6,11 +6,11 @@ import { TablePaginationParams } from 'web-components/lib/components/table/Actio import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; import { UseStateSetter } from 'types/react/use-state'; import { useLedger } from 'ledger'; -import { getAddDataToBatchesQuery } from 'lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery'; import { getBatchesByProjectQuery } from 'lib/queries/react-query/ecocredit/getBatchesByProjectQuery/getBatchesByProjectQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; import { client as sanityClient } from '../../lib/clients/sanity'; +import { useAddDataToBatches } from './useAddDataToBatches'; export const PAGINATED_BATCHES_BY_PROJECT_ROWS_PER_PAGE = 5; @@ -56,17 +56,16 @@ export const usePaginatedBatchesByProject = ({ /* Fetch current page batches supplies */ - const batches = batchesByProjectResult.data?.batches; - const batchesWithSupplyResult = useQuery( - getAddDataToBatchesQuery({ - batches, - sanityCreditClassData: sanityCreditClassDataResult.data, - enabled: !!sanityCreditClassDataResult.data, - reactQueryClient, - dataClient, - ecocreditClient, - }), - ); + const batches = batchesByProjectResult.data?.batches ?? []; + + const { batchesWithData: batchesWithSupply } = useAddDataToBatches({ + batches, + sanityCreditClassData: sanityCreditClassDataResult.data, + reactQueryClient, + dataClient, + ecocreditClient, + withAllData: true, + }); /* Format hook returned variables */ @@ -79,7 +78,6 @@ export const usePaginatedBatchesByProject = ({ retiredAmount: '', tradableAmount: '', })); - const batchesWithSupply = batchesWithSupplyResult.data; return { batchesWithSupply: batchesWithSupply ?? batchesWithDefaultSupply, diff --git a/web-marketplace/src/lib/ecocredit/api.ts b/web-marketplace/src/lib/ecocredit/api.ts index f99611bad1..a846951507 100644 --- a/web-marketplace/src/lib/ecocredit/api.ts +++ b/web-marketplace/src/lib/ecocredit/api.ts @@ -198,27 +198,6 @@ export const getEcocreditsForAccount = async ({ } }; -export const getBatchesByProjectWithSupply = async ( - projectId?: string | null, - dataClient?: DataQueryClientImpl, - ecocreditClient?: EcocreditQueryClientImpl, -): Promise<{ - data: BatchInfoWithSupply[]; -}> => { - if (!projectId) return Promise.resolve({ data: [] }); - const client = await getQueryClient(); - const batches = await queryBatchesByProject({ - client, - request: { projectId }, - }); - const batchesWithData = await addDataToBatches({ - batches: batches?.batches, - dataClient, - ecocreditClient, - }); - return { data: batchesWithData }; -}; - const getClassProjectForBatch = async ( batch: BatchInfo, sanityCreditClassData?: AllCreditClassQuery, @@ -319,74 +298,6 @@ export type AddDataToBatchesParams = { reactQueryClient?: QueryClient; }; -/* addDataToBatches adds Tx Hash and supply info to batch for use in tables */ -export const addDataToBatches = async ({ - batches, - sanityCreditClassData, - withAllData = true, - dataClient, - ecocreditClient, - reactQueryClient, -}: AddDataToBatchesParams): Promise => { - try { - /* TODO: this is limited to 100 results. We need to find a better way */ - const [createBatchTxs, createBatchAlphaTxs] = await Promise.all([ - getTxsByEvent({ - events: [ - `${messageActionEquals}'${ECOCREDIT_MESSAGE_TYPES.CREATE_BATCH.message}'`, - ], - }), - getTxsByEvent({ - events: [ - `${messageActionEquals}'${ECOCREDIT_MESSAGE_TYPES.CREATE_BATCH_ALPHA.message}'`, - ], - }), - ]); - - return Promise.all( - batches.map(async batch => { - let txhash, supplyData, classProjectInfo; - - if (reactQueryClient) { - supplyData = (await getFromCacheOrFetch({ - query: getSupplyQuery({ - request: { batchDenom: batch.denom }, - }), - reactQueryClient, - })) as QuerySupplyResponse; - } else { - supplyData = await queryEcoBatchSupply(batch.denom); - } - - if (withAllData) { - txhash = - getTxHashForBatch(createBatchTxs.txResponses, batch.denom) ?? - getTxHashForBatch( - createBatchAlphaTxs.txResponses, - v1Alpha1BatchDenomMapping[batch.denom], - ); - classProjectInfo = await getClassProjectForBatch( - batch, - sanityCreditClassData, - dataClient, - ecocreditClient, - reactQueryClient, - ); - } - - return { - ...batch, - ...classProjectInfo, - ...supplyData, - txhash, - }; - }), - ); - } catch (err) { - throw new Error(`Could not add data to batches batches: ${err}`); - } -}; - export const getTxHashForBatch = ( txResponses: TxResponse[], log: string, @@ -788,7 +699,7 @@ export const queryBatchesByClass = async ({ // BatchesByIssuer -interface QueryBatchesByIssuerProps extends EcocreditQueryClientProps { +export interface QueryBatchesByIssuerProps extends EcocreditQueryClientProps { request: DeepPartial; } @@ -799,6 +710,7 @@ export const queryBatchesByIssuer = async ({ try { return await client.BatchesByIssuer({ issuer: request.issuer, + pagination: request.pagination, }); } catch (err) { throw new Error( diff --git a/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts b/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts index 8e8304607a..cd5ea1c8f9 100644 --- a/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts +++ b/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts @@ -49,7 +49,11 @@ export const normalizeBatchesWithData = ({ v1Alpha1BatchDenomMapping[batch.denom], ); - const supplyData = batchesSupplyResult?.[index] ?? {}; + const supplyData = batchesSupplyResult?.[index].data ?? { + cancelledAmount: '', + retiredAmount: '', + tradableAmount: '', + }; const project = batchesProjectDataResult?.[index].data?.project; const classMetadata = batchesClassMetadataResult?.[index]; const projectMetadata = batchesProjectMetadataResult?.[index]; diff --git a/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts b/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts deleted file mode 100644 index dc80139d05..0000000000 --- a/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { addDataToBatches } from 'lib/ecocredit/api'; - -import { - ReactQueryAddDataToBatchesParams, - ReactQueryAddDataToBatchesResponse, -} from './getAddDataToBatchesQuery.types'; - -export const getAddDataToBatchesQuery = ({ - batches, - sanityCreditClassData, - reactQueryClient, - dataClient, - txClient, - ecocreditClient, - ...params -}: ReactQueryAddDataToBatchesParams): ReactQueryAddDataToBatchesResponse => ({ - queryKey: ['addDataToBatches', batches?.map(batch => batch.denom).join(',')], - queryFn: async () => { - if (!batches) return null; - - const batchesWithSupply = await addDataToBatches({ - batches, - sanityCreditClassData, - reactQueryClient, - dataClient, - ecocreditClient, - }); - - return batchesWithSupply; - }, - ...params, -}); diff --git a/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.types.ts b/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.types.ts deleted file mode 100644 index 8d5ff2a9a9..0000000000 --- a/web-marketplace/src/lib/queries/react-query/ecocredit/getAddDataToBatchesQuery/getAddDataToBatchesQuery.types.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { QueryClient, QueryObserverOptions } from '@tanstack/react-query'; - -import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; -import { AddDataToBatchesParams } from 'lib/ecocredit/api'; - -import { ReactQueryBuilderResponse } from '../../types/react-query.types'; - -export type ReactQueryAddDataToBatchesResponse = QueryObserverOptions< - BatchInfoWithSupply[] | null ->; - -export type ReactQueryAddDataToBatchesParams = Omit< - AddDataToBatchesParams, - 'batches' -> & { - batches?: AddDataToBatchesParams['batches']; - reactQueryClient?: QueryClient; -} & ReactQueryBuilderResponse; diff --git a/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.constants.ts b/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.constants.ts new file mode 100644 index 0000000000..35e1afba48 --- /dev/null +++ b/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.constants.ts @@ -0,0 +1,16 @@ +type GetBatchesByProjectKey = { + issuer: string; + offset: string; + limit: string; +}; + +export const getBatchesByIssuerKey = ({ + issuer, + offset, + limit, +}: GetBatchesByProjectKey): string[] => [ + 'batchesByIssuer', + issuer, + offset, + limit, +]; diff --git a/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.ts b/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.ts new file mode 100644 index 0000000000..3fb81046bd --- /dev/null +++ b/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.ts @@ -0,0 +1,24 @@ +import { queryBatchesByIssuer } from 'lib/ecocredit/api'; + +import { getBatchesByIssuerKey } from './getBatchesByIssuerQuery.constants'; +import { + ReactQueryBatchesByIssuerProps, + ReactQueryBatchesByIssuerResponse, +} from './getBatchesByIssuerQuery.types'; + +export const getBatchesByIssuerQuery = ({ + client, + request, + ...params +}: ReactQueryBatchesByIssuerProps): ReactQueryBatchesByIssuerResponse => ({ + queryKey: getBatchesByIssuerKey({ + issuer: request.issuer ?? '', + offset: String(request.pagination?.offset), + limit: String(request.pagination?.limit), + }), + queryFn: async () => { + if (!client) return; + return await queryBatchesByIssuer({ client, request }); + }, + ...params, +}); diff --git a/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.types.ts b/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.types.ts new file mode 100644 index 0000000000..699369b4d0 --- /dev/null +++ b/web-marketplace/src/lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery.types.ts @@ -0,0 +1,16 @@ +import { QueryBatchesByIssuerResponse } from '@regen-network/api/lib/generated/regen/ecocredit/v1/query'; +import { QueryObserverOptions } from '@tanstack/react-query'; + +import { QueryBatchesByIssuerProps } from 'lib/ecocredit/api'; + +import { ReactQueryBuilderResponse } from '../../types/react-query.types'; + +export type ReactQueryBatchesByIssuerResponse = + QueryObserverOptions; + +export type ReactQueryBatchesByIssuerProps = Omit< + QueryBatchesByIssuerProps, + 'client' +> & { + client?: QueryBatchesByIssuerProps['client']; +} & ReactQueryBuilderResponse; diff --git a/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx b/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx index 6b3b9b7e98..dfc99a5360 100644 --- a/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx +++ b/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx @@ -19,7 +19,7 @@ import { NO_CREDIT_BATCHES_MESSAGE } from './MyCreditBatches.constants'; export const MyCreditBatches = (): JSX.Element => { const theme = useTheme(); const { wallet } = useWallet(); - const { batchesWithSupply, setPaginationParams } = + const { batchesWithSupply, setPaginationParams, paginationParams } = usePaginatedBatchesByIssuer({ address: wallet?.address }); const hasNoBatches = batchesWithSupply && batchesWithSupply?.length === 0; @@ -63,6 +63,8 @@ export const MyCreditBatches = (): JSX.Element => { From 8dd1dc3c0dd3c51f395b31a50b4338145caad871 Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 28 Sep 2023 09:37:58 +0200 Subject: [PATCH 3/9] refactor: merge hooks for paginated batches --- .../ProjectDetails/ProjectDetails.tsx | 4 +- .../src/hooks/batches/usePaginatedBatches.ts | 61 ++++++++++--- .../batches/usePaginatedBatchesByIssuer.ts | 81 ----------------- .../batches/usePaginatedBatchesByProject.ts | 87 ------------------- .../MyCreditBatches/MyCreditBatches.tsx | 4 +- .../EcocreditBatches/EcocreditBatches.tsx | 2 +- 6 files changed, 55 insertions(+), 184 deletions(-) delete mode 100644 web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts delete mode 100644 web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts diff --git a/web-marketplace/src/components/templates/ProjectDetails/ProjectDetails.tsx b/web-marketplace/src/components/templates/ProjectDetails/ProjectDetails.tsx index 17e2aac80b..7110da225a 100644 --- a/web-marketplace/src/components/templates/ProjectDetails/ProjectDetails.tsx +++ b/web-marketplace/src/components/templates/ProjectDetails/ProjectDetails.tsx @@ -42,7 +42,7 @@ import { useAllSoldOutProjectsIds } from 'components/organisms/ProjectCardsSecti import { ProjectStorySection } from 'components/organisms/ProjectStorySection/ProjectStorySection'; import { SellOrdersActionsBar } from 'components/organisms/SellOrdersActionsBar/SellOrdersActionsBar'; import { AVG_PRICE_TOOLTIP_PROJECT } from 'components/organisms/SellOrdersActionsBar/SellOrdersActionsBar.constants'; -import { usePaginatedBatchesByProject } from 'hooks/batches/usePaginatedBatchesByProject'; +import { usePaginatedBatches } from 'hooks/batches/usePaginatedBatches'; import { useLedger } from '../../../ledger'; import { client as sanityClient } from '../../../lib/clients/sanity'; @@ -224,7 +224,7 @@ function ProjectDetails(): JSX.Element { const anchoredMetadata = data as AnchoredProjectMetadataLD | undefined; const { batchesWithSupply, setPaginationParams, paginationParams } = - usePaginatedBatchesByProject({ projectId: String(onChainProjectId) }); + usePaginatedBatches({ projectId: String(onChainProjectId) }); const { totals: batchesTotal } = getBatchesTotal(batchesWithSupply ?? []); const { diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatches.ts b/web-marketplace/src/hooks/batches/usePaginatedBatches.ts index 0a7fa5fe63..f7dc0ac329 100644 --- a/web-marketplace/src/hooks/batches/usePaginatedBatches.ts +++ b/web-marketplace/src/hooks/batches/usePaginatedBatches.ts @@ -7,6 +7,8 @@ import { TablePaginationParams } from 'web-components/lib/components/table/Actio import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; import { UseStateSetter } from 'types/react/use-state'; import { useLedger } from 'ledger'; +import { getBatchesByIssuerQuery } from 'lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery'; +import { getBatchesByProjectQuery } from 'lib/queries/react-query/ecocredit/getBatchesByProjectQuery/getBatchesByProjectQuery'; import { getBatchesQuery } from 'lib/queries/react-query/ecocredit/getBatchesQuery/getBatchesQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; @@ -15,7 +17,12 @@ import { useAddDataToBatches } from './useAddDataToBatches'; export const PAGINATED_BATCHES_ROWS_PER_PAGE = 10; -export const usePaginatedBatches = (): { +type Props = { address?: string; projectId?: string }; + +export const usePaginatedBatches = ({ + projectId, + address, +}: Props): { batchesWithSupply: BatchInfoWithSupply[] | undefined; setPaginationParams: UseStateSetter; paginationParams: TablePaginationParams; @@ -33,29 +40,61 @@ export const usePaginatedBatches = (): { offset: 0, }); const { rowsPerPage } = paginationParams; + const paginationRequest = { + offset: page * rowsPerPage, + limit: rowsPerPage, + countTotal: true, + }; const sanityCreditClassDataResult = useQuery( getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), ); - /* Fetch current page batches */ + /* Default batches fetch */ const batchesResult = useQuery( getBatchesQuery({ client: ecocreditClient, request: { - pagination: { - offset: page * rowsPerPage, - limit: rowsPerPage, - countTotal: true, - }, + pagination: paginationRequest, + }, + keepPreviousData: true, + enabled: !!ecocreditClient && !projectId && !address, + }), + ); + + /* By Issuer batches fetch */ + const batchesByIssuerResult = useQuery( + getBatchesByIssuerQuery({ + client: ecocreditClient, + request: { + pagination: paginationRequest, + issuer: address, }, - enabled: !!ecocreditClient, + keepPreviousData: true, + enabled: !!ecocreditClient && !!address, }), ); - /* Fetch current page batches supplies */ + /* By Project batches fetch */ + const batchesByProjectResult = useQuery( + getBatchesByProjectQuery({ + client: ecocreditClient, + request: { + pagination: paginationRequest, + projectId, + }, + keepPreviousData: true, + enabled: !!ecocreditClient && !!projectId, + }), + ); + + const batchesData = + batchesResult.data ?? + batchesByIssuerResult.data ?? + batchesByProjectResult.data; + + const batches = batchesData?.batches ?? []; - const batches = batchesResult.data?.batches ?? []; const { batchesWithData: batchesWithSupply } = useAddDataToBatches({ batches, sanityCreditClassData: sanityCreditClassDataResult.data, @@ -67,7 +106,7 @@ export const usePaginatedBatches = (): { /* Format hook returned variables */ - const batchesPagination = batchesResult.data?.pagination; + const batchesPagination = batchesData?.pagination; const allBatchesCount = Number(batchesPagination?.total ?? 0); const batchesWithDefaultSupply: BatchInfoWithSupply[] | undefined = batches?.map(batch => ({ diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts b/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts deleted file mode 100644 index 0beabcaa8b..0000000000 --- a/web-marketplace/src/hooks/batches/usePaginatedBatchesByIssuer.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { useState } from 'react'; -import { useQuery, useQueryClient } from '@tanstack/react-query'; - -import { TablePaginationParams } from 'web-components/lib/components/table/ActionsTable'; -import { DEFAULT_ROWS_PER_PAGE } from 'web-components/src/components/table/Table.constants'; - -import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; -import { UseStateSetter } from 'types/react/use-state'; -import { useLedger } from 'ledger'; -import { getBatchesByIssuerQuery } from 'lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery'; -import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; - -import { client as sanityClient } from '../../lib/clients/sanity'; -import { useAddDataToBatches } from './useAddDataToBatches'; - -type Props = { address?: string }; - -export const usePaginatedBatchesByIssuer = ({ - address, -}: Props): { - batchesWithSupply: BatchInfoWithSupply[] | undefined; - setPaginationParams: UseStateSetter; - paginationParams: TablePaginationParams; -} => { - const { ecocreditClient, dataClient } = useLedger(); - const reactQueryClient = useQueryClient(); - const [paginationParams, setPaginationParams] = - useState({ - page: 0, - rowsPerPage: DEFAULT_ROWS_PER_PAGE, - offset: 0, - }); - const { rowsPerPage, page } = paginationParams; - - const sanityCreditClassDataResult = useQuery( - getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), - ); - - const batchesByIssuerResult = useQuery( - getBatchesByIssuerQuery({ - client: ecocreditClient, - request: { - pagination: { - offset: page * rowsPerPage, - limit: rowsPerPage, - countTotal: true, - }, - issuer: address, - }, - keepPreviousData: true, - enabled: !!ecocreditClient && !!address, - }), - ); - - const batches = batchesByIssuerResult.data?.batches ?? []; - - const { batchesWithData: batchesWithSupply } = useAddDataToBatches({ - batches, - sanityCreditClassData: sanityCreditClassDataResult.data, - reactQueryClient, - dataClient, - ecocreditClient, - withAllData: true, - }); - - const batchesPagination = batchesByIssuerResult.data?.pagination; - const allBatchesCount = Number(batchesPagination?.total ?? 0); - const batchesWithDefaultSupply: BatchInfoWithSupply[] | undefined = - batches?.map(batch => ({ - ...batch, - cancelledAmount: '', - retiredAmount: '', - tradableAmount: '', - })); - - return { - batchesWithSupply: batchesWithSupply ?? batchesWithDefaultSupply, - setPaginationParams, - paginationParams: { ...paginationParams, count: allBatchesCount }, - }; -}; diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts b/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts deleted file mode 100644 index 6321988215..0000000000 --- a/web-marketplace/src/hooks/batches/usePaginatedBatchesByProject.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { useState } from 'react'; -import { useQuery, useQueryClient } from '@tanstack/react-query'; - -import { TablePaginationParams } from 'web-components/lib/components/table/ActionsTable'; - -import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; -import { UseStateSetter } from 'types/react/use-state'; -import { useLedger } from 'ledger'; -import { getBatchesByProjectQuery } from 'lib/queries/react-query/ecocredit/getBatchesByProjectQuery/getBatchesByProjectQuery'; -import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; - -import { client as sanityClient } from '../../lib/clients/sanity'; -import { useAddDataToBatches } from './useAddDataToBatches'; - -export const PAGINATED_BATCHES_BY_PROJECT_ROWS_PER_PAGE = 5; - -type Params = { projectId: string }; - -export const usePaginatedBatchesByProject = ({ - projectId, -}: Params): { - batchesWithSupply: BatchInfoWithSupply[] | undefined; - setPaginationParams: UseStateSetter; - paginationParams: TablePaginationParams; -} => { - const { ecocreditClient, dataClient } = useLedger(); - const reactQueryClient = useQueryClient(); - const [paginationParams, setPaginationParams] = - useState({ - page: 0, - rowsPerPage: PAGINATED_BATCHES_BY_PROJECT_ROWS_PER_PAGE, - offset: 0, - }); - const { rowsPerPage, page } = paginationParams; - - const sanityCreditClassDataResult = useQuery( - getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), - ); - - /* Fetch current page batches */ - const batchesByProjectResult = useQuery( - getBatchesByProjectQuery({ - client: ecocreditClient, - request: { - pagination: { - offset: page * rowsPerPage, - limit: rowsPerPage, - countTotal: true, - }, - projectId, - }, - keepPreviousData: true, - enabled: !!ecocreditClient && !!projectId, - }), - ); - - /* Fetch current page batches supplies */ - - const batches = batchesByProjectResult.data?.batches ?? []; - - const { batchesWithData: batchesWithSupply } = useAddDataToBatches({ - batches, - sanityCreditClassData: sanityCreditClassDataResult.data, - reactQueryClient, - dataClient, - ecocreditClient, - withAllData: true, - }); - - /* Format hook returned variables */ - - const batchesPagination = batchesByProjectResult.data?.pagination; - const allBatchesCount = Number(batchesPagination?.total ?? 0); - const batchesWithDefaultSupply: BatchInfoWithSupply[] | undefined = - batches?.map(batch => ({ - ...batch, - cancelledAmount: '', - retiredAmount: '', - tradableAmount: '', - })); - - return { - batchesWithSupply: batchesWithSupply ?? batchesWithDefaultSupply, - setPaginationParams, - paginationParams: { ...paginationParams, count: allBatchesCount }, - }; -}; diff --git a/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx b/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx index dfc99a5360..6bb8f50816 100644 --- a/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx +++ b/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx @@ -12,7 +12,7 @@ import { useWallet } from 'lib/wallet/wallet'; import WithLoader from 'components/atoms/WithLoader'; import { CreditBatches } from 'components/organisms'; -import { usePaginatedBatchesByIssuer } from 'hooks/batches/usePaginatedBatchesByIssuer'; +import { usePaginatedBatches } from 'hooks/batches/usePaginatedBatches'; import { NO_CREDIT_BATCHES_MESSAGE } from './MyCreditBatches.constants'; @@ -20,7 +20,7 @@ export const MyCreditBatches = (): JSX.Element => { const theme = useTheme(); const { wallet } = useWallet(); const { batchesWithSupply, setPaginationParams, paginationParams } = - usePaginatedBatchesByIssuer({ address: wallet?.address }); + usePaginatedBatches({ address: wallet?.address }); const hasNoBatches = batchesWithSupply && batchesWithSupply?.length === 0; return ( diff --git a/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx b/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx index afd03fecba..0f9453ad9d 100644 --- a/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx +++ b/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx @@ -12,7 +12,7 @@ export const EcocreditBatches = (): JSX.Element => { const navigate = useNavigate(); const { page: routePage } = useParams(); const { batchesWithSupply, setPaginationParams, paginationParams } = - usePaginatedBatches(); + usePaginatedBatches({}); const { page } = paginationParams; useEffect(() => { From a12a5c2623f4145587ca3be0deecc603c628d5d8 Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 28 Sep 2023 10:10:57 +0200 Subject: [PATCH 4/9] refactor: simplify CreditBatches component --- .../hooks/useFetchBridgedEcocredits.tsx | 4 +- .../organisms/CreditBatches/CreditBatches.tsx | 14 +++---- .../organisms/CreditTotals/CreditTotals.tsx | 2 +- .../ProjectDetails/ProjectDetails.tsx | 4 +- .../hooks/batches/useBatchesWithMetadata.ts | 2 +- .../batches}/useFetchCreditBatches.tsx | 30 +++------------ ...Batches.ts => useFetchPaginatedBatches.ts} | 38 +++++++++++++++---- .../hooks/useFetchBasketEcocredits.ts | 4 +- .../CreditClassDetailsSimple.tsx | 7 ++++ .../CreditClassDetails.TableTabs.config.tsx | 12 +++++- .../CreditClassDetails.TableTabs.types.ts | 7 ++++ .../MyCreditBatches/MyCreditBatches.tsx | 4 +- .../MyEcocredits/hooks/useFetchEcocredits.ts | 4 +- .../EcocreditBatches.loader.ts | 2 +- .../EcocreditBatches/EcocreditBatches.tsx | 4 +- 15 files changed, 80 insertions(+), 58 deletions(-) rename web-marketplace/src/{components/organisms/CreditBatches/hooks => hooks/batches}/useFetchCreditBatches.tsx (54%) rename web-marketplace/src/hooks/batches/{usePaginatedBatches.ts => useFetchPaginatedBatches.ts} (79%) diff --git a/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx b/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx index 0931c3c7ef..d0ebeaf615 100644 --- a/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx +++ b/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx @@ -16,7 +16,7 @@ import { getBridgeTxStatusQuery } from 'lib/queries/react-query/bridge/getBridge import { getGetTxsEventQuery } from 'lib/queries/react-query/cosmos/bank/getTxsEventQuery/getTxsEventQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; -import { useBatchesWithMetadata } from 'hooks/batches/useBatchesWithMetadata'; +import { useFetchBatchesWithMetadata } from 'hooks/batches/useBatchesWithMetadata'; import { BRIDGED_STATUSES, @@ -148,7 +148,7 @@ export const useFetchBridgedEcocredits = ({ address }: Props): Output => { isProjectsMetadataLoading, classesMetadata, isClassesMetadataLoading, - } = useBatchesWithMetadata(credits); + } = useFetchBatchesWithMetadata(credits); // Normalization // isLoading -> undefined: return empty strings in normalizer to trigger skeleton diff --git a/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx b/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx index ebd2db06a3..9302754f9d 100644 --- a/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx +++ b/web-marketplace/src/components/organisms/CreditBatches/CreditBatches.tsx @@ -30,7 +30,6 @@ import { creditBatchesHeadCells, } from './CreditBatches.config'; import { useCreditBatchesStyles } from './CreditBatches.styles'; -import { useFetchCreditBatches } from './hooks/useFetchCreditBatches'; interface CreditBatchProps { creditClassId?: string | null; @@ -58,10 +57,7 @@ const CreditBatches: React.FC> = ({ sx, }) => { const { classes } = useCreditBatchesStyles(); - const { batchesWithSupply } = useFetchCreditBatches({ - creditBatches, - creditClassId, - }); + let columnsToShow = [...creditBatchesHeadCells]; // We hide the classId column if creditClassId provided (redundant) @@ -77,13 +73,13 @@ const CreditBatches: React.FC> = ({ ); } - const someTx = batchesWithSupply?.some(batch => batch.txhash); + const someTx = creditBatches?.some(batch => batch.txhash); if (!someTx) { columnsToShow = columnsToShow.filter(column => column.id !== 'txhash'); } - if (!batchesWithSupply?.length) { + if (!creditBatches?.length) { return ( > = ({ initialPaginationParams={initialPaginationParams} isIgnoreOffset={isIgnoreOffset} sx={sx} - rows={batchesWithSupply.map(batch => { + rows={creditBatches.map(batch => { /* eslint-disable react/jsx-key */ let result = []; if (someTx) { @@ -214,7 +210,7 @@ const CreditBatches: React.FC> = ({ /> ); - return batchesWithSupply.length > 0 ? ( + return creditBatches.length > 0 ? ( withSection ? (
{ +export const useFetchCreditBatches = ({ withAllData }: Params) => { const { ecocreditClient, dataClient } = useLedger(); const reactQueryClient = useQueryClient(); const { data: batchesData, isFetching: isLoadingBatches } = useQuery( getBatchesQuery({ - enabled: !creditClassId && !!ecocreditClient && !creditBatches, + enabled: !!ecocreditClient, client: ecocreditClient, request: {}, }), ); - const { data: batchesByClassData, isFetching: isLoadingBatchesByClass } = - useQuery( - getBatchesByClassQuery({ - enabled: !!creditClassId && !!ecocreditClient && !creditBatches, - client: ecocreditClient, - request: { classId: creditClassId ?? undefined }, - }), - ); - - const batches = batchesData?.batches ?? batchesByClassData?.batches ?? []; + const batches = batchesData?.batches ?? []; const sanityCreditClassDataResult = useQuery( getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), @@ -55,11 +38,8 @@ export const useFetchCreditBatches = ({ withAllData, }); - const batchesWithSupply = creditBatches ?? batchesWithData; - return { - batchesWithSupply, - isLoading: - isLoadingBatchesWithData || isLoadingBatches || isLoadingBatchesByClass, + batchesWithSupply: batchesWithData, + isLoading: isLoadingBatchesWithData || isLoadingBatches, }; }; diff --git a/web-marketplace/src/hooks/batches/usePaginatedBatches.ts b/web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts similarity index 79% rename from web-marketplace/src/hooks/batches/usePaginatedBatches.ts rename to web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts index f7dc0ac329..07516a5539 100644 --- a/web-marketplace/src/hooks/batches/usePaginatedBatches.ts +++ b/web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts @@ -7,6 +7,7 @@ import { TablePaginationParams } from 'web-components/lib/components/table/Actio import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; import { UseStateSetter } from 'types/react/use-state'; import { useLedger } from 'ledger'; +import { getBatchesByClassQuery } from 'lib/queries/react-query/ecocredit/getBatchesByClass/getBatchesByClass'; import { getBatchesByIssuerQuery } from 'lib/queries/react-query/ecocredit/getBatchesByIssuerQuery/getBatchesByIssuerQuery'; import { getBatchesByProjectQuery } from 'lib/queries/react-query/ecocredit/getBatchesByProjectQuery/getBatchesByProjectQuery'; import { getBatchesQuery } from 'lib/queries/react-query/ecocredit/getBatchesQuery/getBatchesQuery'; @@ -17,11 +18,18 @@ import { useAddDataToBatches } from './useAddDataToBatches'; export const PAGINATED_BATCHES_ROWS_PER_PAGE = 10; -type Props = { address?: string; projectId?: string }; +type Props = { + address?: string; + projectId?: string; + withAllData?: boolean; + creditClassId?: string | null; +}; -export const usePaginatedBatches = ({ +export const useFetchPaginatedBatches = ({ projectId, address, + creditClassId, + withAllData = true, }: Props): { batchesWithSupply: BatchInfoWithSupply[] | undefined; setPaginationParams: UseStateSetter; @@ -32,14 +40,14 @@ export const usePaginatedBatches = ({ const { page: routePage } = useParams(); // Page index starts at 1 for route // Page index starts at 0 for MUI Table - const page = Number(routePage) - 1; + const initialPage = routePage ? Number(routePage) - 1 : 0; const [paginationParams, setPaginationParams] = useState({ - page, + page: initialPage, rowsPerPage: PAGINATED_BATCHES_ROWS_PER_PAGE, offset: 0, }); - const { rowsPerPage } = paginationParams; + const { rowsPerPage, page } = paginationParams; const paginationRequest = { offset: page * rowsPerPage, limit: rowsPerPage, @@ -58,7 +66,7 @@ export const usePaginatedBatches = ({ pagination: paginationRequest, }, keepPreviousData: true, - enabled: !!ecocreditClient && !projectId && !address, + enabled: !!ecocreditClient && !projectId && !address && !creditClassId, }), ); @@ -88,10 +96,24 @@ export const usePaginatedBatches = ({ }), ); + /* By Class batches fetch */ + const batchesByClassResult = useQuery( + getBatchesByClassQuery({ + client: ecocreditClient, + request: { + pagination: paginationRequest, + classId: creditClassId ?? undefined, + }, + keepPreviousData: true, + enabled: !!ecocreditClient && !!creditClassId, + }), + ); + const batchesData = batchesResult.data ?? batchesByIssuerResult.data ?? - batchesByProjectResult.data; + batchesByProjectResult.data ?? + batchesByClassResult.data; const batches = batchesData?.batches ?? []; @@ -101,7 +123,7 @@ export const usePaginatedBatches = ({ reactQueryClient, dataClient, ecocreditClient, - withAllData: true, + withAllData, }); /* Format hook returned variables */ diff --git a/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts b/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts index 01b2760791..c80649b28d 100644 --- a/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts +++ b/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts @@ -10,7 +10,7 @@ import { client as sanityClient } from 'lib/clients/sanity'; import { getBasketBalancesQuery } from 'lib/queries/react-query/ecocredit/basket/getBasketBalances/getBasketBalancesQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; -import { useBatchesWithMetadata } from 'hooks/batches/useBatchesWithMetadata'; +import { useFetchBatchesWithMetadata } from 'hooks/batches/useBatchesWithMetadata'; import { BasketBatchInfoWithBalance, @@ -76,7 +76,7 @@ export const useFetchBasketEcocredits = ({ isProjectsMetadataLoading, classesMetadata, isClassesMetadataLoading, - } = useBatchesWithMetadata(balances); + } = useFetchBatchesWithMetadata(balances); // AllCreditClasses const { data: creditClassData } = useQuery( diff --git a/web-marketplace/src/pages/CreditClassDetails/CreditClassDetailsSimple/CreditClassDetailsSimple.tsx b/web-marketplace/src/pages/CreditClassDetails/CreditClassDetailsSimple/CreditClassDetailsSimple.tsx index bf4b6ffa43..1cdf99e26e 100644 --- a/web-marketplace/src/pages/CreditClassDetails/CreditClassDetailsSimple/CreditClassDetailsSimple.tsx +++ b/web-marketplace/src/pages/CreditClassDetails/CreditClassDetailsSimple/CreditClassDetailsSimple.tsx @@ -23,6 +23,7 @@ import { OFFSET_GENERATION_METHOD } from 'pages/Buyers/Buyers.constants'; import { EcocreditsSection } from 'components/molecules'; import { DetailsSection } from 'components/organisms/DetailsSection/DetailsSection'; import { parseMethodologies } from 'components/organisms/ProjectTopSection/ProjectTopSection.utils'; +import { useFetchPaginatedBatches } from 'hooks/batches/useFetchPaginatedBatches'; import { useTags } from 'hooks/useTags'; import { client as sanityClient } from '../../../lib/clients/sanity'; @@ -82,6 +83,9 @@ const CreditClassDetailsSimple: React.FC< ecosystemTypes, }); + const { batchesWithSupply, setPaginationParams, paginationParams } = + useFetchPaginatedBatches({ creditClassId: onChainClass.id }); + const { data: sanityCreditClassPageData } = useQuery( getAllCreditClassPageQuery({ sanityClient, enabled: !!sanityClient }), ); @@ -225,6 +229,9 @@ const CreditClassDetailsSimple: React.FC< diff --git a/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx b/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx index b4db069d72..012261c661 100644 --- a/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx +++ b/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx @@ -8,11 +8,21 @@ import { CreditClassDetailsTableTabsProps } from './CreditClassDetails.TableTabs export const getCreditClassDetailsTabs = ({ creditClassMetadata, onChainCreditClassId, + creditBatches, + initialPaginationParams, + onTableChange, }: CreditClassDetailsTableTabsProps): IconTabProps[] => [ { label: 'Credit Issuance', - content: , + content: ( + + ), hidden: !onChainCreditClassId, }, { diff --git a/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.types.ts b/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.types.ts index 375ae7dd2c..760d7e7c33 100644 --- a/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.types.ts +++ b/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.types.ts @@ -1,6 +1,13 @@ +import { TablePaginationParams } from 'web-components/lib/components/table/ActionsTable'; + +import { BatchInfoWithSupply } from 'types/ledger/ecocredit'; +import { UseStateSetter } from 'types/react/use-state'; import { CreditClassMetadataLD } from 'lib/db/types/json-ld'; export type CreditClassDetailsTableTabsProps = { creditClassMetadata?: CreditClassMetadataLD; onChainCreditClassId?: string; + creditBatches?: BatchInfoWithSupply[]; + onTableChange?: UseStateSetter; + initialPaginationParams?: TablePaginationParams; }; diff --git a/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx b/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx index 6bb8f50816..5a789c18a1 100644 --- a/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx +++ b/web-marketplace/src/pages/Dashboard/MyCreditBatches/MyCreditBatches.tsx @@ -12,7 +12,7 @@ import { useWallet } from 'lib/wallet/wallet'; import WithLoader from 'components/atoms/WithLoader'; import { CreditBatches } from 'components/organisms'; -import { usePaginatedBatches } from 'hooks/batches/usePaginatedBatches'; +import { useFetchPaginatedBatches } from 'hooks/batches/useFetchPaginatedBatches'; import { NO_CREDIT_BATCHES_MESSAGE } from './MyCreditBatches.constants'; @@ -20,7 +20,7 @@ export const MyCreditBatches = (): JSX.Element => { const theme = useTheme(); const { wallet } = useWallet(); const { batchesWithSupply, setPaginationParams, paginationParams } = - usePaginatedBatches({ address: wallet?.address }); + useFetchPaginatedBatches({ address: wallet?.address }); const hasNoBatches = batchesWithSupply && batchesWithSupply?.length === 0; return ( diff --git a/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts b/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts index 0940324ad5..806828725b 100644 --- a/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts +++ b/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts @@ -12,7 +12,7 @@ import { getBalancesQuery } from 'lib/queries/react-query/ecocredit/getBalancesQ import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; import { useWallet } from 'lib/wallet/wallet'; -import { useBatchesWithMetadata } from '../../../../hooks/batches/useBatchesWithMetadata'; +import { useFetchBatchesWithMetadata } from '../../../../hooks/batches/useBatchesWithMetadata'; import { client as sanityClient } from '../../../../lib/clients/sanity'; import { isOfCreditClass } from '../MyEcocredits.utils'; @@ -94,7 +94,7 @@ export const useFetchEcocredits = ({ isProjectsMetadataLoading, classesMetadata, isClassesMetadataLoading, - } = useBatchesWithMetadata(filteredBalances); + } = useFetchBatchesWithMetadata(filteredBalances); // AllCreditClasses const { data: creditClassData } = useQuery( diff --git a/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.loader.ts b/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.loader.ts index f47dcfc21a..59a0d5a74c 100644 --- a/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.loader.ts +++ b/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.loader.ts @@ -5,7 +5,7 @@ import { getEcocreditQueryClient } from 'lib/clients/regen/ecocredit/ecocreditQu import { getBatchesQuery } from 'lib/queries/react-query/ecocredit/getBatchesQuery/getBatchesQuery'; import { getFromCacheOrFetch } from 'lib/queries/react-query/utils/getFromCacheOrFetch'; -import { PAGINATED_BATCHES_ROWS_PER_PAGE } from 'hooks/batches/usePaginatedBatches'; +import { PAGINATED_BATCHES_ROWS_PER_PAGE } from 'hooks/batches/useFetchPaginatedBatches'; type LoaderType = { queryClient: QueryClient; diff --git a/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx b/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx index 0f9453ad9d..98c8b2724f 100644 --- a/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx +++ b/web-marketplace/src/pages/EcocreditBatches/EcocreditBatches.tsx @@ -6,13 +6,13 @@ import Section from 'web-components/lib/components/section'; import { Title } from 'web-components/lib/components/typography'; import { CreditBatches } from 'components/organisms'; -import { usePaginatedBatches } from 'hooks/batches/usePaginatedBatches'; +import { useFetchPaginatedBatches } from 'hooks/batches/useFetchPaginatedBatches'; export const EcocreditBatches = (): JSX.Element => { const navigate = useNavigate(); const { page: routePage } = useParams(); const { batchesWithSupply, setPaginationParams, paginationParams } = - usePaginatedBatches({}); + useFetchPaginatedBatches({}); const { page } = paginationParams; useEffect(() => { From 7013f11d8679d9c03a5be42732846c6ab5044b89 Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 28 Sep 2023 10:30:04 +0200 Subject: [PATCH 5/9] fix: improve loading ux --- .../src/hooks/batches/useAddDataToBatches.tsx | 30 ++++++++++++++----- .../batches/normalizeBatchesWithData.ts | 8 ++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx b/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx index aafa0e970b..20b01b2710 100644 --- a/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx +++ b/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx @@ -64,8 +64,11 @@ export const useAddDataToBatches = ({ }), ), }); + const isBatchesSupplyLoading = batchesSupplyResult.some( + batchSupplyQuery => batchSupplyQuery.isFetching, + ); - const batchesProjectDataResult = useQueries({ + const batchesProjectResult = useQueries({ queries: batches.map(batch => getProjectQuery({ request: { projectId: batch.projectId }, @@ -74,10 +77,13 @@ export const useAddDataToBatches = ({ }), ), }); + const isBatchesProjectLoading = batchesProjectResult.some( + batchProjectQuery => batchProjectQuery.isFetching, + ); const batchesProjectMetadataResult = useQueries({ queries: batches.map((batch, index) => { - const project = batchesProjectDataResult?.[index].data?.project; + const project = batchesProjectResult?.[index].data?.project; return getMetadataQuery({ iri: project?.metadata, dataClient, @@ -85,10 +91,13 @@ export const useAddDataToBatches = ({ }); }), }); + const isBatchesProjectMetadataLoading = batchesProjectMetadataResult.some( + batchProjectMetadataQuery => batchProjectMetadataQuery.isFetching, + ); const batchesClassResult = useQueries({ queries: batches.map((batch, index) => { - const project = batchesProjectDataResult?.[index].data?.project; + const project = batchesProjectResult?.[index].data?.project; return getClassQuery({ request: { classId: project?.classId }, client: ecocreditClient, @@ -108,13 +117,20 @@ export const useAddDataToBatches = ({ }); }), }); + const isBatchesClassMetadataLoading = batchesClassMetadataResult.some( + batchClassMetadataQuery => batchClassMetadataQuery.isFetching, + ); const batchesWithData = normalizeBatchesWithData({ batches, - batchesClassMetadataResult, - batchesProjectDataResult, - batchesProjectMetadataResult, - batchesSupplyResult, + batchesClassMetadataResult: isBatchesClassMetadataLoading + ? [] + : batchesClassMetadataResult, + batchesProjectResult: isBatchesProjectLoading ? [] : batchesProjectResult, + batchesProjectMetadataResult: isBatchesProjectMetadataLoading + ? [] + : batchesProjectMetadataResult, + batchesSupplyResult: isBatchesSupplyLoading ? [] : batchesSupplyResult, createBatchAlphaTxs, createBatchTxs, sanityCreditClassData, diff --git a/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts b/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts index cd5ea1c8f9..054d706f5e 100644 --- a/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts +++ b/web-marketplace/src/lib/normalizers/batches/normalizeBatchesWithData.ts @@ -22,7 +22,7 @@ type Props = { createBatchTxs?: GetTxsEventResponse | null; createBatchAlphaTxs?: GetTxsEventResponse | null; batchesSupplyResult?: UseQueryResult[]; - batchesProjectDataResult?: UseQueryResult[]; + batchesProjectResult?: UseQueryResult[]; batchesProjectMetadataResult?: UseQueryResult< AnchoredProjectMetadataLD | CreditClassMetadataLD >[]; @@ -34,7 +34,7 @@ type Props = { export const normalizeBatchesWithData = ({ batches, batchesClassMetadataResult, - batchesProjectDataResult, + batchesProjectResult, batchesProjectMetadataResult, batchesSupplyResult, createBatchAlphaTxs, @@ -49,12 +49,12 @@ export const normalizeBatchesWithData = ({ v1Alpha1BatchDenomMapping[batch.denom], ); - const supplyData = batchesSupplyResult?.[index].data ?? { + const supplyData = batchesSupplyResult?.[index]?.data ?? { cancelledAmount: '', retiredAmount: '', tradableAmount: '', }; - const project = batchesProjectDataResult?.[index].data?.project; + const project = batchesProjectResult?.[index]?.data?.project; const classMetadata = batchesClassMetadataResult?.[index]; const projectMetadata = batchesProjectMetadataResult?.[index]; From 81a6d33a2eaa57e0dca693ea193c1bcf46525920 Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 28 Sep 2023 10:33:47 +0200 Subject: [PATCH 6/9] fix: add missing txClient --- web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts b/web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts index 07516a5539..466a520acd 100644 --- a/web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts +++ b/web-marketplace/src/hooks/batches/useFetchPaginatedBatches.ts @@ -35,7 +35,7 @@ export const useFetchPaginatedBatches = ({ setPaginationParams: UseStateSetter; paginationParams: TablePaginationParams; } => { - const { ecocreditClient, dataClient } = useLedger(); + const { ecocreditClient, dataClient, txClient } = useLedger(); const reactQueryClient = useQueryClient(); const { page: routePage } = useParams(); // Page index starts at 1 for route @@ -123,6 +123,7 @@ export const useFetchPaginatedBatches = ({ reactQueryClient, dataClient, ecocreditClient, + txClient, withAllData, }); From 2a1817c360ba5a76b7687fb887dd293dca495c8a Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 28 Sep 2023 10:50:21 +0200 Subject: [PATCH 7/9] fix: credit class batches pagination --- web-marketplace/src/lib/ecocredit/api.ts | 1 + .../tables/CreditClassDetails.TableTabs.config.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/web-marketplace/src/lib/ecocredit/api.ts b/web-marketplace/src/lib/ecocredit/api.ts index a846951507..68f87f41fb 100644 --- a/web-marketplace/src/lib/ecocredit/api.ts +++ b/web-marketplace/src/lib/ecocredit/api.ts @@ -689,6 +689,7 @@ export const queryBatchesByClass = async ({ try { return await client.BatchesByClass({ classId: request.classId, + pagination: request.pagination, }); } catch (err) { throw new Error( diff --git a/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx b/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx index 012261c661..933a5882ff 100644 --- a/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx +++ b/web-marketplace/src/pages/CreditClassDetails/tables/CreditClassDetails.TableTabs.config.tsx @@ -17,6 +17,7 @@ export const getCreditClassDetailsTabs = ({ label: 'Credit Issuance', content: ( Date: Tue, 3 Oct 2023 15:28:20 +0200 Subject: [PATCH 8/9] fix: activity loading and rename file --- .../hooks/useFetchBridgedEcocredits.tsx | 2 +- .../CreditTotals/CreditTotals.utils.ts | 42 +++++++++++-------- ...data.ts => useFetchBatchesWithMetadata.ts} | 0 .../hooks/useFetchBasketEcocredits.ts | 2 +- .../MyEcocredits/hooks/useFetchEcocredits.ts | 2 +- 5 files changed, 28 insertions(+), 20 deletions(-) rename web-marketplace/src/hooks/batches/{useBatchesWithMetadata.ts => useFetchBatchesWithMetadata.ts} (100%) diff --git a/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx b/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx index d0ebeaf615..991ffe447c 100644 --- a/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx +++ b/web-marketplace/src/components/organisms/BridgedEcocreditsTable/hooks/useFetchBridgedEcocredits.tsx @@ -16,7 +16,7 @@ import { getBridgeTxStatusQuery } from 'lib/queries/react-query/bridge/getBridge import { getGetTxsEventQuery } from 'lib/queries/react-query/cosmos/bank/getTxsEventQuery/getTxsEventQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; -import { useFetchBatchesWithMetadata } from 'hooks/batches/useBatchesWithMetadata'; +import { useFetchBatchesWithMetadata } from 'hooks/batches/useFetchBatchesWithMetadata'; import { BRIDGED_STATUSES, diff --git a/web-marketplace/src/components/organisms/CreditTotals/CreditTotals.utils.ts b/web-marketplace/src/components/organisms/CreditTotals/CreditTotals.utils.ts index d6f840c492..bb1458ade0 100644 --- a/web-marketplace/src/components/organisms/CreditTotals/CreditTotals.utils.ts +++ b/web-marketplace/src/components/organisms/CreditTotals/CreditTotals.utils.ts @@ -18,25 +18,33 @@ export const parseNumber = (value: any): number => { export const sumBatchTotals = ( batches: BatchInfoWithSupply[], ): CreditTotalData => { - let tradeable = 0; - let retired = 0; - let created = 0; + let tradeable: number | undefined = undefined; + let retired: number | undefined = undefined; + let created: number | undefined = undefined; - batches.forEach(batch => { - const batchTradable = parseNumber(batch.tradableAmount); - const batchRetired = parseNumber(batch.retiredAmount); - const batchCancelled = parseNumber(batch.cancelledAmount); - tradeable += batchTradable; - retired += batchRetired; - created += batchTradable + batchRetired + batchCancelled; - }); + if (batches.length > 0) { + batches.forEach(batch => { + const batchTradable = parseNumber(batch.tradableAmount); + const batchRetired = parseNumber(batch.retiredAmount); + const batchCancelled = parseNumber(batch.cancelledAmount); + tradeable = (tradeable ?? 0) + batchTradable; + retired = (retired ?? 0) + batchRetired; + created = (created ?? 0) + batchTradable + batchRetired + batchCancelled; + }); + } return { - tradeable: formatNumber({ - num: tradeable, - ...quantityFormatNumberOptions, - }), - retired: formatNumber({ num: retired, ...quantityFormatNumberOptions }), - created: formatNumber({ num: created, ...quantityFormatNumberOptions }), + tradeable: tradeable + ? formatNumber({ + num: tradeable, + ...quantityFormatNumberOptions, + }) + : undefined, + retired: retired + ? formatNumber({ num: retired, ...quantityFormatNumberOptions }) + : undefined, + created: created + ? formatNumber({ num: created, ...quantityFormatNumberOptions }) + : undefined, }; }; diff --git a/web-marketplace/src/hooks/batches/useBatchesWithMetadata.ts b/web-marketplace/src/hooks/batches/useFetchBatchesWithMetadata.ts similarity index 100% rename from web-marketplace/src/hooks/batches/useBatchesWithMetadata.ts rename to web-marketplace/src/hooks/batches/useFetchBatchesWithMetadata.ts diff --git a/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts b/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts index c80649b28d..378bb714fe 100644 --- a/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts +++ b/web-marketplace/src/pages/BasketDetails/hooks/useFetchBasketEcocredits.ts @@ -10,7 +10,7 @@ import { client as sanityClient } from 'lib/clients/sanity'; import { getBasketBalancesQuery } from 'lib/queries/react-query/ecocredit/basket/getBasketBalances/getBasketBalancesQuery'; import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; -import { useFetchBatchesWithMetadata } from 'hooks/batches/useBatchesWithMetadata'; +import { useFetchBatchesWithMetadata } from 'hooks/batches/useFetchBatchesWithMetadata'; import { BasketBatchInfoWithBalance, diff --git a/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts b/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts index 806828725b..a000161bcf 100644 --- a/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts +++ b/web-marketplace/src/pages/Dashboard/MyEcocredits/hooks/useFetchEcocredits.ts @@ -12,7 +12,7 @@ import { getBalancesQuery } from 'lib/queries/react-query/ecocredit/getBalancesQ import { getAllSanityCreditClassesQuery } from 'lib/queries/react-query/sanity/getAllCreditClassesQuery/getAllCreditClassesQuery'; import { useWallet } from 'lib/wallet/wallet'; -import { useFetchBatchesWithMetadata } from '../../../../hooks/batches/useBatchesWithMetadata'; +import { useFetchBatchesWithMetadata } from '../../../../hooks/batches/useFetchBatchesWithMetadata'; import { client as sanityClient } from '../../../../lib/clients/sanity'; import { isOfCreditClass } from '../MyEcocredits.utils'; From 3f7b02bb00f609dbf6ff5d3509237b23d6b4d7a3 Mon Sep 17 00:00:00 2001 From: Florent Date: Mon, 9 Oct 2023 12:00:47 +0200 Subject: [PATCH 9/9] doc: add back comment --- web-marketplace/src/hooks/batches/useAddDataToBatches.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx b/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx index 20b01b2710..21138f2bda 100644 --- a/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx +++ b/web-marketplace/src/hooks/batches/useAddDataToBatches.tsx @@ -30,6 +30,7 @@ export const useAddDataToBatches = ({ getAllSanityCreditClassesQuery({ sanityClient, enabled: !!sanityClient }), ); + /* TODO: this is limited to 100 results. We need to find a better way */ const { data: createBatchTxs, isFetching: isLoadingCreateBatchTxs } = useQuery( getGetTxsEventQuery({