mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-04 10:52:17 +02:00
chore: add sort order in URL params
This commit is contained in:
parent
e8005042e2
commit
9824d88d53
7 changed files with 148 additions and 59 deletions
|
|
@ -92,9 +92,14 @@ export default function RunsPage() {
|
|||
return decodeFiltersFromURL(searchParams, superadminFilterAttributes);
|
||||
});
|
||||
|
||||
// Sort state
|
||||
const [sortBy, setSortBy] = useState<string | null>(null);
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
|
||||
// Sort state (initialized from URL)
|
||||
const [sortBy, setSortBy] = useState<string | null>(() => {
|
||||
return searchParams.get('sort_by') || null;
|
||||
});
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>(() => {
|
||||
const order = searchParams.get('sort_order');
|
||||
return order === 'asc' ? 'asc' : 'desc';
|
||||
});
|
||||
|
||||
// Dialog state for comment editing
|
||||
const [isCommentDialogOpen, setIsCommentDialogOpen] = useState(false);
|
||||
|
|
@ -167,7 +172,7 @@ export default function RunsPage() {
|
|||
}
|
||||
}, [limit, accessToken]);
|
||||
|
||||
const updatePageInUrl = useCallback((page: number, filters?: ActiveFilter[]) => {
|
||||
const updatePageInUrl = useCallback((page: number, filters?: ActiveFilter[], sortByParam?: string | null, sortOrderParam?: 'asc' | 'desc') => {
|
||||
const params = new URLSearchParams();
|
||||
params.set('page', page.toString());
|
||||
|
||||
|
|
@ -180,6 +185,12 @@ export default function RunsPage() {
|
|||
}
|
||||
}
|
||||
|
||||
// Add sort to URL if present
|
||||
if (sortByParam) {
|
||||
params.set('sort_by', sortByParam);
|
||||
params.set('sort_order', sortOrderParam || 'desc');
|
||||
}
|
||||
|
||||
router.push(`/superadmin/runs?${params.toString()}`);
|
||||
}, [router]);
|
||||
|
||||
|
|
@ -208,7 +219,7 @@ export default function RunsPage() {
|
|||
|
||||
const handlePageChange = (page: number) => {
|
||||
setCurrentPage(page);
|
||||
updatePageInUrl(page, appliedFilters);
|
||||
updatePageInUrl(page, appliedFilters, sortBy, sortOrder);
|
||||
fetchRuns(page, appliedFilters, false, sortBy, sortOrder);
|
||||
};
|
||||
|
||||
|
|
@ -216,7 +227,7 @@ export default function RunsPage() {
|
|||
setIsExecutingFilters(true);
|
||||
setCurrentPage(1); // Reset to first page when applying filters
|
||||
setAppliedFilters(activeFilters); // Update applied filters
|
||||
updatePageInUrl(1, activeFilters);
|
||||
updatePageInUrl(1, activeFilters, sortBy, sortOrder);
|
||||
await fetchRuns(1, activeFilters, false, sortBy, sortOrder);
|
||||
setIsExecutingFilters(false);
|
||||
}, [activeFilters, fetchRuns, updatePageInUrl, sortBy, sortOrder]);
|
||||
|
|
@ -229,7 +240,7 @@ export default function RunsPage() {
|
|||
setIsExecutingFilters(true);
|
||||
setCurrentPage(1);
|
||||
setAppliedFilters([]); // Clear applied filters
|
||||
updatePageInUrl(1, []); // Clear filters from URL
|
||||
updatePageInUrl(1, [], sortBy, sortOrder); // Clear filters from URL
|
||||
await fetchRuns(1, [], false, sortBy, sortOrder); // Fetch all runs without filters
|
||||
setIsExecutingFilters(false);
|
||||
}, [fetchRuns, updatePageInUrl, sortBy, sortOrder]);
|
||||
|
|
@ -238,15 +249,16 @@ export default function RunsPage() {
|
|||
// Reset to first page when sort changes
|
||||
setCurrentPage(1);
|
||||
|
||||
const newSortBy = field;
|
||||
let newSortOrder: 'asc' | 'desc' = 'desc';
|
||||
if (sortBy === field) {
|
||||
// Toggle order if same field
|
||||
setSortOrder(prev => prev === 'asc' ? 'desc' : 'asc');
|
||||
} else {
|
||||
// New field, default to desc
|
||||
setSortBy(field);
|
||||
setSortOrder('desc');
|
||||
newSortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
|
||||
}
|
||||
}, [sortBy]);
|
||||
|
||||
setSortBy(newSortBy);
|
||||
setSortOrder(newSortOrder);
|
||||
updatePageInUrl(1, appliedFilters, newSortBy, newSortOrder);
|
||||
}, [sortBy, sortOrder, updatePageInUrl, appliedFilters]);
|
||||
|
||||
// Save comment function declared outside JSX (requirement #2)
|
||||
const saveAdminComment = useCallback(async () => {
|
||||
|
|
@ -345,6 +357,7 @@ export default function RunsPage() {
|
|||
isExecuting={isExecutingFilters}
|
||||
autoRefresh={autoRefresh}
|
||||
onAutoRefreshChange={setAutoRefresh}
|
||||
hasAppliedFilters={appliedFilters.length > 0}
|
||||
/>
|
||||
|
||||
<Card>
|
||||
|
|
|
|||
|
|
@ -30,9 +30,14 @@ export function WorkflowExecutions({ workflowId, searchParams }: WorkflowExecuti
|
|||
const [isExecutingFilters, setIsExecutingFilters] = useState(false);
|
||||
const [configuredAttributes, setConfiguredAttributes] = useState<FilterAttribute[]>(availableAttributes);
|
||||
|
||||
// Sort state
|
||||
const [sortBy, setSortBy] = useState<string | null>(null);
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
|
||||
// Sort state (initialized from URL)
|
||||
const [sortBy, setSortBy] = useState<string | null>(() => {
|
||||
return searchParams.get('sort_by') || null;
|
||||
});
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>(() => {
|
||||
const order = searchParams.get('sort_order');
|
||||
return order === 'asc' ? 'asc' : 'desc';
|
||||
});
|
||||
|
||||
const { accessToken } = useUserConfig();
|
||||
|
||||
|
|
@ -41,6 +46,11 @@ export function WorkflowExecutions({ workflowId, searchParams }: WorkflowExecuti
|
|||
return decodeFiltersFromURL(searchParams, availableAttributes);
|
||||
});
|
||||
|
||||
// Applied filters are the ones actually used for fetching (only updated on Apply click)
|
||||
const [appliedFilters, setAppliedFilters] = useState<ActiveFilter[]>(() => {
|
||||
return decodeFiltersFromURL(searchParams, availableAttributes);
|
||||
});
|
||||
|
||||
// Load disposition codes from workflow configuration
|
||||
const loadDispositionCodes = useCallback(async () => {
|
||||
if (!accessToken) return;
|
||||
|
|
@ -130,7 +140,7 @@ export function WorkflowExecutions({ workflowId, searchParams }: WorkflowExecuti
|
|||
}
|
||||
}, [workflowId, accessToken]);
|
||||
|
||||
const updatePageInUrl = useCallback((page: number, filters?: ActiveFilter[]) => {
|
||||
const updatePageInUrl = useCallback((page: number, filters?: ActiveFilter[], sortByParam?: string | null, sortOrderParam?: 'asc' | 'desc') => {
|
||||
const params = new URLSearchParams();
|
||||
params.set('page', page.toString());
|
||||
|
||||
|
|
@ -143,17 +153,24 @@ export function WorkflowExecutions({ workflowId, searchParams }: WorkflowExecuti
|
|||
}
|
||||
}
|
||||
|
||||
// Add sort to URL if present
|
||||
if (sortByParam) {
|
||||
params.set('sort_by', sortByParam);
|
||||
params.set('sort_order', sortOrderParam || 'desc');
|
||||
}
|
||||
|
||||
router.push(`/workflow/${workflowId}/runs?${params.toString()}`, { scroll: false });
|
||||
}, [router, workflowId]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchWorkflowRuns(currentPage, activeFilters, sortBy, sortOrder);
|
||||
}, [currentPage, activeFilters, fetchWorkflowRuns, sortBy, sortOrder]);
|
||||
fetchWorkflowRuns(currentPage, appliedFilters, sortBy, sortOrder);
|
||||
}, [currentPage, appliedFilters, fetchWorkflowRuns, sortBy, sortOrder]);
|
||||
|
||||
const handleApplyFilters = useCallback(async () => {
|
||||
setIsExecutingFilters(true);
|
||||
setCurrentPage(1); // Reset to first page when applying filters
|
||||
updatePageInUrl(1, activeFilters);
|
||||
setAppliedFilters(activeFilters);
|
||||
updatePageInUrl(1, activeFilters, sortBy, sortOrder);
|
||||
await fetchWorkflowRuns(1, activeFilters, sortBy, sortOrder);
|
||||
setIsExecutingFilters(false);
|
||||
}, [activeFilters, fetchWorkflowRuns, updatePageInUrl, sortBy, sortOrder]);
|
||||
|
|
@ -165,29 +182,36 @@ export function WorkflowExecutions({ workflowId, searchParams }: WorkflowExecuti
|
|||
const handleClearFilters = useCallback(async () => {
|
||||
setIsExecutingFilters(true);
|
||||
setCurrentPage(1);
|
||||
updatePageInUrl(1, []); // Clear filters from URL
|
||||
setActiveFilters([]);
|
||||
setAppliedFilters([]);
|
||||
updatePageInUrl(1, [], sortBy, sortOrder); // Clear filters from URL
|
||||
await fetchWorkflowRuns(1, [], sortBy, sortOrder); // Fetch all workflows without filters
|
||||
setIsExecutingFilters(false);
|
||||
}, [fetchWorkflowRuns, updatePageInUrl, sortBy, sortOrder]);
|
||||
|
||||
const handlePageChange = useCallback((page: number) => {
|
||||
setCurrentPage(page);
|
||||
updatePageInUrl(page, activeFilters);
|
||||
}, [updatePageInUrl, activeFilters]);
|
||||
updatePageInUrl(page, appliedFilters, sortBy, sortOrder);
|
||||
}, [updatePageInUrl, appliedFilters, sortBy, sortOrder]);
|
||||
|
||||
const handleSort = useCallback((field: string) => {
|
||||
// Reset to first page when sort changes
|
||||
setCurrentPage(1);
|
||||
|
||||
const newSortBy = field;
|
||||
let newSortOrder: 'asc' | 'desc' = 'desc';
|
||||
if (sortBy === field) {
|
||||
// Toggle order if same field
|
||||
setSortOrder(prev => prev === 'asc' ? 'desc' : 'asc');
|
||||
} else {
|
||||
// New field, default to desc
|
||||
setSortBy(field);
|
||||
setSortOrder('desc');
|
||||
newSortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
|
||||
}
|
||||
}, [sortBy]);
|
||||
|
||||
setSortBy(newSortBy);
|
||||
setSortOrder(newSortOrder);
|
||||
updatePageInUrl(1, appliedFilters, newSortBy, newSortOrder);
|
||||
}, [sortBy, sortOrder, updatePageInUrl, appliedFilters]);
|
||||
|
||||
const handleReload = useCallback(() => {
|
||||
fetchWorkflowRuns(currentPage, appliedFilters, sortBy, sortOrder);
|
||||
}, [fetchWorkflowRuns, currentPage, appliedFilters, sortBy, sortOrder]);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-8">
|
||||
|
|
@ -205,11 +229,13 @@ export function WorkflowExecutions({ workflowId, searchParams }: WorkflowExecuti
|
|||
onApplyFilters={handleApplyFilters}
|
||||
onClearFilters={handleClearFilters}
|
||||
isExecutingFilters={isExecutingFilters}
|
||||
hasAppliedFilters={appliedFilters.length > 0}
|
||||
sortBy={sortBy}
|
||||
sortOrder={sortOrder}
|
||||
onSort={handleSort}
|
||||
workflowId={workflowId}
|
||||
accessToken={accessToken}
|
||||
onReload={handleReload}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue