mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-10 22:32:16 +02:00
feat(rename): complete searchSpace to workspace transition across frontend and backend
- Introduced a comprehensive specification for renaming `searchSpace` to `workspace` in `surfsense_web` and `surfsense_desktop`, ensuring all TypeScript identifiers, React props, and local data structures are updated. - Implemented migration shims for persisted local state to prevent data loss during the transition. - Updated observability metrics and IPC channels to reflect the new naming convention. - Removed legacy `active-search-space` module and replaced it with `active-workspace` to maintain consistency. - Ensured no behavioral changes or data loss for users during the renaming process.
This commit is contained in:
parent
2a020629c5
commit
a8c1fb660d
259 changed files with 5480 additions and 2285 deletions
|
|
@ -491,7 +491,7 @@ export const AssistantMessage: FC = () => {
|
|||
const commentPanelRef = useRef<HTMLDivElement>(null);
|
||||
const commentTriggerRef = useRef<HTMLButtonElement>(null);
|
||||
const messageId = useAuiState(({ message }) => message?.id);
|
||||
const searchSpaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const workspaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const dbMessageId = parseMessageId(messageId);
|
||||
const commentsEnabled = useAtomValue(commentsEnabledAtom);
|
||||
|
||||
|
|
@ -520,7 +520,7 @@ export const AssistantMessage: FC = () => {
|
|||
const commentCount = commentsData?.total_count ?? 0;
|
||||
const hasComments = commentCount > 0;
|
||||
|
||||
const showCommentTrigger = searchSpaceId && commentsEnabled && !isMessageStreaming && dbMessageId;
|
||||
const showCommentTrigger = workspaceId && commentsEnabled && !isMessageStreaming && dbMessageId;
|
||||
|
||||
// Close floating panel when clicking outside (but not on portaled popover/dropdown content)
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ interface ConnectorIndicatorProps {
|
|||
|
||||
export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, ConnectorIndicatorProps>(
|
||||
(_props, ref) => {
|
||||
const searchSpaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const workspaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
|
||||
// Real-time document type counts via Zero (updates instantly as docs are indexed)
|
||||
const documentTypeCounts = useZeroDocumentTypeCounts(searchSpaceId);
|
||||
const documentTypeCounts = useZeroDocumentTypeCounts(workspaceId);
|
||||
// Read status inbox items from shared atom (populated by LayoutDataProvider)
|
||||
// instead of creating a duplicate useInbox("status") hook.
|
||||
const statusInboxItems = useAtomValue(statusInboxItemsAtom);
|
||||
|
|
@ -124,7 +124,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
loading: connectorsLoading,
|
||||
error: connectorsError,
|
||||
refreshConnectors: refreshConnectorsSync,
|
||||
} = useConnectorsSync(searchSpaceId);
|
||||
} = useConnectorsSync(workspaceId);
|
||||
|
||||
const useSyncData = connectorsFromSync.length > 0 || (connectorsLoading && !connectorsError);
|
||||
const connectors = useSyncData ? connectorsFromSync : allConnectors || [];
|
||||
|
|
@ -142,7 +142,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
inboxItems
|
||||
);
|
||||
|
||||
// Get document types that have documents in the search space
|
||||
// Get document types that have documents in the workspace
|
||||
const activeDocumentTypes = documentTypeCounts
|
||||
? Object.entries(documentTypeCounts).filter(([, count]) => count > 0)
|
||||
: [];
|
||||
|
|
@ -163,7 +163,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
open: () => handleOpenChange(true),
|
||||
}));
|
||||
|
||||
if (!searchSpaceId) return null;
|
||||
if (!workspaceId) return null;
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} modal={false} onOpenChange={handleOpenChange}>
|
||||
|
|
@ -191,8 +191,8 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
>
|
||||
<DialogTitle className="sr-only">Manage Connectors</DialogTitle>
|
||||
{/* YouTube Crawler View - shown when adding YouTube videos */}
|
||||
{isYouTubeView && searchSpaceId ? (
|
||||
<YouTubeCrawlerView searchSpaceId={searchSpaceId} onBack={handleBackFromYouTube} />
|
||||
{isYouTubeView && workspaceId ? (
|
||||
<YouTubeCrawlerView workspaceId={workspaceId} onBack={handleBackFromYouTube} />
|
||||
) : viewingMCPList ? (
|
||||
<ConnectorAccountsListView
|
||||
connectorType="MCP_CONNECTOR"
|
||||
|
|
@ -253,7 +253,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
isSaving={isSaving}
|
||||
isDisconnecting={isDisconnecting}
|
||||
isIndexing={indexingConnectorIds.has(editingConnector.id)}
|
||||
searchSpaceId={searchSpaceId?.toString()}
|
||||
workspaceId={workspaceId?.toString()}
|
||||
onStartDateChange={setStartDate}
|
||||
onEndDateChange={setEndDate}
|
||||
onPeriodicEnabledChange={setPeriodicEnabled}
|
||||
|
|
@ -346,7 +346,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
|||
<TabsContent value="all" className="m-0">
|
||||
<AllConnectorsTab
|
||||
searchQuery={searchQuery}
|
||||
searchSpaceId={searchSpaceId}
|
||||
workspaceId={workspaceId}
|
||||
connectedTypes={connectedTypes}
|
||||
connectingId={connectingId}
|
||||
allConnectors={connectors}
|
||||
|
|
|
|||
|
|
@ -159,17 +159,17 @@ export const ObsidianConnectForm: FC<ConnectFormProps> = ({ onBack }) => {
|
|||
|
||||
<div className="h-px bg-border/60" />
|
||||
|
||||
{/* Step 4 — Pick search space */}
|
||||
{/* Step 4 — Pick workspace */}
|
||||
<article>
|
||||
<header className="mb-3 flex items-center gap-2">
|
||||
<div className="flex size-7 items-center justify-center rounded-md border border-slate-400/30 text-xs font-medium">
|
||||
4
|
||||
</div>
|
||||
<h3 className="text-sm font-medium sm:text-base">Pick this search space</h3>
|
||||
<h3 className="text-sm font-medium sm:text-base">Pick this workspace</h3>
|
||||
</header>
|
||||
<p className="text-[11px] text-muted-foreground sm:text-xs">
|
||||
In the plugin's <span className="font-medium">Search space</span> setting, choose the
|
||||
search space you want this vault to sync into. The connector will appear here
|
||||
workspace you want this vault to sync into. The connector will appear here
|
||||
automatically once the plugin makes its first sync.
|
||||
</p>
|
||||
</article>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export function getConnectorBenefits(connectorType: string): string[] | null {
|
|||
LINEAR_CONNECTOR: [
|
||||
"Search through all your Linear issues and comments",
|
||||
"Access issue titles, descriptions, and full discussion threads",
|
||||
"Connect your team's project management directly to your search space",
|
||||
"Connect your team's project management directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Linear content",
|
||||
"Index your Linear issues for enhanced search capabilities",
|
||||
],
|
||||
|
|
@ -36,63 +36,63 @@ export function getConnectorBenefits(connectorType: string): string[] | null {
|
|||
SLACK_CONNECTOR: [
|
||||
"Search through all your Slack messages and conversations",
|
||||
"Access messages from public and private channels",
|
||||
"Connect your team's communications directly to your search space",
|
||||
"Connect your team's communications directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Slack content",
|
||||
"Index your Slack conversations for enhanced search capabilities",
|
||||
],
|
||||
DISCORD_CONNECTOR: [
|
||||
"Search through all your Discord messages and conversations",
|
||||
"Access messages from all accessible channels",
|
||||
"Connect your community's communications directly to your search space",
|
||||
"Connect your community's communications directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Discord content",
|
||||
"Index your Discord conversations for enhanced search capabilities",
|
||||
],
|
||||
NOTION_CONNECTOR: [
|
||||
"Search through all your Notion pages and databases",
|
||||
"Access page content, properties, and metadata",
|
||||
"Connect your knowledge base directly to your search space",
|
||||
"Connect your knowledge base directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Notion content",
|
||||
"Index your Notion workspace for enhanced search capabilities",
|
||||
],
|
||||
CONFLUENCE_CONNECTOR: [
|
||||
"Search through all your Confluence pages and spaces",
|
||||
"Access page content, comments, and attachments",
|
||||
"Connect your team's documentation directly to your search space",
|
||||
"Connect your team's documentation directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Confluence content",
|
||||
"Index your Confluence workspace for enhanced search capabilities",
|
||||
],
|
||||
BOOKSTACK_CONNECTOR: [
|
||||
"Search through all your BookStack pages and books",
|
||||
"Access page content, chapters, and documentation",
|
||||
"Connect your documentation directly to your search space",
|
||||
"Connect your documentation directly to your workspace",
|
||||
"Keep your search results up-to-date with latest BookStack content",
|
||||
"Index your BookStack instance for enhanced search capabilities",
|
||||
],
|
||||
GITHUB_CONNECTOR: [
|
||||
"Search through code, issues, and documentation from GitHub repositories",
|
||||
"Access repository content, pull requests, and discussions",
|
||||
"Connect your codebase directly to your search space",
|
||||
"Connect your codebase directly to your workspace",
|
||||
"Keep your search results up-to-date with latest GitHub content",
|
||||
"Index your GitHub repositories for enhanced search capabilities",
|
||||
],
|
||||
JIRA_CONNECTOR: [
|
||||
"Search through all your Jira issues and tickets",
|
||||
"Access issue descriptions, comments, and project data",
|
||||
"Connect your project management directly to your search space",
|
||||
"Connect your project management directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Jira content",
|
||||
"Index your Jira projects for enhanced search capabilities",
|
||||
],
|
||||
CLICKUP_CONNECTOR: [
|
||||
"Search through all your ClickUp tasks and projects",
|
||||
"Access task descriptions, comments, and project data",
|
||||
"Connect your task management directly to your search space",
|
||||
"Connect your task management directly to your workspace",
|
||||
"Keep your search results up-to-date with latest ClickUp content",
|
||||
"Index your ClickUp workspace for enhanced search capabilities",
|
||||
],
|
||||
LUMA_CONNECTOR: [
|
||||
"Search through all your Luma events",
|
||||
"Access event details, descriptions, and attendee information",
|
||||
"Connect your events directly to your search space",
|
||||
"Connect your events directly to your workspace",
|
||||
"Keep your search results up-to-date with latest Luma content",
|
||||
"Index your Luma events for enhanced search capabilities",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ export const CirclebackConfig: FC<CirclebackConfigProps> = ({ connector, onNameC
|
|||
<AlertDescription>
|
||||
Configure this URL in Circleback Settings → Automations → Create automation → Send
|
||||
webhook request. The webhook will automatically send meeting notes, transcripts, and
|
||||
action items to this search space.
|
||||
action items to this workspace.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export interface ConnectorConfigProps {
|
|||
connector: SearchSourceConnector;
|
||||
onConfigChange?: (config: Record<string, unknown>) => void;
|
||||
onNameChange?: (name: string) => void;
|
||||
searchSpaceId?: string;
|
||||
workspaceId?: string;
|
||||
}
|
||||
|
||||
export type ConnectorConfigComponent = FC<ConnectorConfigProps>;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ interface ConnectorEditViewProps {
|
|||
isSaving: boolean;
|
||||
isDisconnecting: boolean;
|
||||
isIndexing?: boolean;
|
||||
searchSpaceId?: string;
|
||||
workspaceId?: string;
|
||||
onStartDateChange: (date: Date | undefined) => void;
|
||||
onEndDateChange: (date: Date | undefined) => void;
|
||||
onPeriodicEnabledChange: (enabled: boolean) => void;
|
||||
|
|
@ -65,7 +65,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
|
|||
isSaving,
|
||||
isDisconnecting,
|
||||
isIndexing = false,
|
||||
searchSpaceId,
|
||||
workspaceId,
|
||||
onStartDateChange,
|
||||
onEndDateChange,
|
||||
onPeriodicEnabledChange,
|
||||
|
|
@ -78,7 +78,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
|
|||
onConfigChange,
|
||||
onNameChange,
|
||||
}) => {
|
||||
const searchSpaceIdAtom = useAtomValue(activeWorkspaceIdAtom);
|
||||
const workspaceIdAtom = useAtomValue(activeWorkspaceIdAtom);
|
||||
const isAuthExpired = connector.config?.auth_expired === true;
|
||||
const reauthEndpoint = getReauthEndpoint(connector);
|
||||
const [reauthing, setReauthing] = useState(false);
|
||||
|
|
@ -91,7 +91,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
|
|||
(connector.is_indexable || connector.connector_type === EnumConnectorName.OBSIDIAN_CONNECTOR);
|
||||
|
||||
const handleReauth = useCallback(async () => {
|
||||
const spaceId = searchSpaceId ?? searchSpaceIdAtom;
|
||||
const spaceId = workspaceId ?? workspaceIdAtom;
|
||||
if (!spaceId || !reauthEndpoint) return;
|
||||
setReauthing(true);
|
||||
try {
|
||||
|
|
@ -119,7 +119,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
|
|||
} finally {
|
||||
setReauthing(false);
|
||||
}
|
||||
}, [searchSpaceId, searchSpaceIdAtom, reauthEndpoint, connector.id]);
|
||||
}, [workspaceId, workspaceIdAtom, reauthEndpoint, connector.id]);
|
||||
|
||||
// Get connector-specific config component (MCP-backed connectors use a generic view)
|
||||
const ConnectorConfigComponent = useMemo(() => {
|
||||
|
|
@ -273,7 +273,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
|
|||
connector={connector}
|
||||
onConfigChange={onConfigChange}
|
||||
onNameChange={onNameChange}
|
||||
searchSpaceId={searchSpaceId}
|
||||
workspaceId={workspaceId}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ function clearOAuthResultCookie(): void {
|
|||
}
|
||||
|
||||
export const useConnectorDialog = () => {
|
||||
const searchSpaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const workspaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const { data: allConnectors, refetch: refetchAllConnectors } = useAtomValue(connectorsAtom);
|
||||
const { mutateAsync: indexConnector } = useAtomValue(indexConnectorMutationAtom);
|
||||
const { mutateAsync: updateConnector } = useAtomValue(updateConnectorMutationAtom);
|
||||
|
|
@ -140,7 +140,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
const handleAutoIndex = useCallback(
|
||||
async (connector: SearchSourceConnector, connectorTitle: string, connectorType: string) => {
|
||||
if (!searchSpaceId || isAutoIndexingRef.current) return;
|
||||
if (!workspaceId || isAutoIndexingRef.current) return;
|
||||
isAutoIndexingRef.current = true;
|
||||
|
||||
const defaults = AUTO_INDEX_DEFAULTS[connectorType];
|
||||
|
|
@ -165,13 +165,13 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: connector.id,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
start_date: format(startDate, "yyyy-MM-dd"),
|
||||
end_date: format(endDate, "yyyy-MM-dd"),
|
||||
},
|
||||
});
|
||||
|
||||
trackIndexWithDateRangeStarted(Number(searchSpaceId), connectorType, connector.id, {
|
||||
trackIndexWithDateRangeStarted(Number(workspaceId), connectorType, connector.id, {
|
||||
hasStartDate: true,
|
||||
hasEndDate: true,
|
||||
});
|
||||
|
|
@ -188,13 +188,13 @@ export const useConnectorDialog = () => {
|
|||
});
|
||||
} finally {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
queryKey: cacheKeys.logs.summary(Number(workspaceId)),
|
||||
});
|
||||
await refetchAllConnectors();
|
||||
isAutoIndexingRef.current = false;
|
||||
}
|
||||
},
|
||||
[searchSpaceId, indexConnector, updateConnector, refetchAllConnectors]
|
||||
[workspaceId, indexConnector, updateConnector, refetchAllConnectors]
|
||||
);
|
||||
|
||||
// YouTube view state
|
||||
|
|
@ -206,7 +206,7 @@ export const useConnectorDialog = () => {
|
|||
// Consume OAuth result from cookie (set by /connectors/callback route handler)
|
||||
useEffect(() => {
|
||||
const raw = readOAuthResultCookie();
|
||||
if (!raw || !searchSpaceId) return;
|
||||
if (!raw || !workspaceId) return;
|
||||
clearOAuthResultCookie();
|
||||
|
||||
const result = parseOAuthCallbackResult(raw);
|
||||
|
|
@ -221,7 +221,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
if (oauthConnector) {
|
||||
trackConnectorSetupFailure(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
oauthConnector.connectorType,
|
||||
result.error,
|
||||
"oauth_callback"
|
||||
|
|
@ -292,7 +292,7 @@ export const useConnectorDialog = () => {
|
|||
const connectorValidation = searchSourceConnector.safeParse(newConnector);
|
||||
if (connectorValidation.success) {
|
||||
trackConnectorConnected(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
oauthConnector.connectorType,
|
||||
newConnector.id
|
||||
);
|
||||
|
|
@ -338,20 +338,20 @@ export const useConnectorDialog = () => {
|
|||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [searchSpaceId, handleAutoIndex, refetchAllConnectors, setIsOpen]);
|
||||
}, [workspaceId, handleAutoIndex, refetchAllConnectors, setIsOpen]);
|
||||
|
||||
// Handle OAuth connection
|
||||
const handleConnectOAuth = useCallback(
|
||||
async (connector: (typeof OAUTH_CONNECTORS)[number] | (typeof COMPOSIO_CONNECTORS)[number]) => {
|
||||
if (!searchSpaceId || !connector.authEndpoint) return;
|
||||
if (!workspaceId || !connector.authEndpoint) return;
|
||||
|
||||
// Set connecting state immediately to disable button and show spinner
|
||||
setConnectingId(connector.id);
|
||||
|
||||
trackConnectorSetupStarted(Number(searchSpaceId), connector.connectorType, "oauth_click");
|
||||
trackConnectorSetupStarted(Number(workspaceId), connector.connectorType, "oauth_click");
|
||||
|
||||
try {
|
||||
const url = buildBackendUrl(connector.authEndpoint, { space_id: searchSpaceId });
|
||||
const url = buildBackendUrl(connector.authEndpoint, { space_id: workspaceId });
|
||||
|
||||
const response = await authenticatedFetch(url, { method: "GET" });
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ export const useConnectorDialog = () => {
|
|||
} catch (error) {
|
||||
console.error(`Error connecting to ${connector.title}:`, error);
|
||||
trackConnectorSetupFailure(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
connector.connectorType,
|
||||
error instanceof Error ? error.message : "oauth_initiation_failed",
|
||||
"oauth_init"
|
||||
|
|
@ -384,22 +384,22 @@ export const useConnectorDialog = () => {
|
|||
setConnectingId(null);
|
||||
}
|
||||
},
|
||||
[searchSpaceId]
|
||||
[workspaceId]
|
||||
);
|
||||
|
||||
// Handle creating YouTube crawler (not a connector, shows view in popup)
|
||||
const handleCreateYouTubeCrawler = useCallback(() => {
|
||||
if (!searchSpaceId) return;
|
||||
if (!workspaceId) return;
|
||||
setIsYouTubeView(true);
|
||||
}, [searchSpaceId]);
|
||||
}, [workspaceId]);
|
||||
|
||||
// Handle creating webcrawler connector
|
||||
const handleCreateWebcrawler = useCallback(async () => {
|
||||
if (!searchSpaceId) return;
|
||||
if (!workspaceId) return;
|
||||
|
||||
setConnectingId("webcrawler-connector");
|
||||
trackConnectorSetupStarted(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
EnumConnectorName.WEBCRAWLER_CONNECTOR,
|
||||
"webcrawler_quick_add"
|
||||
);
|
||||
|
|
@ -418,7 +418,7 @@ export const useConnectorDialog = () => {
|
|||
enable_vision_llm: false,
|
||||
},
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -433,7 +433,7 @@ export const useConnectorDialog = () => {
|
|||
if (connectorValidation.success) {
|
||||
// Track webcrawler connector connected
|
||||
trackConnectorConnected(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
EnumConnectorName.WEBCRAWLER_CONNECTOR,
|
||||
connector.id
|
||||
);
|
||||
|
|
@ -453,7 +453,7 @@ export const useConnectorDialog = () => {
|
|||
} catch (error) {
|
||||
console.error("Error creating webcrawler connector:", error);
|
||||
trackConnectorSetupFailure(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
EnumConnectorName.WEBCRAWLER_CONNECTOR,
|
||||
error instanceof Error ? error.message : "webcrawler_create_failed",
|
||||
"webcrawler_quick_add"
|
||||
|
|
@ -462,18 +462,18 @@ export const useConnectorDialog = () => {
|
|||
} finally {
|
||||
setConnectingId(null);
|
||||
}
|
||||
}, [searchSpaceId, createConnector, refetchAllConnectors, setIsOpen]);
|
||||
}, [workspaceId, createConnector, refetchAllConnectors, setIsOpen]);
|
||||
|
||||
// Handle connecting non-OAuth connectors (like Tavily API, Obsidian plugin, etc.)
|
||||
const handleConnectNonOAuth = useCallback(
|
||||
(connectorType: string) => {
|
||||
if (!searchSpaceId) return;
|
||||
if (!workspaceId) return;
|
||||
|
||||
trackConnectorSetupStarted(Number(searchSpaceId), connectorType, "non_oauth_click");
|
||||
trackConnectorSetupStarted(Number(workspaceId), connectorType, "non_oauth_click");
|
||||
|
||||
setConnectingConnectorType(connectorType);
|
||||
},
|
||||
[searchSpaceId]
|
||||
[workspaceId]
|
||||
);
|
||||
|
||||
// Handle submitting connect form
|
||||
|
|
@ -495,7 +495,7 @@ export const useConnectorDialog = () => {
|
|||
},
|
||||
onIndexingStart?: (connectorId: number) => void
|
||||
) => {
|
||||
if (!searchSpaceId || !connectingConnectorType) {
|
||||
if (!workspaceId || !connectingConnectorType) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -519,7 +519,7 @@ export const useConnectorDialog = () => {
|
|||
enable_vision_llm: false,
|
||||
},
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
},
|
||||
});
|
||||
// Refetch connectors to get the new one
|
||||
|
|
@ -536,7 +536,7 @@ export const useConnectorDialog = () => {
|
|||
const currentConnectorType = connectingConnectorType;
|
||||
|
||||
// Track connector connected event for non-OAuth connectors
|
||||
trackConnectorConnected(Number(searchSpaceId), currentConnectorType, connector.id);
|
||||
trackConnectorConnected(Number(workspaceId), currentConnectorType, connector.id);
|
||||
|
||||
// Find connector title from constants
|
||||
const connectorInfo = OTHER_CONNECTORS.find(
|
||||
|
|
@ -612,7 +612,7 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: connector.id,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
start_date: startDateStr,
|
||||
end_date: endDateStr,
|
||||
},
|
||||
|
|
@ -631,7 +631,7 @@ export const useConnectorDialog = () => {
|
|||
setIndexingConnectorConfig(null);
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
queryKey: cacheKeys.logs.summary(Number(workspaceId)),
|
||||
});
|
||||
|
||||
await refetchAllConnectors();
|
||||
|
|
@ -684,7 +684,7 @@ export const useConnectorDialog = () => {
|
|||
} catch (error) {
|
||||
console.error("Error creating connector:", error);
|
||||
trackConnectorSetupFailure(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
connectingConnectorType ?? formData.connector_type,
|
||||
error instanceof Error ? error.message : "connector_create_failed",
|
||||
"non_oauth_form"
|
||||
|
|
@ -698,7 +698,7 @@ export const useConnectorDialog = () => {
|
|||
},
|
||||
[
|
||||
connectingConnectorType,
|
||||
searchSpaceId,
|
||||
workspaceId,
|
||||
createConnector,
|
||||
refetchAllConnectors,
|
||||
updateConnector,
|
||||
|
|
@ -724,7 +724,7 @@ export const useConnectorDialog = () => {
|
|||
// Handle viewing accounts list for OAuth connector type
|
||||
const handleViewAccountsList = useCallback(
|
||||
(connectorType: string, _connectorTitle?: string) => {
|
||||
if (!searchSpaceId) return;
|
||||
if (!workspaceId) return;
|
||||
|
||||
const oauthConnector =
|
||||
OAUTH_CONNECTORS.find((c) => c.connectorType === connectorType) ||
|
||||
|
|
@ -736,7 +736,7 @@ export const useConnectorDialog = () => {
|
|||
});
|
||||
}
|
||||
},
|
||||
[searchSpaceId]
|
||||
[workspaceId]
|
||||
);
|
||||
|
||||
// Handle going back from accounts list view
|
||||
|
|
@ -746,9 +746,9 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Handle viewing MCP list
|
||||
const handleViewMCPList = useCallback(() => {
|
||||
if (!searchSpaceId) return;
|
||||
if (!workspaceId) return;
|
||||
setViewingMCPList(true);
|
||||
}, [searchSpaceId]);
|
||||
}, [workspaceId]);
|
||||
|
||||
// Handle going back from MCP list view
|
||||
const handleBackFromMCPList = useCallback(() => {
|
||||
|
|
@ -765,7 +765,7 @@ export const useConnectorDialog = () => {
|
|||
// Handle starting indexing
|
||||
const handleStartIndexing = useCallback(
|
||||
async (refreshConnectors: () => void) => {
|
||||
if (!indexingConfig || !searchSpaceId) return;
|
||||
if (!indexingConfig || !workspaceId) return;
|
||||
|
||||
// Validate date range (skip for Google Drive, Composio Drive, OneDrive, Dropbox, and Webcrawler)
|
||||
if (
|
||||
|
|
@ -847,7 +847,7 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: indexingConfig.connectorId,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
},
|
||||
body: {
|
||||
folders: selectedFolders || [],
|
||||
|
|
@ -870,14 +870,14 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: indexingConfig.connectorId,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
await indexConnector({
|
||||
connector_id: indexingConfig.connectorId,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
start_date: startDateStr,
|
||||
end_date: endDateStr,
|
||||
},
|
||||
|
|
@ -886,7 +886,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Track index with date range started event
|
||||
trackIndexWithDateRangeStarted(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
indexingConfig.connectorType,
|
||||
indexingConfig.connectorId,
|
||||
{
|
||||
|
|
@ -898,7 +898,7 @@ export const useConnectorDialog = () => {
|
|||
// Track periodic indexing started if enabled
|
||||
if (periodicEnabled) {
|
||||
trackPeriodicIndexingStarted(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
indexingConfig.connectorType,
|
||||
indexingConfig.connectorId,
|
||||
parseInt(frequencyMinutes, 10)
|
||||
|
|
@ -915,7 +915,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
refreshConnectors();
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
queryKey: cacheKeys.logs.summary(Number(workspaceId)),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error starting indexing:", error);
|
||||
|
|
@ -926,7 +926,7 @@ export const useConnectorDialog = () => {
|
|||
},
|
||||
[
|
||||
indexingConfig,
|
||||
searchSpaceId,
|
||||
workspaceId,
|
||||
startDate,
|
||||
endDate,
|
||||
indexConnector,
|
||||
|
|
@ -951,7 +951,7 @@ export const useConnectorDialog = () => {
|
|||
// Handle starting edit mode
|
||||
const handleStartEdit = useCallback(
|
||||
(connector: SearchSourceConnector) => {
|
||||
if (!searchSpaceId) return;
|
||||
if (!workspaceId) return;
|
||||
|
||||
// For MCP connectors from "All Connectors" tab, show the list view instead of directly editing
|
||||
// (unless we're already in the MCP list view or on the Active tab where individual MCPs are shown)
|
||||
|
|
@ -986,11 +986,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Track index with date range opened event
|
||||
if (connector.is_indexable) {
|
||||
trackIndexWithDateRangeOpened(
|
||||
Number(searchSpaceId),
|
||||
connector.connector_type,
|
||||
connector.id
|
||||
);
|
||||
trackIndexWithDateRangeOpened(Number(workspaceId), connector.connector_type, connector.id);
|
||||
}
|
||||
|
||||
setEditingConnector(connector);
|
||||
|
|
@ -1001,13 +997,13 @@ export const useConnectorDialog = () => {
|
|||
setStartDate(undefined);
|
||||
setEndDate(undefined);
|
||||
},
|
||||
[searchSpaceId, viewingAccountsType, viewingMCPList, handleViewMCPList, activeTab]
|
||||
[workspaceId, viewingAccountsType, viewingMCPList, handleViewMCPList, activeTab]
|
||||
);
|
||||
|
||||
// Handle saving connector changes
|
||||
const handleSaveConnector = useCallback(
|
||||
async (refreshConnectors: () => void) => {
|
||||
if (!editingConnector || !searchSpaceId || isSaving) return;
|
||||
if (!editingConnector || !workspaceId || isSaving) return;
|
||||
|
||||
// Validate date range (skip for Google Drive/OneDrive/Dropbox which uses folder selection, Webcrawler which uses config, and non-indexable connectors)
|
||||
if (
|
||||
|
|
@ -1114,7 +1110,7 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: editingConnector.id,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
},
|
||||
body: {
|
||||
folders: selectedFolders || [],
|
||||
|
|
@ -1134,7 +1130,7 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: editingConnector.id,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
},
|
||||
});
|
||||
indexingDescription = "Re-indexing started with updated configuration.";
|
||||
|
|
@ -1143,7 +1139,7 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: editingConnector.id,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
start_date: startDateStr,
|
||||
end_date: endDateStr,
|
||||
},
|
||||
|
|
@ -1157,7 +1153,7 @@ export const useConnectorDialog = () => {
|
|||
(indexingDescription.includes("Re-indexing") || indexingDescription.includes("indexing"))
|
||||
) {
|
||||
trackIndexWithDateRangeStarted(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
editingConnector.connector_type,
|
||||
editingConnector.id,
|
||||
{
|
||||
|
|
@ -1170,7 +1166,7 @@ export const useConnectorDialog = () => {
|
|||
// Track periodic indexing if enabled
|
||||
if (periodicEnabled && editingConnector.is_indexable) {
|
||||
trackPeriodicIndexingStarted(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
editingConnector.connector_type,
|
||||
editingConnector.id,
|
||||
frequency || parseInt(frequencyMinutes, 10)
|
||||
|
|
@ -1190,7 +1186,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
refreshConnectors();
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
queryKey: cacheKeys.logs.summary(Number(workspaceId)),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error saving connector:", error);
|
||||
|
|
@ -1201,7 +1197,7 @@ export const useConnectorDialog = () => {
|
|||
},
|
||||
[
|
||||
editingConnector,
|
||||
searchSpaceId,
|
||||
workspaceId,
|
||||
isSaving,
|
||||
startDate,
|
||||
endDate,
|
||||
|
|
@ -1220,7 +1216,7 @@ export const useConnectorDialog = () => {
|
|||
// Handle disconnecting connector
|
||||
const handleDisconnectConnector = useCallback(
|
||||
async (refreshConnectors: () => void) => {
|
||||
if (!editingConnector || !searchSpaceId) return;
|
||||
if (!editingConnector || !workspaceId) return;
|
||||
|
||||
setIsDisconnecting(true);
|
||||
try {
|
||||
|
|
@ -1230,7 +1226,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Track connector deleted event
|
||||
trackConnectorDeleted(
|
||||
Number(searchSpaceId),
|
||||
Number(workspaceId),
|
||||
editingConnector.connector_type,
|
||||
editingConnector.id
|
||||
);
|
||||
|
|
@ -1255,7 +1251,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
refreshConnectors();
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
queryKey: cacheKeys.logs.summary(Number(workspaceId)),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error disconnecting connector:", error);
|
||||
|
|
@ -1264,7 +1260,7 @@ export const useConnectorDialog = () => {
|
|||
setIsDisconnecting(false);
|
||||
}
|
||||
},
|
||||
[editingConnector, searchSpaceId, deleteConnector, cameFromMCPList, setIsOpen]
|
||||
[editingConnector, workspaceId, deleteConnector, cameFromMCPList, setIsOpen]
|
||||
);
|
||||
|
||||
// Handle quick index (index with selected date range, or backend defaults if none selected)
|
||||
|
|
@ -1276,7 +1272,7 @@ export const useConnectorDialog = () => {
|
|||
startDate?: Date,
|
||||
endDate?: Date
|
||||
) => {
|
||||
if (!searchSpaceId) {
|
||||
if (!workspaceId) {
|
||||
if (stopIndexing) {
|
||||
stopIndexing(connectorId);
|
||||
}
|
||||
|
|
@ -1285,7 +1281,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Track quick index clicked event
|
||||
if (connectorType) {
|
||||
trackQuickIndexClicked(Number(searchSpaceId), connectorType, connectorId);
|
||||
trackQuickIndexClicked(Number(workspaceId), connectorType, connectorId);
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -1296,7 +1292,7 @@ export const useConnectorDialog = () => {
|
|||
await indexConnector({
|
||||
connector_id: connectorId,
|
||||
queryParams: {
|
||||
workspace_id: searchSpaceId,
|
||||
workspace_id: workspaceId,
|
||||
start_date: startDateStr,
|
||||
end_date: endDateStr,
|
||||
},
|
||||
|
|
@ -1305,7 +1301,7 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Invalidate queries to refresh data
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: cacheKeys.logs.summary(Number(searchSpaceId)),
|
||||
queryKey: cacheKeys.logs.summary(Number(workspaceId)),
|
||||
});
|
||||
// Note: Don't call stopIndexing here - let useIndexingConnectors hook
|
||||
// detect when last_indexed_at changes via real-time sync
|
||||
|
|
@ -1318,7 +1314,7 @@ export const useConnectorDialog = () => {
|
|||
}
|
||||
}
|
||||
},
|
||||
[searchSpaceId, indexConnector]
|
||||
[workspaceId, indexConnector]
|
||||
);
|
||||
|
||||
// Handle going back from edit view
|
||||
|
|
@ -1406,7 +1402,7 @@ export const useConnectorDialog = () => {
|
|||
periodicEnabled,
|
||||
frequencyMinutes,
|
||||
enableVisionLlm,
|
||||
searchSpaceId,
|
||||
workspaceId,
|
||||
allConnectors,
|
||||
viewingAccountsType,
|
||||
viewingMCPList,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export function getConnectorDisplayName(fullName: string): string {
|
|||
|
||||
interface AllConnectorsTabProps {
|
||||
searchQuery: string;
|
||||
searchSpaceId: string;
|
||||
workspaceId: string;
|
||||
connectedTypes: Set<string>;
|
||||
connectingId: string | null;
|
||||
allConnectors: SearchSourceConnector[] | undefined;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export const ConnectorAccountsListView: FC<ConnectorAccountsListViewProps> = ({
|
|||
isConnecting = false,
|
||||
addButtonText,
|
||||
}) => {
|
||||
const searchSpaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const workspaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const [reauthingId, setReauthingId] = useState<number | null>(null);
|
||||
const [confirmDisconnectId, setConfirmDisconnectId] = useState<number | null>(null);
|
||||
const [disconnectingId, setDisconnectingId] = useState<number | null>(null);
|
||||
|
|
@ -58,13 +58,13 @@ export const ConnectorAccountsListView: FC<ConnectorAccountsListViewProps> = ({
|
|||
const handleReauth = useCallback(
|
||||
async (connector: SearchSourceConnector) => {
|
||||
const endpoint = getReauthEndpoint(connector);
|
||||
if (!searchSpaceId || !endpoint) return;
|
||||
if (!workspaceId || !endpoint) return;
|
||||
setReauthingId(connector.id);
|
||||
try {
|
||||
const response = await authenticatedFetch(
|
||||
buildBackendUrl(endpoint, {
|
||||
connector_id: connector.id,
|
||||
space_id: searchSpaceId,
|
||||
space_id: workspaceId,
|
||||
return_url: window.location.pathname,
|
||||
})
|
||||
);
|
||||
|
|
@ -86,7 +86,7 @@ export const ConnectorAccountsListView: FC<ConnectorAccountsListViewProps> = ({
|
|||
setReauthingId(null);
|
||||
}
|
||||
},
|
||||
[searchSpaceId]
|
||||
[workspaceId]
|
||||
);
|
||||
|
||||
// Filter connectors to only show those of this type
|
||||
|
|
|
|||
|
|
@ -38,11 +38,11 @@ function extractYoutubeUrls(text: string): string[] {
|
|||
}
|
||||
|
||||
interface YouTubeCrawlerViewProps {
|
||||
searchSpaceId: string;
|
||||
workspaceId: string;
|
||||
onBack: () => void;
|
||||
}
|
||||
|
||||
export const YouTubeCrawlerView: FC<YouTubeCrawlerViewProps> = ({ searchSpaceId, onBack }) => {
|
||||
export const YouTubeCrawlerView: FC<YouTubeCrawlerViewProps> = ({ workspaceId, onBack }) => {
|
||||
const t = useTranslations("add_youtube");
|
||||
const [videoTags, setVideoTags] = useState<TagType[]>([]);
|
||||
const [activeTagIndex, setActiveTagIndex] = useState<number | null>(null);
|
||||
|
|
@ -165,7 +165,7 @@ export const YouTubeCrawlerView: FC<YouTubeCrawlerViewProps> = ({ searchSpaceId,
|
|||
{
|
||||
document_type: "YOUTUBE_VIDEO",
|
||||
content: videoUrls,
|
||||
workspace_id: parseInt(searchSpaceId, 10),
|
||||
workspace_id: parseInt(workspaceId, 10),
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@ const DocumentUploadPopupContent: FC<{
|
|||
isOpen: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
}> = ({ isOpen, onOpenChange }) => {
|
||||
const searchSpaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
const workspaceId = useAtomValue(activeWorkspaceIdAtom);
|
||||
|
||||
if (!searchSpaceId) return null;
|
||||
if (!workspaceId) return null;
|
||||
|
||||
const handleSuccess = () => {
|
||||
onOpenChange(false);
|
||||
|
|
@ -112,12 +112,12 @@ const DocumentUploadPopupContent: FC<{
|
|||
Upload Documents
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-xs sm:text-base text-muted-foreground/80 line-clamp-1">
|
||||
Upload and sync your documents to your search space
|
||||
Upload and sync your documents to your workspace
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="px-4 sm:px-6 pb-4 sm:pb-6">
|
||||
<DocumentUploadTab searchSpaceId={searchSpaceId} onSuccess={handleSuccess} />
|
||||
<DocumentUploadTab workspaceId={workspaceId} onSuccess={handleSuccess} />
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ function FilePathLink({ path, className }: { path: string; className?: string })
|
|||
const openEditorPanel = useSetAtom(openEditorPanelAtom);
|
||||
const params = useParams();
|
||||
const electronAPI = useElectronAPI();
|
||||
const resolvedSearchSpaceId = getWorkspaceIdNumber(params);
|
||||
const resolvedWorkspaceId = getWorkspaceIdNumber(params);
|
||||
|
||||
const { displayName, isFolder } = getVirtualPathDisplay(path);
|
||||
const icon = isFolder ? <FolderIcon className="size-3.5" /> : <FileIcon className="size-3.5" />;
|
||||
|
|
@ -204,7 +204,7 @@ function FilePathLink({ path, className }: { path: string; className?: string })
|
|||
if (electronAPI.getAgentFilesystemMounts) {
|
||||
try {
|
||||
const mounts = (await electronAPI.getAgentFilesystemMounts(
|
||||
resolvedSearchSpaceId
|
||||
resolvedWorkspaceId
|
||||
)) as AgentFilesystemMount[];
|
||||
resolvedLocalPath = normalizeLocalVirtualPathForEditor(path, mounts);
|
||||
} catch {
|
||||
|
|
@ -215,21 +215,21 @@ function FilePathLink({ path, className }: { path: string; className?: string })
|
|||
kind: "local_file",
|
||||
localFilePath: resolvedLocalPath,
|
||||
title: resolvedLocalPath.split("/").pop() || resolvedLocalPath,
|
||||
searchSpaceId: resolvedSearchSpaceId,
|
||||
workspaceId: resolvedWorkspaceId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resolvedSearchSpaceId || !path.startsWith("/documents/")) return;
|
||||
if (!resolvedWorkspaceId || !path.startsWith("/documents/")) return;
|
||||
try {
|
||||
const doc = await documentsApiService.getDocumentByVirtualPath({
|
||||
workspace_id: resolvedSearchSpaceId,
|
||||
workspace_id: resolvedWorkspaceId,
|
||||
virtual_path: path,
|
||||
});
|
||||
openEditorPanel({
|
||||
kind: "document",
|
||||
documentId: doc.id,
|
||||
searchSpaceId: resolvedSearchSpaceId,
|
||||
workspaceId: resolvedWorkspaceId,
|
||||
title: doc.title,
|
||||
});
|
||||
} catch {
|
||||
|
|
@ -237,7 +237,7 @@ function FilePathLink({ path, className }: { path: string; className?: string })
|
|||
}
|
||||
})();
|
||||
},
|
||||
[electronAPI, openEditorPanel, path, resolvedSearchSpaceId]
|
||||
[electronAPI, openEditorPanel, path, resolvedWorkspaceId]
|
||||
);
|
||||
|
||||
// Folders cannot open in the editor panel — keep them as visual chips.
|
||||
|
|
|
|||
|
|
@ -895,7 +895,7 @@ const Composer: FC = () => {
|
|||
<ComposerSuggestionPopoverContent side="top">
|
||||
<DocumentMentionPicker
|
||||
ref={documentPickerRef}
|
||||
searchSpaceId={workspaceId ?? 0}
|
||||
workspaceId={workspaceId ?? 0}
|
||||
enableChatMentions
|
||||
currentChatId={threadId}
|
||||
onSelectionChange={handleDocumentsMention}
|
||||
|
|
@ -961,7 +961,7 @@ const Composer: FC = () => {
|
|||
</div>
|
||||
<ComposerAction
|
||||
isBlockedByOtherUser={isBlockedByOtherUser}
|
||||
searchSpaceId={workspaceId ?? 0}
|
||||
workspaceId={workspaceId ?? 0}
|
||||
onChatModelSelected={handleChatModelSelected}
|
||||
/>
|
||||
<ConnectorIndicator showTrigger={false} />
|
||||
|
|
@ -982,13 +982,13 @@ const Composer: FC = () => {
|
|||
|
||||
interface ComposerActionProps {
|
||||
isBlockedByOtherUser?: boolean;
|
||||
searchSpaceId: number;
|
||||
workspaceId: number;
|
||||
onChatModelSelected?: () => void;
|
||||
}
|
||||
|
||||
const ComposerAction: FC<ComposerActionProps> = ({
|
||||
isBlockedByOtherUser = false,
|
||||
searchSpaceId,
|
||||
workspaceId,
|
||||
onChatModelSelected,
|
||||
}) => {
|
||||
const mentionedDocuments = useAtomValue(mentionedDocumentsAtom);
|
||||
|
|
@ -1564,7 +1564,7 @@ const ComposerAction: FC<ComposerActionProps> = ({
|
|||
)}
|
||||
<div className="ml-auto flex min-w-0 shrink-0 items-center gap-2">
|
||||
<ChatHeader
|
||||
searchSpaceId={searchSpaceId}
|
||||
workspaceId={workspaceId}
|
||||
className="h-9 max-w-[44vw] px-2 sm:max-w-[220px] sm:px-3"
|
||||
onChatModelSelected={onChatModelSelected}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -76,33 +76,33 @@ const UserTextPart: FC = () => {
|
|||
const openEditorPanel = useSetAtom(openEditorPanelAtom);
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const resolvedSearchSpaceId = getWorkspaceIdNumber(params);
|
||||
const resolvedWorkspaceId = getWorkspaceIdNumber(params);
|
||||
|
||||
const handleOpenDoc = useCallback(
|
||||
(docId: number, title: string) => {
|
||||
if (!resolvedSearchSpaceId) {
|
||||
toast.error("Cannot open document outside a search space.");
|
||||
if (!resolvedWorkspaceId) {
|
||||
toast.error("Cannot open document outside a workspace.");
|
||||
return;
|
||||
}
|
||||
openEditorPanel({
|
||||
kind: "document",
|
||||
documentId: docId,
|
||||
searchSpaceId: resolvedSearchSpaceId,
|
||||
workspaceId: resolvedWorkspaceId,
|
||||
title,
|
||||
});
|
||||
},
|
||||
[openEditorPanel, resolvedSearchSpaceId]
|
||||
[openEditorPanel, resolvedWorkspaceId]
|
||||
);
|
||||
|
||||
const handleOpenThread = useCallback(
|
||||
(threadId: number) => {
|
||||
if (!resolvedSearchSpaceId) {
|
||||
toast.error("Cannot open chat outside a search space.");
|
||||
if (!resolvedWorkspaceId) {
|
||||
toast.error("Cannot open chat outside a workspace.");
|
||||
return;
|
||||
}
|
||||
router.push(`/dashboard/${resolvedSearchSpaceId}/new-chat/${threadId}`);
|
||||
router.push(`/dashboard/${resolvedWorkspaceId}/new-chat/${threadId}`);
|
||||
},
|
||||
[resolvedSearchSpaceId, router]
|
||||
[resolvedWorkspaceId, router]
|
||||
);
|
||||
|
||||
const segments = parseMentionSegments(text, mentionedDocs);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue