react-query#useInfiniteQuery JavaScript Examples

The following examples show how to use react-query#useInfiniteQuery. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: paginated-results.js    From Quest with MIT License 4 votes vote down vote up
export function PaginatedResults({
  searchViewState,
  logo,
  configuration,
  queryKey,
  fetcher,
  getFetchMore,
  renderPages = _.noop,
  getTotal = _.noop,
  filters,
  itemDetailRenderer,
  globalError,
}) {
  const state = useStateLink(searchViewState);
  const [listRef, setListRef] = useState(null);

  const {
    status,
    data,
    isFetchingMore,
    fetchMore,
    canFetchMore,
    error,
    isFetching,
  } = useInfiniteQuery(globalError ? null : queryKey, fetcher, { getFetchMore });

  const total = getTotal(data);
  const { name, pageSize } = configuration.get();

  const pages = status === "success" ? renderPages({ pages: data, error }) : [];
  const isEmpty = _.isEmpty(pages);

  return (
    <div className={styles.results}>
      <div className={styles.resultsHeader}>
        {logo && <img className={styles.moduleLogo} src={logo} alt={`${name} logo`} />}
        {!error && total > 0 ? (
          <>
            <Tooltip
              content={numberFormatter.format(total) + " " + (total === 1 ? "result" : "results")}
            >
              <H5 className={styles.moduleTitle}>{name}</H5>
            </Tooltip>
            <p className={styles.resultTotal}>
              ({numberFormatter.format(total)} {total === 1 ? "result" : "results"})
            </p>
          </>
        ) : (
          <H5 className={styles.moduleTitle}>{name}</H5>
        )}
        {filters && (
          <>
            <div className={styles.moduleFilters}>{filters}</div>
            <Popover
              className={styles.moduleFiltersMore}
              hasBackdrop
              position={"left"}
              target={
                <Tooltip content="Filters">
                  <Button icon="more" small minimal style={{ margin: 3 }} />
                </Tooltip>
              }
              content={<div className={styles.moduleFiltersMoreContainer}>{filters}</div>}
            />
          </>
        )}
      </div>

      <div className={styles.resultList} ref={setListRef}>
        {globalError ? (
          <Callout intent="danger" className={styles.resultItem}>
            {globalError}
          </Callout>
        ) : status === "loading" ? null : status === "error" ? (
          <Callout intent="danger" className={styles.resultItem}>
            {error.message}
          </Callout>
        ) : _.isEmpty(pages) ? (
          <Card className={styles.resultItem}>No results.</Card>
        ) : (
          pages.map(({ key, component, item } = {}) =>
            renderResults({ key, component, item, state, itemDetailRenderer })
          )
        )}
        {(!globalError && isFetching && isEmpty) || isFetchingMore
          ? Array(isFetching ? pageSize : 1)
              .fill(0)
              .map((id, index) => <React.Fragment key={index}>{loader}</React.Fragment>)
          : null}
      </div>

      {canFetchMore && !isFetchingMore && (
        <div>
          <Button
            className="focusable"
            minimal
            intent="primary"
            rightIcon="arrow-right"
            onClick={() => {
              const nodes = listRef.querySelectorAll(".focusable");
              nodes[nodes.length - 1].focus();
              fetchMore();
            }}
          >
            Load More
          </Button>
        </div>
      )}
    </div>
  );
}
Example #2
Source File: components.js    From idena-web with MIT License 4 votes vote down vote up
export function WalletTransactions({address}) {
  const LIMIT = 10
  const {t, i18n} = useTranslation()

  const toNumber = toLocaleNumber(i18n.language, {maximumFractionDigits: 4})

  const fetchTxs = ({pageParam = null}) =>
    getTxs(address, LIMIT, pageParam).then(result => {
      if (!result) {
        return {result: []}
      }
      const newResult = result.map(tx => {
        const fromWallet =
          lowerCase(address) === lowerCase(tx.from) ? address : null
        const toWallet =
          lowerCase(address) === lowerCase(tx.to) ? address : null

        const direction = fromWallet ? t('Sent') : t('Received')

        const typeName = tx.type === 'SendTx' ? direction : transactionType(tx)

        const sourceWallet = fromWallet || toWallet
        const signAmount = fromWallet ? -tx.amount : `+${tx.amount}`
        const counterParty = fromWallet ? tx.to : tx.from
        const counterPartyWallet = fromWallet ? toWallet : fromWallet
        const isMining = !tx.timestamp

        const nextTx = {
          ...tx,
          typeName,
          wallet: sourceWallet,
          direction,
          signAmount,
          counterParty,
          counterPartyWallet,
          isMining,
        }
        return nextTx
      })
      return {result: newResult, continuationToken: result.continuationToken}
    })

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    status,
  } = useInfiniteQuery(['transactions', address], fetchTxs, {
    getNextPageParam: lastPage => lastPage?.continuationToken,
    refetchInterval: 10 * 1000,
  })

  const isLoading = status === 'loading'

  return (
    <div>
      <Table
        sx={{
          '&': {
            tableLayout: 'fixed',
          },
          tr: {
            '&:last-of-type': {
              td: {borderBottomWidth: 0},
            },
          },
        }}
      >
        <Thead display={['none', 'table-header-group']}>
          <Tr>
            <RoundedTh isLeft>{t('Transaction')}</RoundedTh>
            <RoundedTh>{t('Address')}</RoundedTh>
            <RoundedTh textAlign="right">{t('Amount, iDNA')}</RoundedTh>
            <RoundedTh textAlign="right">{t('Fee, iDNA')}</RoundedTh>
            <RoundedTh>{t('Date')}</RoundedTh>
            <RoundedTh isRight>{t('Blockchain transaction ID')}</RoundedTh>
          </Tr>
        </Thead>
        <Tbody>
          {!isLoading &&
            data &&
            data.pages.map((group, i) => (
              <React.Fragment key={i}>
                {group.result.map((tx, k) => (
                  <Tr key={i + k}>
                    <TransactionsTd>
                      <RowStatus
                        isMining={tx.isMining}
                        direction={tx.direction}
                        type={tx.typeName}
                        walletName="Main"
                        tx={tx}
                      />
                    </TransactionsTd>

                    <TransactionsTd display={['none', 'table-cell']}>
                      {(!tx.to && '\u2013') || (
                        <Flex align="center">
                          <Avatar
                            address={lowerCase(tx.counterParty)}
                            size={8}
                          />
                          <Box ml={3}>
                            <div>
                              {tx.direction === 'Sent' ? t('To') : t('From')}{' '}
                              {tx.counterPartyWallet
                                ? `${t('wallet')} Main`
                                : t('address')}
                            </div>
                            <TableHint>
                              <Text isTruncated w="130px">
                                {tx.counterParty}
                              </Text>
                            </TableHint>
                          </Box>
                        </Flex>
                      )}
                    </TransactionsTd>

                    <TransactionsTd
                      display={['none', 'table-cell']}
                      textAlign="right"
                    >
                      <Box color={tx.signAmount < 0 ? 'red.500' : 'gray.500'}>
                        {(tx.type === 'kill' && t('See in Explorer...')) ||
                          (tx.amount === '0'
                            ? '\u2013'
                            : toNumber(tx.signAmount))}
                      </Box>
                    </TransactionsTd>

                    <TransactionsTd
                      display={['none', 'table-cell']}
                      textAlign="right"
                    >
                      {(!tx.isMining &&
                        (tx.fee === '0' ? '\u2013' : toNumber(tx.fee))) || (
                        <div>
                          <div> {tx.maxFee} </div>
                          <TableHint>{t('Fee limit')}</TableHint>
                        </div>
                      )}
                    </TransactionsTd>
                    <TransactionsTd display={['none', 'table-cell']}>
                      {!tx.timestamp
                        ? '\u2013'
                        : new Date(tx.timestamp).toLocaleString()}
                    </TransactionsTd>

                    <TransactionsTd display={['none', 'table-cell']}>
                      <div>
                        <div>
                          {tx.isMining ? t('Mining...') : t('Confirmed')}
                        </div>
                        <TableHint>
                          <Text isTruncated w="130px">
                            {tx.hash}
                          </Text>
                        </TableHint>
                      </div>
                    </TransactionsTd>
                  </Tr>
                ))}
              </React.Fragment>
            ))}
        </Tbody>
      </Table>
      {isLoading && (
        <Stack spacing={2} mt={2}>
          {new Array(10).fill(0).map((_, i) => (
            <Skeleton key={i} height={10} w="full"></Skeleton>
          ))}
        </Stack>
      )}
      {!isLoading && hasNextPage && (
        <Flex justify="center" mt={2}>
          <FlatButton
            mb={2.5}
            onClick={() => fetchNextPage()}
            disabled={isFetchingNextPage}
          >
            {isFetchingNextPage ? t('Loading more...') : t('Load More')}
          </FlatButton>
        </Flex>
      )}

      {!isLoading && data?.pages && data.pages[0].result?.length === 0 && (
        <Box color="muted" textAlign="center" lineHeight="40vh">
          {t(`You don't have any transactions yet`)}
        </Box>
      )}
    </div>
  )
}