• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 8536869866

03 Apr 2024 10:05AM CUT coverage: 21.234% (-0.3%) from 21.535%
8536869866

Pull #514

github

web-flow
Merge 91a25d710 into 45ee7ebb3
Pull Request #514: refactor: user and link selector

1394 of 2532 branches covered (55.06%)

27 of 1620 new or added lines in 60 files covered. (1.67%)

4 existing lines in 2 files now uncovered.

14588 of 68702 relevant lines covered (21.23%)

2.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/sdk/src/components/record-list/ApiRecordList.tsx
NEW
1
import type { QueryFunction, QueryKey } from '@tanstack/react-query';
×
NEW
2
import { useInfiniteQuery } from '@tanstack/react-query';
×
NEW
3
import type { ILinkCellValue } from '@teable/core';
×
NEW
4
import { Button } from '@teable/ui-lib';
×
NEW
5
import { debounce } from 'lodash';
×
NEW
6
import { useEffect, useMemo, useState } from 'react';
×
NEW
7
import { useTranslation } from '../../context/app/i18n';
×
NEW
8
import { RecordItem } from './RecordItem';
×
NEW
9
import { RecordList } from './RecordList';
×
NEW
10
import { RecordSearch } from './RecordSearch';
×
NEW
11

×
NEW
12
interface IApiRecordListProps {
×
NEW
13
  queryKey: QueryKey;
×
NEW
14
  queryFn: QueryFunction<{ id: string; title?: string }[]>;
×
NEW
15
  selectedRecordIds?: string[];
×
NEW
16
  pageSize: number;
×
NEW
17
  onSearch?: (search?: string) => void;
×
NEW
18
  onClick?: (record: ILinkCellValue) => void;
×
NEW
19
  onSelected?: (record: ILinkCellValue) => void;
×
NEW
20
}
×
NEW
21

×
NEW
22
export const ApiRecordList = (props: IApiRecordListProps) => {
×
NEW
23
  const { queryFn, queryKey, onSearch, selectedRecordIds, pageSize, onClick, onSelected } = props;
×
NEW
24
  const { t } = useTranslation();
×
NEW
25
  const [search, setSearch] = useState('');
×
NEW
26

×
NEW
27
  const updateSearchParam = useMemo(() => {
×
NEW
28
    return debounce((search?: string) => {
×
NEW
29
      return onSearch?.(search);
×
NEW
30
    }, 300);
×
NEW
31
  }, [onSearch]);
×
NEW
32

×
NEW
33
  useEffect(() => {
×
NEW
34
    if (!search) {
×
NEW
35
      return updateSearchParam(undefined);
×
NEW
36
    }
×
NEW
37
    updateSearchParam(search);
×
NEW
38
  }, [search, updateSearchParam]);
×
NEW
39

×
NEW
40
  const { status, data, fetchNextPage, hasNextPage } = useInfiniteQuery({
×
NEW
41
    queryKey,
×
NEW
42
    queryFn,
×
NEW
43
    staleTime: 1000,
×
NEW
44
    refetchOnWindowFocus: false,
×
NEW
45
    getNextPageParam: (lastPage, allPage) =>
×
NEW
46
      lastPage.length < pageSize ? undefined : allPage.length,
×
NEW
47
  });
×
NEW
48

×
NEW
49
  const allRows = data ? data.pages.flatMap((d) => d) : [];
×
NEW
50
  const rowCount = hasNextPage ? allRows.length + 1 : allRows.length;
×
NEW
51

×
NEW
52
  return (
×
NEW
53
    <RecordList
×
NEW
54
      className="h-full"
×
NEW
55
      onSelect={(index) => {
×
NEW
56
        const record = allRows[index];
×
NEW
57
        if (!record) {
×
NEW
58
          return;
×
NEW
59
        }
×
NEW
60
        if (!selectedRecordIds?.includes(record.id)) {
×
NEW
61
          onSelected?.(record);
×
NEW
62
        }
×
NEW
63
        onClick?.(record);
×
NEW
64
      }}
×
NEW
65
      itemRender={(index) => {
×
NEW
66
        const record = allRows[index];
×
NEW
67
        if (rowCount - 1 <= index && hasNextPage) {
×
NEW
68
          return (
×
NEW
69
            <Button size={'sm'} variant={'link'} className="mx-auto my-0.5">
×
NEW
70
              {t('common.loadMore')}
×
NEW
71
            </Button>
×
NEW
72
          );
×
NEW
73
        }
×
NEW
74
        const isActive = selectedRecordIds?.includes(record.id);
×
NEW
75
        return <RecordItem title={record.title} active={isActive} />;
×
NEW
76
      }}
×
NEW
77
      rowCount={rowCount}
×
NEW
78
      isLoading={status === 'loading'}
×
NEW
79
      onVisibleChange={(range) => {
×
NEW
80
        const [, endIndex] = range;
×
NEW
81
        if (rowCount - 1 <= endIndex && hasNextPage) {
×
NEW
82
          fetchNextPage();
×
NEW
83
        }
×
NEW
84
      }}
×
NEW
85
    >
×
NEW
86
      {onSearch && <RecordSearch value={search} onChange={(e) => setSearch(e.target.value)} />}
×
NEW
87
    </RecordList>
×
NEW
88
  );
×
NEW
89
};
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc