Skip to content

Commit 3c7258b

Browse files
committed
fix(launchplan): render the full launch plan list instead of clipping it
The launch plan table and card views virtualized against document.getElementById('scroll-element'), which is null in this layout, so the virtualizer had no scroll container and rendered the wrong number of rows. The table view also read result?.length (the lodash `result` function, always truthy) instead of results?.length. Render the results directly with stable keys. Signed-off-by: 1fanwang <1fannnw@gmail.com>
1 parent b80a88a commit 3c7258b

3 files changed

Lines changed: 48 additions & 30 deletions

File tree

packages/oss-console/src/components/LaunchPlan/LaunchPlanCardList/LaunchPlanCardView.tsx

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import React, { useRef } from 'react';
1+
import React from 'react';
22
import { LargeLoadingComponent } from '@clients/primitives/LoadingSpinner';
33
import { NoResults } from '@clients/primitives/NoResults';
4-
import { useVirtualizer } from '@tanstack/react-virtual';
54
import { SearchResult } from '../../common/SearchableList';
65
import { NamedEntity } from '../../../models/Common/types';
76
import LaunchPlanListCard from './LaunchPlanListCard';
@@ -12,25 +11,14 @@ interface LaunchPlanCardViewProps {
1211
}
1312

1413
const LaunchPlanCardView: React.FC<LaunchPlanCardViewProps> = ({ results, loading }) => {
15-
const parentRef = useRef<any>(document.getElementById('scroll-element'));
16-
17-
const rowVirtualizer = useVirtualizer({
18-
count: results?.length ? results.length + 1 : 0,
19-
getScrollElement: () => parentRef.current,
20-
estimateSize: () => 100,
21-
overscan: 15,
22-
});
23-
24-
const items = rowVirtualizer.getVirtualItems();
25-
2614
return loading ? (
2715
<LargeLoadingComponent useDelay={false} />
2816
) : results.length === 0 ? (
2917
<NoResults />
3018
) : (
3119
<>
32-
{items.map((virtualRow) => (
33-
<LaunchPlanListCard {...results[virtualRow.index]} />
20+
{results.map((searchResult, index) => (
21+
<LaunchPlanListCard key={searchResult.key || index} {...searchResult} />
3422
))}
3523
</>
3624
);

packages/oss-console/src/components/LaunchPlan/LaunchPlanTable/LaunchPlanTableView.tsx

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef } from 'react';
1+
import React from 'react';
22
import Table from '@mui/material/Table';
33
import TableBody from '@mui/material/TableBody';
44
import TableCell from '@mui/material/TableCell';
@@ -8,8 +8,6 @@ import TableRow from '@mui/material/TableRow';
88
import { LargeLoadingComponent } from '@clients/primitives/LoadingSpinner';
99
import { TableNoRowsCell } from '@clients/primitives/TableNoRowsCell';
1010
import { noLaunchPlansFoundString } from '@clients/common/constants';
11-
import { useVirtualizer } from '@tanstack/react-virtual';
12-
import result from 'lodash/result';
1311
import { SearchResult } from '../../common/useSearchableListState';
1412
import { NamedEntity } from '../../../models/Common/types';
1513
import { LaunchPlanTableRow } from './LaunchPlanTableRow';
@@ -20,17 +18,6 @@ export interface LaunchPlanTableViewProps {
2018
}
2119

2220
export const LaunchPlanTableView = ({ results, loading }: LaunchPlanTableViewProps) => {
23-
const parentRef = useRef<any>(document.getElementById('scroll-element'));
24-
25-
const rowVirtualizer = useVirtualizer({
26-
count: result?.length ? results.length + 1 : 0,
27-
getScrollElement: () => parentRef.current,
28-
estimateSize: () => 100,
29-
overscan: 15,
30-
});
31-
32-
const items = rowVirtualizer.getVirtualItems();
33-
3421
return (
3522
<TableContainer
3623
sx={{
@@ -54,7 +41,9 @@ export const LaunchPlanTableView = ({ results, loading }: LaunchPlanTableViewPro
5441
) : results.length === 0 ? (
5542
<TableNoRowsCell displayMessage={noLaunchPlansFoundString} />
5643
) : (
57-
items.map((virtualRow) => <LaunchPlanTableRow {...results[virtualRow.index]} />)
44+
results.map((searchResult, index) => (
45+
<LaunchPlanTableRow key={searchResult.key || index} {...searchResult} />
46+
))
5847
)}
5948
</TableBody>
6049
</Table>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as React from 'react';
2+
import { ThemeProvider } from '@mui/material/styles';
3+
import { render, screen } from '@testing-library/react';
4+
import { muiTheme } from '@clients/theme/Theme/muiTheme';
5+
import { LaunchPlanTableView } from '../LaunchPlanTable/LaunchPlanTableView';
6+
import { SearchResult } from '../../common/useSearchableListState';
7+
import { NamedEntity } from '../../../models/Common/types';
8+
9+
// The real row pulls in routing + queries; mock it so the test isolates the view's row rendering.
10+
jest.mock('../LaunchPlanTable/LaunchPlanTableRow', () => ({
11+
LaunchPlanTableRow: () => (
12+
<tr data-testid="lp-row">
13+
<td>row</td>
14+
</tr>
15+
),
16+
}));
17+
18+
const makeResults = (n: number): SearchResult<NamedEntity>[] =>
19+
Array.from({ length: n }, (_, i) => ({
20+
key: `lp-${i}`,
21+
value: { id: { name: `lp-${i}` } },
22+
})) as unknown as SearchResult<NamedEntity>[];
23+
24+
const renderTable = (results: SearchResult<NamedEntity>[], loading = false) =>
25+
render(
26+
<ThemeProvider theme={muiTheme}>
27+
<LaunchPlanTableView results={results} loading={loading} />
28+
</ThemeProvider>,
29+
);
30+
31+
describe('LaunchPlanTableView', () => {
32+
it('renders one row per result without clipping the list', () => {
33+
renderTable(makeResults(3));
34+
expect(screen.getAllByTestId('lp-row')).toHaveLength(3);
35+
});
36+
37+
it('renders the empty state when there are no results', () => {
38+
renderTable(makeResults(0));
39+
expect(screen.queryAllByTestId('lp-row')).toHaveLength(0);
40+
});
41+
});

0 commit comments

Comments
 (0)