Skip to content

Commit 1607e85

Browse files
committed
feat: allow selecting number of questions in list
closes #19
1 parent 25a82e9 commit 1607e85

File tree

3 files changed

+98
-18
lines changed

3 files changed

+98
-18
lines changed

plugins/qeta/src/components/QuestionsContainer/QuestionList.tsx

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import { useStyles } from '../../utils/hooks';
22
import { WarningPanel } from '@backstage/core-components';
3-
import { Box, Button, Divider, Grid, Typography } from '@material-ui/core';
3+
import {
4+
Box,
5+
Button,
6+
Divider,
7+
FormControl,
8+
Grid,
9+
MenuItem,
10+
Select,
11+
Tooltip,
12+
Typography,
13+
} from '@material-ui/core';
414
import React from 'react';
515
import { QuestionListItem } from './QuestionListItem';
616
import { Pagination, Skeleton } from '@material-ui/lab';
@@ -12,17 +22,35 @@ export const QuestionList = (props: {
1222
error: any;
1323
response?: QuestionsResponse;
1424
onPageChange: (page: number) => void;
25+
onPageSizeChange: (size: number) => void;
1526
page: number;
27+
pageSize: number;
1628
entity?: string;
1729
}) => {
18-
const { loading, error, response, onPageChange, entity, page } = props;
19-
const pageSize = 10;
30+
const {
31+
loading,
32+
error,
33+
response,
34+
onPageChange,
35+
entity,
36+
page,
37+
onPageSizeChange,
38+
} = props;
2039
const styles = useStyles();
2140

22-
const handleChange = (_event: React.ChangeEvent<unknown>, value: number) => {
41+
const handlePageChange = (
42+
_event: React.ChangeEvent<unknown>,
43+
value: number,
44+
) => {
2345
onPageChange(value);
2446
};
2547

48+
const handlePageSizeChange = (
49+
event: React.ChangeEvent<{ value: unknown }>,
50+
) => {
51+
onPageSizeChange(Number.parseInt(event.target.value as string, 10));
52+
};
53+
2654
if (loading) {
2755
return <Skeleton variant="rect" height={200} />;
2856
}
@@ -59,7 +87,9 @@ export const QuestionList = (props: {
5987
}
6088

6189
const pageCount =
62-
response.total < pageSize ? 1 : Math.ceil(response.total / pageSize);
90+
response.total < props.pageSize
91+
? 1
92+
: Math.ceil(response.total / props.pageSize);
6393

6494
return (
6595
<Box sx={{ mt: 2 }}>
@@ -77,13 +107,28 @@ export const QuestionList = (props: {
77107
container
78108
spacing={0}
79109
className={styles.questionListPagination}
80-
direction="column"
81110
alignItems="center"
82-
justifyContent="center"
111+
justifyContent="space-between"
83112
>
113+
<Tooltip title="Questions per page" arrow>
114+
<FormControl variant="filled">
115+
<Select
116+
value={props.pageSize}
117+
onChange={handlePageSizeChange}
118+
className={styles.questionsPerPage}
119+
inputProps={{ className: styles.questionsPerPageInput }}
120+
>
121+
<MenuItem value={5}>5</MenuItem>
122+
<MenuItem value={10}>10</MenuItem>
123+
<MenuItem value={25}>25</MenuItem>
124+
<MenuItem value={50}>50</MenuItem>
125+
<MenuItem value={100}>100</MenuItem>
126+
</Select>
127+
</FormControl>
128+
</Tooltip>
84129
<Pagination
85130
page={page}
86-
onChange={handleChange}
131+
onChange={handlePageChange}
87132
count={pageCount}
88133
size="large"
89134
variant="outlined"

plugins/qeta/src/components/QuestionsContainer/QuestionsContainer.tsx

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const QuestionsContainer = (props: QuestionsContainerProps) => {
2020
const { tags, author, entity, showFilters, showTitle, title, favorite } =
2121
props;
2222
const [page, setPage] = React.useState(1);
23+
const [questionsPerPage, setQuestionsPerPage] = React.useState(10);
2324
const [showFilterPanel, setShowFilterPanel] = React.useState(false);
2425
const [searchParams, setSearchParams] = useSearchParams();
2526
const [filters, setFilters] = React.useState({
@@ -29,8 +30,6 @@ export const QuestionsContainer = (props: QuestionsContainerProps) => {
2930
noCorrectAnswer: 'false',
3031
noVotes: 'false',
3132
});
32-
const pageSize = 10;
33-
const offset = (page - 1) * pageSize;
3433

3534
const onPageChange = (value: number) => {
3635
setPage(value);
@@ -54,11 +53,23 @@ export const QuestionsContainer = (props: QuestionsContainerProps) => {
5453
useEffect(() => {
5554
let filtersApplied = false;
5655
searchParams.forEach((value, key) => {
57-
if (key === 'page') {
58-
setPage(Number.parseInt(value, 10));
59-
} else if (key in filterKeys) {
60-
filtersApplied = true;
61-
filters[key as FilterKey] = value;
56+
try {
57+
if (key === 'page') {
58+
const pv = Number.parseInt(value, 10);
59+
if (pv > 0) {
60+
setPage(pv);
61+
} else {
62+
setPage(1);
63+
}
64+
} else if (key === 'questionsPerPage') {
65+
const qpp = Number.parseInt(value, 10);
66+
if (qpp > 0) setQuestionsPerPage(qpp);
67+
} else if (key in filterKeys) {
68+
filtersApplied = true;
69+
filters[key as FilterKey] = value;
70+
}
71+
} catch (_e) {
72+
// NOOP
6273
}
6374
});
6475
setFilters(filters);
@@ -74,17 +85,33 @@ export const QuestionsContainer = (props: QuestionsContainerProps) => {
7485
} = useQetaApi(
7586
api =>
7687
api.getQuestions({
77-
limit: pageSize,
78-
offset,
88+
limit: questionsPerPage,
89+
offset: (page - 1) * questionsPerPage,
7990
tags,
8091
entity,
8192
author,
8293
favorite,
8394
...filters,
8495
}),
85-
[page, offset, filters],
96+
[page, filters, questionsPerPage],
8697
);
8798

99+
const onPageSizeChange = (value: number) => {
100+
if (response) {
101+
let newPage = page;
102+
while (newPage * value > response.total) {
103+
newPage -= 1;
104+
}
105+
onPageChange(Math.max(1, newPage));
106+
}
107+
setQuestionsPerPage(value);
108+
setSearchParams(prev => {
109+
const newValue = prev;
110+
newValue.set('questionsPerPage', String(value));
111+
return newValue;
112+
});
113+
};
114+
88115
let shownTitle = title;
89116
if (author) {
90117
shownTitle = `Questions by ${formatEntityName(author)}`;
@@ -127,8 +154,10 @@ export const QuestionsContainer = (props: QuestionsContainerProps) => {
127154
error={error}
128155
response={response}
129156
onPageChange={onPageChange}
157+
onPageSizeChange={onPageSizeChange}
130158
entity={entity}
131159
page={page}
160+
pageSize={questionsPerPage}
132161
/>
133162
</Box>
134163
);

plugins/qeta/src/utils/hooks.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ export const useStyles = makeStyles(theme => {
9696
marginTop: theme.spacing(1),
9797
marginBottom: theme.spacing(1),
9898
},
99+
questionsPerPageInput: {
100+
paddingTop: '10px',
101+
},
102+
questionsPerPage: {
103+
marginRight: theme.spacing(3),
104+
},
99105
questionHighlightList: {
100106
width: '100%',
101107
border: `1px solid ${theme.palette.action.selected}`,

0 commit comments

Comments
 (0)