feat: persist pagination and search value on flows page
This commit is contained in:
@@ -7,7 +7,7 @@ import FormControl from '@mui/material/FormControl';
|
|||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
|
||||||
export default function SearchInput({ onChange }) {
|
export default function SearchInput({ onChange, defaultValue = '' }) {
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
return (
|
return (
|
||||||
<FormControl variant="outlined" fullWidth>
|
<FormControl variant="outlined" fullWidth>
|
||||||
@@ -16,6 +16,7 @@ export default function SearchInput({ onChange }) {
|
|||||||
</InputLabel>
|
</InputLabel>
|
||||||
|
|
||||||
<OutlinedInput
|
<OutlinedInput
|
||||||
|
defaultValue={defaultValue}
|
||||||
id="search-input"
|
id="search-input"
|
||||||
type="text"
|
type="text"
|
||||||
size="medium"
|
size="medium"
|
||||||
@@ -34,4 +35,5 @@ export default function SearchInput({ onChange }) {
|
|||||||
|
|
||||||
SearchInput.propTypes = {
|
SearchInput.propTypes = {
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
|
defaultValue: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Link, useSearchParams } from 'react-router-dom';
|
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Grid from '@mui/material/Grid';
|
import Grid from '@mui/material/Grid';
|
||||||
@@ -23,9 +23,10 @@ import useLazyFlows from 'hooks/useLazyFlows';
|
|||||||
|
|
||||||
export default function Flows() {
|
export default function Flows() {
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const page = parseInt(searchParams.get('page') || '', 10) || 1;
|
const page = parseInt(searchParams.get('page') || '', 10) || 1;
|
||||||
const [flowName, setFlowName] = React.useState('');
|
const flowName = searchParams.get('flowName') || '';
|
||||||
const [isLoading, setIsLoading] = React.useState(false);
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
const currentUserAbility = useCurrentUserAbility();
|
const currentUserAbility = useCurrentUserAbility();
|
||||||
|
|
||||||
@@ -38,6 +39,46 @@ export default function Flows() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const flows = data?.data || [];
|
||||||
|
const pageInfo = data?.meta;
|
||||||
|
const hasFlows = flows?.length;
|
||||||
|
|
||||||
|
const onSearchChange = React.useCallback((event) => {
|
||||||
|
setSearchParams({ flowName: event.target.value });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getLinkWithSearchParams = (page, flowName) => {
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
|
||||||
|
if (page > 1) {
|
||||||
|
searchParams.set('page', page);
|
||||||
|
}
|
||||||
|
if (flowName) {
|
||||||
|
searchParams.set('flowName', flowName);
|
||||||
|
}
|
||||||
|
return `?${searchParams.toString()}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDeleteFlow = () => {
|
||||||
|
const isLastItem = flows?.length === 1;
|
||||||
|
const hasOtherPages =
|
||||||
|
pageInfo && pageInfo.totalPages > 1 && pageInfo.currentPage > 1;
|
||||||
|
|
||||||
|
if (isLastItem && hasOtherPages) {
|
||||||
|
navigate(getLinkWithSearchParams(pageInfo.currentPage - 1, flowName));
|
||||||
|
} else {
|
||||||
|
fetchFlows();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDuplicateFlow = () => {
|
||||||
|
if (pageInfo?.currentPage > 1) {
|
||||||
|
navigate(getLinkWithSearchParams(1, flowName));
|
||||||
|
} else {
|
||||||
|
fetchFlows();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const fetchData = React.useMemo(
|
const fetchData = React.useMemo(
|
||||||
() => debounce(fetchFlows, 300),
|
() => debounce(fetchFlows, 300),
|
||||||
[fetchFlows],
|
[fetchFlows],
|
||||||
@@ -53,22 +94,6 @@ export default function Flows() {
|
|||||||
};
|
};
|
||||||
}, [fetchData, flowName, page]);
|
}, [fetchData, flowName, page]);
|
||||||
|
|
||||||
React.useEffect(
|
|
||||||
function resetPageOnSearch() {
|
|
||||||
// reset search params which only consists of `page`
|
|
||||||
setSearchParams({});
|
|
||||||
},
|
|
||||||
[flowName],
|
|
||||||
);
|
|
||||||
|
|
||||||
const flows = data?.data || [];
|
|
||||||
const pageInfo = data?.meta;
|
|
||||||
const hasFlows = flows?.length;
|
|
||||||
|
|
||||||
const onSearchChange = React.useCallback((event) => {
|
|
||||||
setFlowName(event.target.value);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ py: 3 }}>
|
<Box sx={{ py: 3 }}>
|
||||||
<Container>
|
<Container>
|
||||||
@@ -78,7 +103,7 @@ export default function Flows() {
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={12} sm="auto" order={{ xs: 2, sm: 1 }}>
|
<Grid item xs={12} sm="auto" order={{ xs: 2, sm: 1 }}>
|
||||||
<SearchInput onChange={onSearchChange} />
|
<SearchInput onChange={onSearchChange} defaultValue={flowName} />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid
|
<Grid
|
||||||
@@ -119,8 +144,8 @@ export default function Flows() {
|
|||||||
<FlowRow
|
<FlowRow
|
||||||
key={flow.id}
|
key={flow.id}
|
||||||
flow={flow}
|
flow={flow}
|
||||||
onDuplicateFlow={fetchFlows}
|
onDuplicateFlow={onDuplicateFlow}
|
||||||
onDeleteFlow={fetchFlows}
|
onDeleteFlow={onDeleteFlow}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{!isLoading && !hasFlows && (
|
{!isLoading && !hasFlows && (
|
||||||
@@ -136,13 +161,10 @@ export default function Flows() {
|
|||||||
sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}
|
sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}
|
||||||
page={pageInfo?.currentPage}
|
page={pageInfo?.currentPage}
|
||||||
count={pageInfo?.totalPages}
|
count={pageInfo?.totalPages}
|
||||||
onChange={(event, page) =>
|
|
||||||
setSearchParams({ page: page.toString() })
|
|
||||||
}
|
|
||||||
renderItem={(item) => (
|
renderItem={(item) => (
|
||||||
<PaginationItem
|
<PaginationItem
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`${item.page === 1 ? '' : `?page=${item.page}`}`}
|
to={getLinkWithSearchParams(item.page, flowName)}
|
||||||
{...item}
|
{...item}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
Reference in New Issue
Block a user