zerobyte/app/client/components/file-browsers/local-file-browser.tsx
Nico ca8248b2a0
ui: scroll to error (#541)
* refactor: scroll to first error when submitting a form

* refactor: split file browsers into dedicated components with base

* chore: pr feedbacks
2026-02-18 20:13:09 +01:00

63 lines
2.2 KiB
TypeScript

import { useQuery, useQueryClient } from "@tanstack/react-query";
import { browseFilesystemOptions } from "~/client/api-client/@tanstack/react-query.gen";
import { FileBrowser, type FileBrowserUiProps } from "~/client/components/file-browsers/file-browser";
import { useFileBrowser } from "~/client/hooks/use-file-browser";
import { parseError } from "~/client/lib/errors";
const normalizeAbsolutePath = (path?: string): string => {
if (!path) return "/";
const withLeadingSlash = path.startsWith("/") ? path : `/${path}`;
const trimmed = withLeadingSlash.replace(/\/+$/, "");
return trimmed || "/";
};
type LocalFileBrowserProps = FileBrowserUiProps & {
initialPath?: string;
enabled?: boolean;
};
export const LocalFileBrowser = ({ initialPath = "/", enabled = true, ...uiProps }: LocalFileBrowserProps) => {
const queryClient = useQueryClient();
const normalizedInitialPath = normalizeAbsolutePath(initialPath);
const { data, isLoading, error } = useQuery({
...browseFilesystemOptions({ query: { path: normalizedInitialPath } }),
enabled,
});
const fileBrowser = useFileBrowser({
initialData: data,
isLoading,
fetchFolder: async (path) => {
return await queryClient.ensureQueryData(browseFilesystemOptions({ query: { path } }));
},
prefetchFolder: (path) => {
void queryClient.prefetchQuery(browseFilesystemOptions({ query: { path } }));
},
});
const errorDetails = parseError(error)?.message;
const errorMessage = errorDetails
? `Failed to load directories: ${errorDetails}`
: error
? "Failed to load directories"
: undefined;
return (
<FileBrowser
{...uiProps}
fileArray={fileBrowser.fileArray}
expandedFolders={fileBrowser.expandedFolders}
loadingFolders={fileBrowser.loadingFolders}
onFolderExpand={fileBrowser.handleFolderExpand}
onFolderHover={fileBrowser.handleFolderHover}
onLoadMore={fileBrowser.handleLoadMore}
getFolderPagination={fileBrowser.getFolderPagination}
isLoading={fileBrowser.isLoading}
isEmpty={fileBrowser.isEmpty}
errorMessage={errorMessage}
loadingMessage={uiProps.loadingMessage ?? "Loading directories..."}
emptyMessage={uiProps.emptyMessage ?? "No subdirectories found"}
/>
);
};