mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-21 18:55:16 +02:00
revert Composio Drive to folder tree, harden Picker for native Drive
This commit is contained in:
parent
2c9d01ba2d
commit
3bda6c1679
5 changed files with 558 additions and 436 deletions
|
|
@ -4,8 +4,9 @@ import { useAtomValue } from "jotai";
|
|||
import { AlertTriangle, Cable, Settings } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { type FC, forwardRef, useImperativeHandle, useMemo } from "react";
|
||||
import { type FC, forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react";
|
||||
import { documentTypeCountsAtom } from "@/atoms/documents/document-query.atoms";
|
||||
import { statusInboxItemsAtom } from "@/atoms/inbox/status-inbox.atom";
|
||||
import {
|
||||
globalNewLLMConfigsAtom,
|
||||
llmPreferencesAtom,
|
||||
|
|
@ -19,8 +20,8 @@ import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
|||
import { Spinner } from "@/components/ui/spinner";
|
||||
import { Tabs, TabsContent } from "@/components/ui/tabs";
|
||||
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
|
||||
import { statusInboxItemsAtom } from "@/atoms/inbox/status-inbox.atom";
|
||||
import { useConnectorsElectric } from "@/hooks/use-connectors-electric";
|
||||
import { PICKER_CLOSE_EVENT, PICKER_OPEN_EVENT } from "@/hooks/use-google-picker";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ConnectorDialogHeader } from "./connector-popup/components/connector-dialog-header";
|
||||
import { ConnectorConnectView } from "./connector-popup/connector-configs/views/connector-connect-view";
|
||||
|
|
@ -143,6 +144,18 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
setConnectorName,
|
||||
} = useConnectorDialog();
|
||||
|
||||
const [pickerOpen, setPickerOpen] = useState(false);
|
||||
useEffect(() => {
|
||||
const onOpen = () => setPickerOpen(true);
|
||||
const onClose = () => setPickerOpen(false);
|
||||
window.addEventListener(PICKER_OPEN_EVENT, onOpen);
|
||||
window.addEventListener(PICKER_CLOSE_EVENT, onClose);
|
||||
return () => {
|
||||
window.removeEventListener(PICKER_OPEN_EVENT, onOpen);
|
||||
window.removeEventListener(PICKER_CLOSE_EVENT, onClose);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Fetch connectors using Electric SQL + PGlite for real-time updates
|
||||
// This provides instant updates when connectors change, without polling
|
||||
const {
|
||||
|
|
@ -202,11 +215,20 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
if (!searchSpaceId) return null;
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onOpenChange={(open) => {
|
||||
if (!open && pickerOpen) return;
|
||||
handleOpenChange(open);
|
||||
}}
|
||||
modal={!pickerOpen}
|
||||
>
|
||||
{showTrigger && (
|
||||
<TooltipIconButton
|
||||
data-joyride="connector-icon"
|
||||
tooltip={hasConnectors ? `Manage ${activeConnectorsCount} connectors` : "Connect your data"}
|
||||
tooltip={
|
||||
hasConnectors ? `Manage ${activeConnectorsCount} connectors` : "Connect your data"
|
||||
}
|
||||
side="bottom"
|
||||
className={cn(
|
||||
"size-[34px] rounded-full p-1 flex items-center justify-center transition-colors relative",
|
||||
|
|
@ -215,7 +237,9 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
"border-0 ring-0 focus:ring-0 shadow-none focus:shadow-none"
|
||||
)}
|
||||
aria-label={
|
||||
hasConnectors ? `View ${activeConnectorsCount} connectors` : "Add your first connector"
|
||||
hasConnectors
|
||||
? `View ${activeConnectorsCount} connectors`
|
||||
: "Add your first connector"
|
||||
}
|
||||
onClick={() => handleOpenChange(true)}
|
||||
>
|
||||
|
|
@ -411,7 +435,9 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
indexingConnectorIds={indexingConnectorIds}
|
||||
onConnectOAuth={hasDocumentSummaryLLM ? handleConnectOAuth : () => {}}
|
||||
onConnectNonOAuth={hasDocumentSummaryLLM ? handleConnectNonOAuth : () => {}}
|
||||
onCreateWebcrawler={hasDocumentSummaryLLM ? handleCreateWebcrawler : () => {}}
|
||||
onCreateWebcrawler={
|
||||
hasDocumentSummaryLLM ? handleCreateWebcrawler : () => {}
|
||||
}
|
||||
onCreateYouTubeCrawler={
|
||||
hasDocumentSummaryLLM ? handleCreateYouTubeCrawler : () => {}
|
||||
}
|
||||
|
|
@ -441,6 +467,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
ConnectorIndicator.displayName = "ConnectorIndicator";
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import {
|
|||
FileText,
|
||||
FolderClosed,
|
||||
Image,
|
||||
Loader2,
|
||||
Presentation,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import type { FC } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ComposioDriveFolderTree } from "@/components/connectors/composio-drive-folder-tree";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
|
|
@ -23,7 +23,6 @@ import {
|
|||
} from "@/components/ui/select";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
|
||||
import { type PickerResult, useGooglePicker } from "@/hooks/use-google-picker";
|
||||
|
||||
interface ComposioDriveConfigProps {
|
||||
connector: SearchSourceConnector;
|
||||
|
|
@ -31,7 +30,7 @@ interface ComposioDriveConfigProps {
|
|||
onNameChange?: (name: string) => void;
|
||||
}
|
||||
|
||||
interface SelectedItem {
|
||||
interface SelectedFolder {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
|
@ -94,18 +93,20 @@ export const ComposioDriveConfig: FC<ComposioDriveConfigProps> = ({
|
|||
}) => {
|
||||
const isIndexable = connector.config?.is_indexable as boolean;
|
||||
|
||||
const existingFolders = (connector.config?.selected_folders as SelectedItem[] | undefined) || [];
|
||||
const existingFiles = (connector.config?.selected_files as SelectedItem[] | undefined) || [];
|
||||
const existingFolders =
|
||||
(connector.config?.selected_folders as SelectedFolder[] | undefined) || [];
|
||||
const existingFiles = (connector.config?.selected_files as SelectedFolder[] | undefined) || [];
|
||||
const existingIndexingOptions =
|
||||
(connector.config?.indexing_options as IndexingOptions | undefined) || DEFAULT_INDEXING_OPTIONS;
|
||||
|
||||
const [selectedFolders, setSelectedFolders] = useState<SelectedItem[]>(existingFolders);
|
||||
const [selectedFiles, setSelectedFiles] = useState<SelectedItem[]>(existingFiles);
|
||||
const [selectedFolders, setSelectedFolders] = useState<SelectedFolder[]>(existingFolders);
|
||||
const [selectedFiles, setSelectedFiles] = useState<SelectedFolder[]>(existingFiles);
|
||||
const [showFolderSelector, setShowFolderSelector] = useState(false);
|
||||
const [indexingOptions, setIndexingOptions] = useState<IndexingOptions>(existingIndexingOptions);
|
||||
|
||||
useEffect(() => {
|
||||
const folders = (connector.config?.selected_folders as SelectedItem[] | undefined) || [];
|
||||
const files = (connector.config?.selected_files as SelectedItem[] | undefined) || [];
|
||||
const folders = (connector.config?.selected_folders as SelectedFolder[] | undefined) || [];
|
||||
const files = (connector.config?.selected_files as SelectedFolder[] | undefined) || [];
|
||||
const options =
|
||||
(connector.config?.indexing_options as IndexingOptions | undefined) ||
|
||||
DEFAULT_INDEXING_OPTIONS;
|
||||
|
|
@ -115,8 +116,8 @@ export const ComposioDriveConfig: FC<ComposioDriveConfigProps> = ({
|
|||
}, [connector.config]);
|
||||
|
||||
const updateConfig = (
|
||||
folders: SelectedItem[],
|
||||
files: SelectedItem[],
|
||||
folders: SelectedFolder[],
|
||||
files: SelectedFolder[],
|
||||
options: IndexingOptions
|
||||
) => {
|
||||
if (onConfigChange) {
|
||||
|
|
@ -129,26 +130,15 @@ export const ComposioDriveConfig: FC<ComposioDriveConfigProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const handlePicked = useCallback(
|
||||
(result: PickerResult) => {
|
||||
const folders = result.folders.map((f) => ({ id: f.id, name: f.name }));
|
||||
const files = result.files.map((f) => ({ id: f.id, name: f.name }));
|
||||
const handleSelectFolders = (folders: SelectedFolder[]) => {
|
||||
setSelectedFolders(folders);
|
||||
setSelectedFiles(files);
|
||||
updateConfig(folders, files, indexingOptions);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[indexingOptions, connector.config]
|
||||
);
|
||||
updateConfig(folders, selectedFiles, indexingOptions);
|
||||
};
|
||||
|
||||
const {
|
||||
openPicker,
|
||||
loading: pickerLoading,
|
||||
error: pickerError,
|
||||
} = useGooglePicker({
|
||||
connectorId: connector.id,
|
||||
onPicked: handlePicked,
|
||||
});
|
||||
const handleSelectFiles = (files: SelectedFolder[]) => {
|
||||
setSelectedFiles(files);
|
||||
updateConfig(selectedFolders, files, indexingOptions);
|
||||
};
|
||||
|
||||
const handleIndexingOptionChange = (key: keyof IndexingOptions, value: number | boolean) => {
|
||||
const newOptions = { ...indexingOptions, [key]: value };
|
||||
|
|
@ -157,13 +147,13 @@ export const ComposioDriveConfig: FC<ComposioDriveConfigProps> = ({
|
|||
};
|
||||
|
||||
const handleRemoveFolder = (folderId: string) => {
|
||||
const newFolders = selectedFolders.filter((f) => f.id !== folderId);
|
||||
const newFolders = selectedFolders.filter((folder) => folder.id !== folderId);
|
||||
setSelectedFolders(newFolders);
|
||||
updateConfig(newFolders, selectedFiles, indexingOptions);
|
||||
};
|
||||
|
||||
const handleRemoveFile = (fileId: string) => {
|
||||
const newFiles = selectedFiles.filter((f) => f.id !== fileId);
|
||||
const newFiles = selectedFiles.filter((file) => file.id !== fileId);
|
||||
setSelectedFiles(newFiles);
|
||||
updateConfig(selectedFolders, newFiles, indexingOptions);
|
||||
};
|
||||
|
|
@ -242,18 +232,35 @@ export const ComposioDriveConfig: FC<ComposioDriveConfigProps> = ({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{showFolderSelector ? (
|
||||
<div className="space-y-2 sm:space-y-3">
|
||||
<ComposioDriveFolderTree
|
||||
connectorId={connector.id}
|
||||
selectedFolders={selectedFolders}
|
||||
onSelectFolders={handleSelectFolders}
|
||||
selectedFiles={selectedFiles}
|
||||
onSelectFiles={handleSelectFiles}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={openPicker}
|
||||
disabled={pickerLoading}
|
||||
size="sm"
|
||||
onClick={() => setShowFolderSelector(false)}
|
||||
className="bg-slate-400/5 dark:bg-white/5 border-slate-400/20 hover:bg-slate-400/10 dark:hover:bg-white/10 text-xs sm:text-sm h-8 sm:h-9"
|
||||
>
|
||||
{pickerLoading && <Loader2 className="size-3.5 mr-1.5 animate-spin" />}
|
||||
{totalSelected > 0 ? "Change Selection" : "Select from Google Drive"}
|
||||
Done Selecting
|
||||
</Button>
|
||||
|
||||
{pickerError && <p className="text-xs text-destructive">{pickerError}</p>}
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => setShowFolderSelector(true)}
|
||||
className="bg-slate-400/5 dark:bg-white/5 border-slate-400/20 hover:bg-slate-400/10 dark:hover:bg-white/10 text-xs sm:text-sm h-8 sm:h-9"
|
||||
>
|
||||
{totalSelected > 0 ? "Change Selection" : "Select Folders & Files"}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Indexing Options */}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { EnumConnectorName } from "@/contracts/enums/connector";
|
|||
|
||||
// OAuth Connectors (Quick Connect)
|
||||
export const OAUTH_CONNECTORS = [
|
||||
// // Uncomment for managed Google Connections
|
||||
// {
|
||||
// id: "google-drive-connector",
|
||||
// title: "Google Drive",
|
||||
|
|
@ -249,19 +248,84 @@ export interface AutoIndexConfig {
|
|||
}
|
||||
|
||||
export const AUTO_INDEX_DEFAULTS: Record<string, AutoIndexConfig> = {
|
||||
[EnumConnectorName.GOOGLE_GMAIL_CONNECTOR]: { daysBack: 30, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 30 days of emails." },
|
||||
[EnumConnectorName.COMPOSIO_GMAIL_CONNECTOR]: { daysBack: 30, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 30 days of emails." },
|
||||
[EnumConnectorName.SLACK_CONNECTOR]: { daysBack: 30, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 30 days of messages." },
|
||||
[EnumConnectorName.DISCORD_CONNECTOR]: { daysBack: 30, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 30 days of messages." },
|
||||
[EnumConnectorName.TEAMS_CONNECTOR]: { daysBack: 30, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 30 days of messages." },
|
||||
[EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR]: { daysBack: 90, daysForward: 90, frequencyMinutes: 1440, syncDescription: "Syncing 90 days of past and upcoming events." },
|
||||
[EnumConnectorName.COMPOSIO_GOOGLE_CALENDAR_CONNECTOR]: { daysBack: 90, daysForward: 90, frequencyMinutes: 1440, syncDescription: "Syncing 90 days of past and upcoming events." },
|
||||
[EnumConnectorName.LINEAR_CONNECTOR]: { daysBack: 90, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 90 days of issues." },
|
||||
[EnumConnectorName.JIRA_CONNECTOR]: { daysBack: 90, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 90 days of issues." },
|
||||
[EnumConnectorName.CLICKUP_CONNECTOR]: { daysBack: 90, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your last 90 days of tasks." },
|
||||
[EnumConnectorName.NOTION_CONNECTOR]: { daysBack: 365, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your pages." },
|
||||
[EnumConnectorName.CONFLUENCE_CONNECTOR]: { daysBack: 365, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your documentation." },
|
||||
[EnumConnectorName.AIRTABLE_CONNECTOR]: { daysBack: 365, daysForward: 0, frequencyMinutes: 1440, syncDescription: "Syncing your bases." },
|
||||
[EnumConnectorName.GOOGLE_GMAIL_CONNECTOR]: {
|
||||
daysBack: 30,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 30 days of emails.",
|
||||
},
|
||||
[EnumConnectorName.COMPOSIO_GMAIL_CONNECTOR]: {
|
||||
daysBack: 30,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 30 days of emails.",
|
||||
},
|
||||
[EnumConnectorName.SLACK_CONNECTOR]: {
|
||||
daysBack: 30,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 30 days of messages.",
|
||||
},
|
||||
[EnumConnectorName.DISCORD_CONNECTOR]: {
|
||||
daysBack: 30,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 30 days of messages.",
|
||||
},
|
||||
[EnumConnectorName.TEAMS_CONNECTOR]: {
|
||||
daysBack: 30,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 30 days of messages.",
|
||||
},
|
||||
[EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR]: {
|
||||
daysBack: 90,
|
||||
daysForward: 90,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing 90 days of past and upcoming events.",
|
||||
},
|
||||
[EnumConnectorName.COMPOSIO_GOOGLE_CALENDAR_CONNECTOR]: {
|
||||
daysBack: 90,
|
||||
daysForward: 90,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing 90 days of past and upcoming events.",
|
||||
},
|
||||
[EnumConnectorName.LINEAR_CONNECTOR]: {
|
||||
daysBack: 90,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 90 days of issues.",
|
||||
},
|
||||
[EnumConnectorName.JIRA_CONNECTOR]: {
|
||||
daysBack: 90,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 90 days of issues.",
|
||||
},
|
||||
[EnumConnectorName.CLICKUP_CONNECTOR]: {
|
||||
daysBack: 90,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your last 90 days of tasks.",
|
||||
},
|
||||
[EnumConnectorName.NOTION_CONNECTOR]: {
|
||||
daysBack: 365,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your pages.",
|
||||
},
|
||||
[EnumConnectorName.CONFLUENCE_CONNECTOR]: {
|
||||
daysBack: 365,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your documentation.",
|
||||
},
|
||||
[EnumConnectorName.AIRTABLE_CONNECTOR]: {
|
||||
daysBack: 365,
|
||||
daysForward: 0,
|
||||
frequencyMinutes: 1440,
|
||||
syncDescription: "Syncing your bases.",
|
||||
},
|
||||
};
|
||||
|
||||
export const AUTO_INDEX_CONNECTOR_TYPES = new Set<string>(Object.keys(AUTO_INDEX_DEFAULTS));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { connectorsApiService } from "@/lib/apis/connectors-api.service";
|
||||
|
||||
export interface PickerItem {
|
||||
|
|
@ -21,6 +21,8 @@ interface UseGooglePickerOptions {
|
|||
|
||||
const PICKER_SCRIPT_URL = "https://apis.google.com/js/api.js";
|
||||
const FOLDER_MIME = "application/vnd.google-apps.folder";
|
||||
export const PICKER_OPEN_EVENT = "google-picker-open";
|
||||
export const PICKER_CLOSE_EVENT = "google-picker-close";
|
||||
|
||||
let scriptLoadPromise: Promise<void> | null = null;
|
||||
let pickerApiPromise: Promise<void> | null = null;
|
||||
|
|
@ -68,6 +70,25 @@ export function useGooglePicker({ connectorId, onPicked }: UseGooglePickerOption
|
|||
const onPickedRef = useRef(onPicked);
|
||||
onPickedRef.current = onPicked;
|
||||
const openingRef = useRef(false);
|
||||
const pickerRef = useRef<google.picker.Picker | null>(null);
|
||||
|
||||
const closePicker = useCallback(() => {
|
||||
if (!pickerRef.current) return;
|
||||
window.dispatchEvent(new Event(PICKER_CLOSE_EVENT));
|
||||
pickerRef.current.dispose();
|
||||
pickerRef.current = null;
|
||||
openingRef.current = false;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const onEscape = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape" && pickerRef.current) {
|
||||
closePicker();
|
||||
}
|
||||
};
|
||||
window.addEventListener("keydown", onEscape);
|
||||
return () => window.removeEventListener("keydown", onEscape);
|
||||
}, [closePicker]);
|
||||
|
||||
const openPicker = useCallback(async () => {
|
||||
if (openingRef.current) return;
|
||||
|
|
@ -87,15 +108,18 @@ export function useGooglePicker({ connectorId, onPicked }: UseGooglePickerOption
|
|||
.setIncludeFolders(true)
|
||||
.setSelectFolderEnabled(true);
|
||||
|
||||
let pickerInstance: google.picker.Picker | null = null;
|
||||
|
||||
const picker = new google.picker.PickerBuilder()
|
||||
const builder = new google.picker.PickerBuilder()
|
||||
.addView(docsView)
|
||||
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
|
||||
.setOAuthToken(access_token)
|
||||
.setDeveloperKey(picker_api_key)
|
||||
.setOrigin(window.location.protocol + "//" + window.location.host)
|
||||
.setTitle("Select files and folders to index")
|
||||
.setTitle("Select files and folders to index");
|
||||
|
||||
if (picker_api_key) {
|
||||
builder.setDeveloperKey(picker_api_key);
|
||||
}
|
||||
|
||||
const picker = builder
|
||||
.setCallback((data: google.picker.ResponseObject) => {
|
||||
const action = data[google.picker.Response.ACTION];
|
||||
|
||||
|
|
@ -128,16 +152,16 @@ export function useGooglePicker({ connectorId, onPicked }: UseGooglePickerOption
|
|||
action === google.picker.Action.CANCEL ||
|
||||
action === google.picker.Action.ERROR
|
||||
) {
|
||||
pickerInstance?.dispose();
|
||||
pickerInstance = null;
|
||||
openingRef.current = false;
|
||||
closePicker();
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
pickerInstance = picker;
|
||||
pickerRef.current = picker;
|
||||
window.dispatchEvent(new Event(PICKER_OPEN_EVENT));
|
||||
picker.setVisible(true);
|
||||
} catch (err) {
|
||||
window.dispatchEvent(new Event(PICKER_CLOSE_EVENT));
|
||||
openingRef.current = false;
|
||||
const msg = err instanceof Error ? err.message : "Failed to open Google Picker";
|
||||
setError(msg);
|
||||
|
|
@ -145,7 +169,7 @@ export function useGooglePicker({ connectorId, onPicked }: UseGooglePickerOption
|
|||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [connectorId]);
|
||||
}, [connectorId, closePicker]);
|
||||
|
||||
return { openPicker, loading, error };
|
||||
return { openPicker, closePicker, loading, error };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ class ConnectorsApiService {
|
|||
return baseApiService.get<{
|
||||
access_token: string;
|
||||
client_id: string;
|
||||
picker_api_key: string;
|
||||
picker_api_key: string | null;
|
||||
}>(`/api/v1/connectors/${connectorId}/drive-picker-token`);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue