Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 17 additions & 117 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions src/components/common/DebouncedSearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function DebouncedSearchInput({
const [draftValue, setDraftValue] = useState(initialDraft);
const debounced = useDebouncedValue(draftValue, debounceMs);
const didInitInitialRef = useRef(false);
const skipInitialDebouncedSyncRef = useRef(true);

useEffect(() => {
if (!didInitInitialRef.current) {
Expand All @@ -65,6 +66,12 @@ export function DebouncedSearchInput({
}, [initialDraft]);

useEffect(() => {
// Parent tables already hydrate filters from the URL; firing on mount would
// call setFilter with the same value and (before the no-op guard) reset page.
if (skipInitialDebouncedSyncRef.current) {
skipInitialDebouncedSyncRef.current = false;
return;
}
onDebouncedChange(debounced);
}, [debounced, onDebouncedChange]);

Expand Down
38 changes: 24 additions & 14 deletions src/components/issues/IssuesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ import ReactECharts from 'echarts-for-react';
import { format } from 'date-fns';
import { IssueBounty } from '../../api/models/Issues';
import { usePrices } from '../../hooks/usePrices';
import {
useClampUrlPage,
useResetPageOnDepsChange,
useUrlPaginationParam,
} from '../../hooks/useUrlPaginationParam';
import {
formatAlphaToUsd,
formatDate,
Expand All @@ -62,6 +67,7 @@ import {
ISSUES_LIST_ROWS,
ISSUES_DEFAULT_CARD_ROWS,
ISSUES_DEFAULT_LIST_ROWS,
ISSUES_VALID_ROWS,
clampRowsForIssuesView,
getIssuesViewModeFromQuery,
readStoredIssuesViewMode,
Expand Down Expand Up @@ -266,10 +272,14 @@ const IssuesList: React.FC<IssuesListProps> = ({
const [sortDirection, setSortDirection] = useState<SortDirection>('desc');
const [searchQuery, setSearchQuery] = useState('');
const [showChart, setShowChart] = useState(false);
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState<number>(() =>
viewMode === 'cards' ? ISSUES_DEFAULT_CARD_ROWS : ISSUES_DEFAULT_LIST_ROWS,
);
const [page, setPage, rowsPerPage, setRowsPerPage] = useUrlPaginationParam({
pageParam: 'page',
rows: {
paramName: 'rows',
allowed: ISSUES_VALID_ROWS,
defaultRows: ISSUES_DEFAULT_LIST_ROWS,
},
});

const isLargeScreen = useMediaQuery(theme.breakpoints.up('xl'));
const [portalTarget, setPortalTarget] = useState<HTMLElement | null>(null);
Expand Down Expand Up @@ -423,16 +433,16 @@ const IssuesList: React.FC<IssuesListProps> = ({
const pageSize = clampRowsForIssuesView(rowsPerPage, viewMode);
const totalPages = Math.max(1, Math.ceil(sortedIssues.length / pageSize));

// Reset to page 0 when filter/search/sort/view/rowsPerPage changes.
// set-state-during-render (not useEffect) so React discards the stale render
// before commit, avoiding a one-frame flash of the clamped old page.
const paginationResetKey = `${filterType}|${searchQuery}|${sortKey}|${sortDirection}|${viewMode}|${pageSize}`;
const [prevPaginationResetKey, setPrevPaginationResetKey] =
useState(paginationResetKey);
if (paginationResetKey !== prevPaginationResetKey) {
setPrevPaginationResetKey(paginationResetKey);
setPage(0);
}
useResetPageOnDepsChange(setPage, [
filterType,
searchQuery,
sortKey,
sortDirection,
viewMode,
pageSize,
]);

useClampUrlPage(page, setPage, totalPages, !isLoading);

const safePage = Math.min(page, totalPages - 1);

Expand Down
4 changes: 4 additions & 0 deletions src/components/issues/issuesViewMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const getIssuesViewModeFromQuery = (
// the last row of cards is never partial.
export const ISSUES_LIST_ROWS = [10, 25, 50] as const;
export const ISSUES_CARD_ROWS = [12, 24, 48] as const;
export const ISSUES_VALID_ROWS: readonly number[] = [
...ISSUES_LIST_ROWS,
...ISSUES_CARD_ROWS,
];
export const ISSUES_DEFAULT_LIST_ROWS = 10;
export const ISSUES_DEFAULT_CARD_ROWS = 12;

Expand Down
Loading
Loading