Skip to content

Commit

Permalink
add sort and don't flash when updating query
Browse files Browse the repository at this point in the history
  • Loading branch information
sknep committed Feb 26, 2025
1 parent 518a901 commit 9017b73
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 31 deletions.
41 changes: 36 additions & 5 deletions frontend/hooks/useFileStorage.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,53 @@
import { useQuery } from '@tanstack/react-query';
import { useRef, useEffect } from 'react';
import federalist from '@util/federalistApi';

export default function useFileStorage(fileStorageId, path = '') {
export default function useFileStorage(
fileStorageId,
path = '',
sortKey = null,
sortOrder = null
) {
// Create a ref to store previous data. (Declare it first!)
const previousData = useRef();

const fetchPublicFiles = async () => {
const response = await federalist.fetchPublicFiles(fileStorageId, path);
const response = await federalist.fetchPublicFiles(
fileStorageId,
path,
sortKey,
sortOrder
);
if (response.error) {
throw new Error(response.error);
}
return response.data;
};

const { data = [], isLoading, error, refetch } = useQuery({
queryKey: ['fileStorage', fileStorageId, path],
// Use placeholderData: previousData.current if available.
const { data, isLoading, isFetching, error, refetch } = useQuery({
queryKey: ['fileStorage', fileStorageId, path, sortKey, sortOrder],
queryFn: fetchPublicFiles,
enabled: !!fileStorageId,
keepPreviousData: true,
staleTime: 2000,
placeholderData: previousData.current || undefined,
onError: (err) => console.error('Error fetching public files:', err),
});

// Update previousData whenever new data is available.
useEffect(() => {
if (data !== undefined) {
previousData.current = data;
}
}, [data]);

return { data, isLoading, error, refetch };
return {
data,
previousData: previousData.current,
isLoading,
isFetching,
error,
refetch
};
}
11 changes: 3 additions & 8 deletions frontend/pages/file-storage/FileList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ const FileList = ({
onViewDetails,
currentSortKey,
currentSortOrder,
children,
}) => {
const EMPTY_STATE_MESSAGE = 'No files or folders found.';
const TABLE_CAPTION = `
Listing all contents for the current folder, sorted by ${currentSortKey} in
${ariaFormatSort(currentSortOrder)} order
Expand Down Expand Up @@ -192,6 +192,7 @@ const FileList = ({
</tr>
</thead>
<tbody>
{children}
{data.map((item) => (
<FileListRow
key={item.name}
Expand All @@ -204,13 +205,6 @@ const FileList = ({
onViewDetails={onViewDetails}
/>
))}
{data.length === 0 && (
<tr>
<td colSpan="99" className="text-italic">
{EMPTY_STATE_MESSAGE}
</td>
</tr>
)}
</tbody>
</table>
);
Expand Down Expand Up @@ -255,6 +249,7 @@ FileList.propTypes = {
onSort: PropTypes.func.isRequired,
currentSortKey: PropTypes.string.isRequired,
currentSortOrder: PropTypes.oneOf(['asc', 'desc']).isRequired,
children: PropTypes.node,
};

FileListRow.propTypes = {
Expand Down
35 changes: 19 additions & 16 deletions frontend/pages/file-storage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,29 @@ function FileStoragePage() {
if (path !== "/") {
path = path.replace(/\/+$/, "") + "/";
}
const DEFAULT_SORT_KEY = "updatedAt";
const DEFAULT_SORT_ORDER = "desc";
const REVERSE_SORT_ORDER = "asc";

const sortKey = searchParams.get('sortKey') || DEFAULT_SORT_KEY;
const sortOrder = searchParams.get('sortOrder') || DEFAULT_SORT_ORDER;
const {
data: fetchedPublicFiles,
isLoading,
error,
// refetch (if we need to manually update)
} = useFileStorage(fileStorageServiceId, path);

} = useFileStorage(fileStorageServiceId, path, sortKey, sortOrder);

const detailsFile = searchParams.get('details');
const storageRoot = `${site.siteOrigin}/~assets`


const fileDetails = fetchedPublicFiles?.find(file => file.name === detailsFile);


const mockPagination = {
currentPage: parseInt(searchParams.get('page')) || 1,
totalPages: 20,
totalItems: 392,
};

const DEFAULT_SORT_KEY = "name";
const DEFAULT_SORT_ORDER = "asc";
const REVERSE_SORT_ORDER = "desc";

const sortKey = searchParams.get('sortKey') || DEFAULT_SORT_KEY;
const sortOrder = searchParams.get('sortOrder') || DEFAULT_SORT_ORDER;

const mockedSort = {
...mockPagination,
sortKey,
Expand Down Expand Up @@ -130,7 +125,8 @@ function FileStoragePage() {
});
};

if (isLoading) {

if (isLoading && fetchedPublicFiles === undefined) {
return <LoadingIndicator />;
}

Expand Down Expand Up @@ -169,15 +165,22 @@ function FileStoragePage() {
<FileList
path={path}
storageRoot={storageRoot}
data={fetchedPublicFiles}
data={fetchedPublicFiles || []}
onDelete={handleDelete}
onNavigate={handleNavigate}
onSort={handleSort}
onViewDetails={handleViewDetails}
currentSortKey={mockedSort.sortKey}
currentSortOrder={mockedSort.sortOrder}
/>

>
{!isLoading && fetchedPublicFiles?.length === 0 && (
<tr>
<td colSpan="99" className="text-italic">
No files or folders found.
</td>
</tr>
)}
</FileList>
<Pagination
currentPage={mockPagination.currentPage}
totalPages={mockPagination.totalPages}
Expand Down
12 changes: 10 additions & 2 deletions frontend/util/federalistApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,20 @@ export default {
return request(`tasks/${id}/report/${subPage || ''}`);
},

fetchPublicFiles(fileStorageId, path = '/') {
return request(`file-storage/${fileStorageId}?path=${path}`, {
// default sort from backend is updatedAt, descending. 'name' is also a possible key
fetchPublicFiles(fileStorageId, path = '/', sortKey = 'updatedAt', sortOrder = 'desc') {
const params = new URLSearchParams({
path,
sortKey,
sortOrder,
});
return request(`file-storage/${fileStorageId}?${params.toString()}`, {
method: 'GET',
});
},



createPublicDirectory(fileStorageId, parent = '/', name) {
return request(`file-storage/${fileStorageId}/directory`, {
method: 'POST',
Expand Down

0 comments on commit 9017b73

Please sign in to comment.