mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-29 19:35:20 +02:00
Merge branch 'dev' into sur-73-impr-implement-new-main-app-ux
This commit is contained in:
commit
8255d158a8
47 changed files with 2632 additions and 33 deletions
|
|
@ -7,7 +7,7 @@ import { cn } from "@/lib/utils";
|
|||
export const Logo = ({ className }: { className?: string }) => {
|
||||
return (
|
||||
<Link href="/">
|
||||
<Image src="/icon-128.png" className={cn(className)} alt="logo" width={128} height={128} />
|
||||
<Image src="/icon-128.svg" className={cn("dark:invert", className)} alt="logo" width={128} height={128} />
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -248,7 +248,8 @@ export const ConnectorIndicator: FC = () => {
|
|||
onBack={handleBackFromEdit}
|
||||
onQuickIndex={
|
||||
editingConnector.connector_type !== "GOOGLE_DRIVE_CONNECTOR"
|
||||
? () => handleQuickIndexConnector(editingConnector.id)
|
||||
? () =>
|
||||
handleQuickIndexConnector(editingConnector.id, editingConnector.connector_type)
|
||||
: undefined
|
||||
}
|
||||
onConfigChange={setConnectorConfig}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
"use client";
|
||||
|
||||
import { Info } from "lucide-react";
|
||||
import type { FC } from "react";
|
||||
import type { ConnectorConfigProps } from "../index";
|
||||
|
||||
export interface TeamsConfigProps extends ConnectorConfigProps {
|
||||
onNameChange?: (name: string) => void;
|
||||
}
|
||||
|
||||
export const TeamsConfig: FC<TeamsConfigProps> = () => {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
|
||||
<Info className="size-4" />
|
||||
</div>
|
||||
<div className="text-xs sm:text-sm">
|
||||
<p className="font-medium text-xs sm:text-sm">Microsoft Teams Access</p>
|
||||
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
|
||||
SurfSense will index messages from Teams channels that you have access to. The app can
|
||||
only read messages from teams and channels where you are a member. Make sure you're a
|
||||
member of the teams you want to index before connecting.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -17,6 +17,7 @@ import { LumaConfig } from "./components/luma-config";
|
|||
import { SearxngConfig } from "./components/searxng-config";
|
||||
import { SlackConfig } from "./components/slack-config";
|
||||
import { TavilyApiConfig } from "./components/tavily-api-config";
|
||||
import { TeamsConfig } from "./components/teams-config";
|
||||
import { WebcrawlerConfig } from "./components/webcrawler-config";
|
||||
|
||||
export interface ConnectorConfigProps {
|
||||
|
|
@ -52,6 +53,8 @@ export function getConnectorConfigComponent(
|
|||
return SlackConfig;
|
||||
case "DISCORD_CONNECTOR":
|
||||
return DiscordConfig;
|
||||
case "TEAMS_CONNECTOR":
|
||||
return TeamsConfig;
|
||||
case "CONFLUENCE_CONNECTOR":
|
||||
return ConfluenceConfig;
|
||||
case "BOOKSTACK_CONNECTOR":
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ export const OAUTH_CONNECTORS = [
|
|||
connectorType: EnumConnectorName.SLACK_CONNECTOR,
|
||||
authEndpoint: "/api/v1/auth/slack/connector/add/",
|
||||
},
|
||||
{
|
||||
id: "teams-connector",
|
||||
title: "Microsoft Teams",
|
||||
description: "Search Teams messages",
|
||||
connectorType: EnumConnectorName.TEAMS_CONNECTOR,
|
||||
authEndpoint: "/api/v1/auth/teams/connector/add/",
|
||||
},
|
||||
{
|
||||
id: "discord-connector",
|
||||
title: "Discord",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,14 @@ import { EnumConnectorName } from "@/contracts/enums/connector";
|
|||
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
|
||||
import { searchSourceConnector } from "@/contracts/types/connector.types";
|
||||
import { authenticatedFetch } from "@/lib/auth-utils";
|
||||
import {
|
||||
trackConnectorConnected,
|
||||
trackConnectorDeleted,
|
||||
trackIndexWithDateRangeOpened,
|
||||
trackIndexWithDateRangeStarted,
|
||||
trackPeriodicIndexingStarted,
|
||||
trackQuickIndexClicked,
|
||||
} from "@/lib/posthog/events";
|
||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||
import { queryClient } from "@/lib/query-client/client";
|
||||
import type { IndexingConfigState } from "../constants/connector-constants";
|
||||
|
|
@ -309,6 +317,13 @@ export const useConnectorDialog = () => {
|
|||
if (newConnector) {
|
||||
const connectorValidation = searchSourceConnector.safeParse(newConnector);
|
||||
if (connectorValidation.success) {
|
||||
// Track connector connected event for OAuth connectors
|
||||
trackConnectorConnected(
|
||||
Number(searchSpaceId),
|
||||
oauthConnector.connectorType,
|
||||
newConnector.id
|
||||
);
|
||||
|
||||
const config = validateIndexingConfigState({
|
||||
connectorType: oauthConnector.connectorType,
|
||||
connectorId: newConnector.id,
|
||||
|
|
@ -419,6 +434,13 @@ export const useConnectorDialog = () => {
|
|||
if (connector) {
|
||||
const connectorValidation = searchSourceConnector.safeParse(connector);
|
||||
if (connectorValidation.success) {
|
||||
// Track webcrawler connector connected
|
||||
trackConnectorConnected(
|
||||
Number(searchSpaceId),
|
||||
EnumConnectorName.WEBCRAWLER_CONNECTOR,
|
||||
connector.id
|
||||
);
|
||||
|
||||
const config = validateIndexingConfigState({
|
||||
connectorType: EnumConnectorName.WEBCRAWLER_CONNECTOR,
|
||||
connectorId: connector.id,
|
||||
|
|
@ -514,6 +536,9 @@ export const useConnectorDialog = () => {
|
|||
// Store connectingConnectorType before clearing it
|
||||
const currentConnectorType = connectingConnectorType;
|
||||
|
||||
// Track connector connected event for non-OAuth connectors
|
||||
trackConnectorConnected(Number(searchSpaceId), currentConnectorType, connector.id);
|
||||
|
||||
// Find connector title from constants
|
||||
const connectorInfo = OTHER_CONNECTORS.find(
|
||||
(c) => c.connectorType === currentConnectorType
|
||||
|
|
@ -848,6 +873,27 @@ export const useConnectorDialog = () => {
|
|||
});
|
||||
}
|
||||
|
||||
// Track index with date range started event
|
||||
trackIndexWithDateRangeStarted(
|
||||
Number(searchSpaceId),
|
||||
indexingConfig.connectorType,
|
||||
indexingConfig.connectorId,
|
||||
{
|
||||
hasStartDate: !!startDate,
|
||||
hasEndDate: !!endDate,
|
||||
}
|
||||
);
|
||||
|
||||
// Track periodic indexing started if enabled
|
||||
if (periodicEnabled && indexingConfig.connectorType !== "GOOGLE_DRIVE_CONNECTOR") {
|
||||
trackPeriodicIndexingStarted(
|
||||
Number(searchSpaceId),
|
||||
indexingConfig.connectorType,
|
||||
indexingConfig.connectorId,
|
||||
parseInt(frequencyMinutes, 10)
|
||||
);
|
||||
}
|
||||
|
||||
toast.success(`${indexingConfig.connectorTitle} indexing started`, {
|
||||
description: periodicEnabled
|
||||
? `Periodic sync enabled every ${getFrequencyLabel(frequencyMinutes)}.`
|
||||
|
|
@ -914,6 +960,15 @@ export const useConnectorDialog = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
// Track index with date range opened event
|
||||
if (connector.is_indexable) {
|
||||
trackIndexWithDateRangeOpened(
|
||||
Number(searchSpaceId),
|
||||
connector.connector_type,
|
||||
connector.id
|
||||
);
|
||||
}
|
||||
|
||||
setEditingConnector(connector);
|
||||
setConnectorName(connector.name);
|
||||
// Load existing periodic sync settings (disabled for Google Drive and non-indexable connectors)
|
||||
|
|
@ -1049,6 +1104,36 @@ export const useConnectorDialog = () => {
|
|||
indexingDescription = "Re-indexing started with new date range.";
|
||||
}
|
||||
|
||||
// Track indexing started if re-indexing was performed
|
||||
if (
|
||||
editingConnector.is_indexable &&
|
||||
(indexingDescription.includes("Re-indexing") || indexingDescription.includes("indexing"))
|
||||
) {
|
||||
trackIndexWithDateRangeStarted(
|
||||
Number(searchSpaceId),
|
||||
editingConnector.connector_type,
|
||||
editingConnector.id,
|
||||
{
|
||||
hasStartDate: !!startDateStr,
|
||||
hasEndDate: !!endDateStr,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Track periodic indexing if enabled (for non-Google Drive connectors)
|
||||
if (
|
||||
periodicEnabled &&
|
||||
editingConnector.is_indexable &&
|
||||
editingConnector.connector_type !== "GOOGLE_DRIVE_CONNECTOR"
|
||||
) {
|
||||
trackPeriodicIndexingStarted(
|
||||
Number(searchSpaceId),
|
||||
editingConnector.connector_type,
|
||||
editingConnector.id,
|
||||
frequency || parseInt(frequencyMinutes, 10)
|
||||
);
|
||||
}
|
||||
|
||||
toast.success(`${editingConnector.name} updated successfully`, {
|
||||
description: periodicEnabled
|
||||
? `Periodic sync ${frequency ? `enabled every ${getFrequencyLabel(frequencyMinutes)}` : "enabled"}. ${indexingDescription}`
|
||||
|
|
@ -1101,6 +1186,13 @@ export const useConnectorDialog = () => {
|
|||
id: editingConnector.id,
|
||||
});
|
||||
|
||||
// Track connector deleted event
|
||||
trackConnectorDeleted(
|
||||
Number(searchSpaceId),
|
||||
editingConnector.connector_type,
|
||||
editingConnector.id
|
||||
);
|
||||
|
||||
toast.success(`${editingConnector.name} disconnected successfully`);
|
||||
|
||||
// Update URL - the effect will handle closing the modal and clearing state
|
||||
|
|
@ -1127,9 +1219,14 @@ export const useConnectorDialog = () => {
|
|||
|
||||
// Handle quick index (index without date picker, uses backend defaults)
|
||||
const handleQuickIndexConnector = useCallback(
|
||||
async (connectorId: number) => {
|
||||
async (connectorId: number, connectorType?: string) => {
|
||||
if (!searchSpaceId) return;
|
||||
|
||||
// Track quick index clicked event
|
||||
if (connectorType) {
|
||||
trackQuickIndexClicked(Number(searchSpaceId), connectorType, connectorId);
|
||||
}
|
||||
|
||||
try {
|
||||
await indexConnector({
|
||||
connector_id: connectorId,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
export const CONNECTOR_TO_DOCUMENT_TYPE: Record<string, string> = {
|
||||
// Direct mappings (connector type matches document type)
|
||||
SLACK_CONNECTOR: "SLACK_CONNECTOR",
|
||||
TEAMS_CONNECTOR: "TEAMS_CONNECTOR",
|
||||
NOTION_CONNECTOR: "NOTION_CONNECTOR",
|
||||
GITHUB_CONNECTOR: "GITHUB_CONNECTOR",
|
||||
LINEAR_CONNECTOR: "LINEAR_CONNECTOR",
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ const DesktopNav = ({ navItems, isScrolled }: any) => {
|
|||
: "bg-transparent border border-transparent"
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-1 flex-row items-center gap-2">
|
||||
<div className="flex flex-1 flex-row items-center gap-0.5">
|
||||
<Logo className="h-8 w-8 rounded-md" />
|
||||
<span className="dark:text-white/90 text-gray-800 text-lg font-bold">SurfSense</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue