refactor(web): use React Query for Google Drive folder operations

- Fix errors in connectors-api.service (use .issues instead of .errors)
- Create useGoogleDriveFolders hook with proper React Query integration
- Add Google Drive folders cache keys with proper query invalidation
- Refactor GoogleDriveFolderTree to use React Query hook for root data
- Remove manual state management (isInitialized, setRootItems, loadRootItems)
- Remove unused state (driveFolders, isLoadingFolders) from manage page
- Simplify handleOpenDriveFolderDialog function
- Automatic loading, caching, error handling, and refetching via React Query
- Better performance with proper caching and state management
This commit is contained in:
CREDO23 2025-12-28 19:17:37 +02:00
parent c5c61a2c6b
commit 10c98745cd
6 changed files with 129 additions and 93 deletions

View file

@ -18,7 +18,8 @@ import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";
import { authenticatedFetch } from "@/lib/auth-utils";
import { useGoogleDriveFolders } from "@/hooks/use-google-drive-folders";
import { connectorsApiService } from "@/lib/apis/connectors-api.service";
interface DriveItem {
id: string;
@ -70,10 +71,13 @@ export function GoogleDriveFolderTree({
selectedFolders,
onSelectFolders,
}: GoogleDriveFolderTreeProps) {
const [rootItems, setRootItems] = useState<DriveItem[]>([]);
const [itemStates, setItemStates] = useState<Map<string, ItemTreeNode>>(new Map());
const [isLoadingRoot, setIsLoadingRoot] = useState(false);
const [isInitialized, setIsInitialized] = useState(false);
const { data: rootData, isLoading: isLoadingRoot } = useGoogleDriveFolders({
connectorId,
});
const rootItems = rootData?.items || [];
const isFolderSelected = (folderId: string): boolean => {
return selectedFolders.some((f) => f.id === folderId);
@ -87,29 +91,6 @@ export function GoogleDriveFolderTree({
}
};
/**
* Load root-level folders and files from Google Drive.
*/
const loadRootItems = async () => {
if (isInitialized) return;
setIsLoadingRoot(true);
try {
const response = await authenticatedFetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/connectors/${connectorId}/google-drive/folders`
);
if (!response.ok) throw new Error("Failed to load items");
const data = await response.json();
setRootItems(data.items || []);
setIsInitialized(true);
} catch (error) {
console.error("Error loading root items:", error);
} finally {
setIsLoadingRoot(false);
}
};
/**
* Find an item by ID across all loaded items (root and nested).
*/
@ -154,12 +135,10 @@ export function GoogleDriveFolderTree({
return newMap;
});
const response = await authenticatedFetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/connectors/${connectorId}/google-drive/folders?parent_id=${folderId}`
);
if (!response.ok) throw new Error("Failed to load folder contents");
const data = await response.json();
const data = await connectorsApiService.listGoogleDriveFolders({
connector_id: connectorId,
parent_id: folderId,
});
const items = data.items || [];
setItemStates((prev) => {
@ -301,10 +280,6 @@ export function GoogleDriveFolderTree({
);
};
if (!isInitialized && !isLoadingRoot) {
loadRootItems();
}
return (
<div className="border rounded-md w-full overflow-hidden">
<ScrollArea className="h-[450px] w-full">