mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-10 20:35:17 +02:00
chore: linting
This commit is contained in:
parent
89c96c1a23
commit
c6e1a04169
19 changed files with 327 additions and 196 deletions
|
|
@ -1,8 +1,7 @@
|
|||
"use client";
|
||||
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ import { useParams } from "next/navigation";
|
|||
import { useTranslations } from "next-intl";
|
||||
import React, { useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { useDebouncedValue } from "@/hooks/use-debounced-value";
|
||||
import {
|
||||
createLogMutationAtom,
|
||||
deleteLogMutationAtom,
|
||||
|
|
@ -96,6 +95,7 @@ import {
|
|||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import type { CreateLogRequest, Log, UpdateLogRequest } from "@/contracts/types/log.types";
|
||||
import { useDebouncedValue } from "@/hooks/use-debounced-value";
|
||||
import { type LogLevel, type LogStatus, useLogs, useLogsSummary } from "@/hooks/use-logs";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
@ -728,10 +728,7 @@ function LogsFilters({
|
|||
<motion.div className="relative w-full sm:w-auto" variants={fadeInScale}>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
className={cn(
|
||||
"peer w-full sm:min-w-60 ps-9",
|
||||
Boolean(filterInput) && "pe-9"
|
||||
)}
|
||||
className={cn("peer w-full sm:min-w-60 ps-9", Boolean(filterInput) && "pe-9")}
|
||||
value={filterInput}
|
||||
onChange={(e) => setFilterInput(e.target.value)}
|
||||
placeholder={t("filter_by_message")}
|
||||
|
|
|
|||
|
|
@ -40,18 +40,62 @@ import { ThinkingStepsDataUI } from "@/components/assistant-ui/thinking-steps";
|
|||
import { Thread } from "@/components/assistant-ui/thread";
|
||||
import { useChatSessionStateSync } from "@/hooks/use-chat-session-state";
|
||||
import { useMessagesSync } from "@/hooks/use-messages-sync";
|
||||
import { documentsApiService } from "@/lib/apis/documents-api.service";
|
||||
import { getBearerToken } from "@/lib/auth-utils";
|
||||
import { convertToThreadMessage } from "@/lib/chat/message-utils";
|
||||
import {
|
||||
isPodcastGenerating,
|
||||
looksLikePodcastRequest,
|
||||
setActivePodcastTaskId,
|
||||
} from "@/lib/chat/podcast-state";
|
||||
import {
|
||||
addToolCall,
|
||||
appendText,
|
||||
buildContentForPersistence,
|
||||
buildContentForUI,
|
||||
type ContentPartsState,
|
||||
FrameBatchedUpdater,
|
||||
readSSEStream,
|
||||
type ThinkingStepData,
|
||||
updateThinkingSteps,
|
||||
updateToolCall,
|
||||
} from "@/lib/chat/streaming-state";
|
||||
import {
|
||||
appendMessage,
|
||||
createThread,
|
||||
getRegenerateUrl,
|
||||
getThreadFull,
|
||||
getThreadMessages,
|
||||
type ThreadRecord,
|
||||
} from "@/lib/chat/thread-persistence";
|
||||
import { NotFoundError } from "@/lib/error";
|
||||
import {
|
||||
trackChatCreated,
|
||||
trackChatError,
|
||||
trackChatMessageSent,
|
||||
trackChatResponseReceived,
|
||||
} from "@/lib/posthog/events";
|
||||
import Loading from "../loading";
|
||||
|
||||
const MobileEditorPanel = dynamic(
|
||||
() => import("@/components/editor-panel/editor-panel").then((m) => ({ default: m.MobileEditorPanel })),
|
||||
() =>
|
||||
import("@/components/editor-panel/editor-panel").then((m) => ({
|
||||
default: m.MobileEditorPanel,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const MobileHitlEditPanel = dynamic(
|
||||
() => import("@/components/hitl-edit-panel/hitl-edit-panel").then((m) => ({ default: m.MobileHitlEditPanel })),
|
||||
() =>
|
||||
import("@/components/hitl-edit-panel/hitl-edit-panel").then((m) => ({
|
||||
default: m.MobileHitlEditPanel,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const MobileReportPanel = dynamic(
|
||||
() => import("@/components/report-panel/report-panel").then((m) => ({ default: m.MobileReportPanel })),
|
||||
() =>
|
||||
import("@/components/report-panel/report-panel").then((m) => ({
|
||||
default: m.MobileReportPanel,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -346,15 +346,11 @@ export default function SuggestionPage() {
|
|||
needsTruncation && !isExpanded ? option.slice(0, TRUNCATE_LENGTH) + "…" : option;
|
||||
|
||||
return (
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
key={index}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="suggestion-option"
|
||||
onClick={() => handleSelect(option)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") handleSelect(option);
|
||||
}}
|
||||
>
|
||||
<span className="option-number">{index + 1}</span>
|
||||
<span className="option-text">{displayText}</span>
|
||||
|
|
@ -370,7 +366,7 @@ export default function SuggestionPage() {
|
|||
{isExpanded ? "less" : "more"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -51,131 +51,172 @@ const IS_QUICK_ASSIST_WINDOW =
|
|||
|
||||
// Dynamically import tool UI components to avoid loading them in main bundle
|
||||
const GenerateReportToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/generate-report").then(m => ({ default: m.GenerateReportToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/generate-report").then((m) => ({
|
||||
default: m.GenerateReportToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const GeneratePodcastToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/generate-podcast").then(m => ({ default: m.GeneratePodcastToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/generate-podcast").then((m) => ({
|
||||
default: m.GeneratePodcastToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const GenerateVideoPresentationToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/video-presentation").then(m => ({ default: m.GenerateVideoPresentationToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/video-presentation").then((m) => ({
|
||||
default: m.GenerateVideoPresentationToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const GenerateImageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/generate-image").then(m => ({ default: m.GenerateImageToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/generate-image").then((m) => ({ default: m.GenerateImageToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const SaveMemoryToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/user-memory").then(m => ({ default: m.SaveMemoryToolUI })),
|
||||
() => import("@/components/tool-ui/user-memory").then((m) => ({ default: m.SaveMemoryToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const RecallMemoryToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/user-memory").then(m => ({ default: m.RecallMemoryToolUI })),
|
||||
() => import("@/components/tool-ui/user-memory").then((m) => ({ default: m.RecallMemoryToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const SandboxExecuteToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/sandbox-execute").then(m => ({ default: m.SandboxExecuteToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/sandbox-execute").then((m) => ({
|
||||
default: m.SandboxExecuteToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateNotionPageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/notion").then(m => ({ default: m.CreateNotionPageToolUI })),
|
||||
() => import("@/components/tool-ui/notion").then((m) => ({ default: m.CreateNotionPageToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const UpdateNotionPageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/notion").then(m => ({ default: m.UpdateNotionPageToolUI })),
|
||||
() => import("@/components/tool-ui/notion").then((m) => ({ default: m.UpdateNotionPageToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteNotionPageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/notion").then(m => ({ default: m.DeleteNotionPageToolUI })),
|
||||
() => import("@/components/tool-ui/notion").then((m) => ({ default: m.DeleteNotionPageToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateLinearIssueToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/linear").then(m => ({ default: m.CreateLinearIssueToolUI })),
|
||||
() => import("@/components/tool-ui/linear").then((m) => ({ default: m.CreateLinearIssueToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const UpdateLinearIssueToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/linear").then(m => ({ default: m.UpdateLinearIssueToolUI })),
|
||||
() => import("@/components/tool-ui/linear").then((m) => ({ default: m.UpdateLinearIssueToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteLinearIssueToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/linear").then(m => ({ default: m.DeleteLinearIssueToolUI })),
|
||||
() => import("@/components/tool-ui/linear").then((m) => ({ default: m.DeleteLinearIssueToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateGoogleDriveFileToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/google-drive").then(m => ({ default: m.CreateGoogleDriveFileToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/google-drive").then((m) => ({
|
||||
default: m.CreateGoogleDriveFileToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteGoogleDriveFileToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/google-drive").then(m => ({ default: m.DeleteGoogleDriveFileToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/google-drive").then((m) => ({
|
||||
default: m.DeleteGoogleDriveFileToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateOneDriveFileToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/onedrive").then(m => ({ default: m.CreateOneDriveFileToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/onedrive").then((m) => ({ default: m.CreateOneDriveFileToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteOneDriveFileToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/onedrive").then(m => ({ default: m.DeleteOneDriveFileToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/onedrive").then((m) => ({ default: m.DeleteOneDriveFileToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateDropboxFileToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/dropbox").then(m => ({ default: m.CreateDropboxFileToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/dropbox").then((m) => ({ default: m.CreateDropboxFileToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteDropboxFileToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/dropbox").then(m => ({ default: m.DeleteDropboxFileToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/dropbox").then((m) => ({ default: m.DeleteDropboxFileToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateCalendarEventToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/google-calendar").then(m => ({ default: m.CreateCalendarEventToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/google-calendar").then((m) => ({
|
||||
default: m.CreateCalendarEventToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const UpdateCalendarEventToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/google-calendar").then(m => ({ default: m.UpdateCalendarEventToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/google-calendar").then((m) => ({
|
||||
default: m.UpdateCalendarEventToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteCalendarEventToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/google-calendar").then(m => ({ default: m.DeleteCalendarEventToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/google-calendar").then((m) => ({
|
||||
default: m.DeleteCalendarEventToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateGmailDraftToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/gmail").then(m => ({ default: m.CreateGmailDraftToolUI })),
|
||||
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.CreateGmailDraftToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const UpdateGmailDraftToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/gmail").then(m => ({ default: m.UpdateGmailDraftToolUI })),
|
||||
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.UpdateGmailDraftToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const SendGmailEmailToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/gmail").then(m => ({ default: m.SendGmailEmailToolUI })),
|
||||
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.SendGmailEmailToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const TrashGmailEmailToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/gmail").then(m => ({ default: m.TrashGmailEmailToolUI })),
|
||||
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.TrashGmailEmailToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateJiraIssueToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/jira").then(m => ({ default: m.CreateJiraIssueToolUI })),
|
||||
() => import("@/components/tool-ui/jira").then((m) => ({ default: m.CreateJiraIssueToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const UpdateJiraIssueToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/jira").then(m => ({ default: m.UpdateJiraIssueToolUI })),
|
||||
() => import("@/components/tool-ui/jira").then((m) => ({ default: m.UpdateJiraIssueToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteJiraIssueToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/jira").then(m => ({ default: m.DeleteJiraIssueToolUI })),
|
||||
() => import("@/components/tool-ui/jira").then((m) => ({ default: m.DeleteJiraIssueToolUI })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CreateConfluencePageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/confluence").then(m => ({ default: m.CreateConfluencePageToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/confluence").then((m) => ({
|
||||
default: m.CreateConfluencePageToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const UpdateConfluencePageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/confluence").then(m => ({ default: m.UpdateConfluencePageToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/confluence").then((m) => ({
|
||||
default: m.UpdateConfluencePageToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DeleteConfluencePageToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/confluence").then(m => ({ default: m.DeleteConfluencePageToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/confluence").then((m) => ({
|
||||
default: m.DeleteConfluencePageToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,16 +25,38 @@ export interface ConnectFormProps {
|
|||
export type ConnectFormComponent = FC<ConnectFormProps>;
|
||||
|
||||
const formMap: Record<string, () => Promise<{ default: FC<ConnectFormProps> }>> = {
|
||||
TAVILY_API: () => import("./components/tavily-api-connect-form").then(m => ({ default: m.TavilyApiConnectForm })),
|
||||
LINKUP_API: () => import("./components/linkup-api-connect-form").then(m => ({ default: m.LinkupApiConnectForm })),
|
||||
BAIDU_SEARCH_API: () => import("./components/baidu-search-api-connect-form").then(m => ({ default: m.BaiduSearchApiConnectForm })),
|
||||
ELASTICSEARCH_CONNECTOR: () => import("./components/elasticsearch-connect-form").then(m => ({ default: m.ElasticsearchConnectForm })),
|
||||
BOOKSTACK_CONNECTOR: () => import("./components/bookstack-connect-form").then(m => ({ default: m.BookStackConnectForm })),
|
||||
GITHUB_CONNECTOR: () => import("./components/github-connect-form").then(m => ({ default: m.GithubConnectForm })),
|
||||
LUMA_CONNECTOR: () => import("./components/luma-connect-form").then(m => ({ default: m.LumaConnectForm })),
|
||||
CIRCLEBACK_CONNECTOR: () => import("./components/circleback-connect-form").then(m => ({ default: m.CirclebackConnectForm })),
|
||||
MCP_CONNECTOR: () => import("./components/mcp-connect-form").then(m => ({ default: m.MCPConnectForm })),
|
||||
OBSIDIAN_CONNECTOR: () => import("./components/obsidian-connect-form").then(m => ({ default: m.ObsidianConnectForm })),
|
||||
TAVILY_API: () =>
|
||||
import("./components/tavily-api-connect-form").then((m) => ({
|
||||
default: m.TavilyApiConnectForm,
|
||||
})),
|
||||
LINKUP_API: () =>
|
||||
import("./components/linkup-api-connect-form").then((m) => ({
|
||||
default: m.LinkupApiConnectForm,
|
||||
})),
|
||||
BAIDU_SEARCH_API: () =>
|
||||
import("./components/baidu-search-api-connect-form").then((m) => ({
|
||||
default: m.BaiduSearchApiConnectForm,
|
||||
})),
|
||||
ELASTICSEARCH_CONNECTOR: () =>
|
||||
import("./components/elasticsearch-connect-form").then((m) => ({
|
||||
default: m.ElasticsearchConnectForm,
|
||||
})),
|
||||
BOOKSTACK_CONNECTOR: () =>
|
||||
import("./components/bookstack-connect-form").then((m) => ({
|
||||
default: m.BookStackConnectForm,
|
||||
})),
|
||||
GITHUB_CONNECTOR: () =>
|
||||
import("./components/github-connect-form").then((m) => ({ default: m.GithubConnectForm })),
|
||||
LUMA_CONNECTOR: () =>
|
||||
import("./components/luma-connect-form").then((m) => ({ default: m.LumaConnectForm })),
|
||||
CIRCLEBACK_CONNECTOR: () =>
|
||||
import("./components/circleback-connect-form").then((m) => ({
|
||||
default: m.CirclebackConnectForm,
|
||||
})),
|
||||
MCP_CONNECTOR: () =>
|
||||
import("./components/mcp-connect-form").then((m) => ({ default: m.MCPConnectForm })),
|
||||
OBSIDIAN_CONNECTOR: () =>
|
||||
import("./components/obsidian-connect-form").then((m) => ({ default: m.ObsidianConnectForm })),
|
||||
};
|
||||
|
||||
const componentCache = new Map<string, ConnectFormComponent>();
|
||||
|
|
|
|||
|
|
@ -14,29 +14,53 @@ export interface ConnectorConfigProps {
|
|||
export type ConnectorConfigComponent = FC<ConnectorConfigProps>;
|
||||
|
||||
const configMap: Record<string, () => Promise<{ default: FC<ConnectorConfigProps> }>> = {
|
||||
GOOGLE_DRIVE_CONNECTOR: () => import("./components/google-drive-config").then(m => ({ default: m.GoogleDriveConfig })),
|
||||
TAVILY_API: () => import("./components/tavily-api-config").then(m => ({ default: m.TavilyApiConfig })),
|
||||
LINKUP_API: () => import("./components/linkup-api-config").then(m => ({ default: m.LinkupApiConfig })),
|
||||
BAIDU_SEARCH_API: () => import("./components/baidu-search-api-config").then(m => ({ default: m.BaiduSearchApiConfig })),
|
||||
WEBCRAWLER_CONNECTOR: () => import("./components/webcrawler-config").then(m => ({ default: m.WebcrawlerConfig })),
|
||||
ELASTICSEARCH_CONNECTOR: () => import("./components/elasticsearch-config").then(m => ({ default: m.ElasticsearchConfig })),
|
||||
SLACK_CONNECTOR: () => import("./components/slack-config").then(m => ({ default: m.SlackConfig })),
|
||||
DISCORD_CONNECTOR: () => import("./components/discord-config").then(m => ({ default: m.DiscordConfig })),
|
||||
TEAMS_CONNECTOR: () => import("./components/teams-config").then(m => ({ default: m.TeamsConfig })),
|
||||
DROPBOX_CONNECTOR: () => import("./components/dropbox-config").then(m => ({ default: m.DropboxConfig })),
|
||||
ONEDRIVE_CONNECTOR: () => import("./components/onedrive-config").then(m => ({ default: m.OneDriveConfig })),
|
||||
CONFLUENCE_CONNECTOR: () => import("./components/confluence-config").then(m => ({ default: m.ConfluenceConfig })),
|
||||
BOOKSTACK_CONNECTOR: () => import("./components/bookstack-config").then(m => ({ default: m.BookStackConfig })),
|
||||
GITHUB_CONNECTOR: () => import("./components/github-config").then(m => ({ default: m.GithubConfig })),
|
||||
JIRA_CONNECTOR: () => import("./components/jira-config").then(m => ({ default: m.JiraConfig })),
|
||||
CLICKUP_CONNECTOR: () => import("./components/clickup-config").then(m => ({ default: m.ClickUpConfig })),
|
||||
LUMA_CONNECTOR: () => import("./components/luma-config").then(m => ({ default: m.LumaConfig })),
|
||||
CIRCLEBACK_CONNECTOR: () => import("./components/circleback-config").then(m => ({ default: m.CirclebackConfig })),
|
||||
MCP_CONNECTOR: () => import("./components/mcp-config").then(m => ({ default: m.MCPConfig })),
|
||||
OBSIDIAN_CONNECTOR: () => import("./components/obsidian-config").then(m => ({ default: m.ObsidianConfig })),
|
||||
COMPOSIO_GOOGLE_DRIVE_CONNECTOR: () => import("./components/composio-drive-config").then(m => ({ default: m.ComposioDriveConfig })),
|
||||
COMPOSIO_GMAIL_CONNECTOR: () => import("./components/composio-gmail-config").then(m => ({ default: m.ComposioGmailConfig })),
|
||||
COMPOSIO_GOOGLE_CALENDAR_CONNECTOR: () => import("./components/composio-calendar-config").then(m => ({ default: m.ComposioCalendarConfig })),
|
||||
GOOGLE_DRIVE_CONNECTOR: () =>
|
||||
import("./components/google-drive-config").then((m) => ({ default: m.GoogleDriveConfig })),
|
||||
TAVILY_API: () =>
|
||||
import("./components/tavily-api-config").then((m) => ({ default: m.TavilyApiConfig })),
|
||||
LINKUP_API: () =>
|
||||
import("./components/linkup-api-config").then((m) => ({ default: m.LinkupApiConfig })),
|
||||
BAIDU_SEARCH_API: () =>
|
||||
import("./components/baidu-search-api-config").then((m) => ({
|
||||
default: m.BaiduSearchApiConfig,
|
||||
})),
|
||||
WEBCRAWLER_CONNECTOR: () =>
|
||||
import("./components/webcrawler-config").then((m) => ({ default: m.WebcrawlerConfig })),
|
||||
ELASTICSEARCH_CONNECTOR: () =>
|
||||
import("./components/elasticsearch-config").then((m) => ({ default: m.ElasticsearchConfig })),
|
||||
SLACK_CONNECTOR: () =>
|
||||
import("./components/slack-config").then((m) => ({ default: m.SlackConfig })),
|
||||
DISCORD_CONNECTOR: () =>
|
||||
import("./components/discord-config").then((m) => ({ default: m.DiscordConfig })),
|
||||
TEAMS_CONNECTOR: () =>
|
||||
import("./components/teams-config").then((m) => ({ default: m.TeamsConfig })),
|
||||
DROPBOX_CONNECTOR: () =>
|
||||
import("./components/dropbox-config").then((m) => ({ default: m.DropboxConfig })),
|
||||
ONEDRIVE_CONNECTOR: () =>
|
||||
import("./components/onedrive-config").then((m) => ({ default: m.OneDriveConfig })),
|
||||
CONFLUENCE_CONNECTOR: () =>
|
||||
import("./components/confluence-config").then((m) => ({ default: m.ConfluenceConfig })),
|
||||
BOOKSTACK_CONNECTOR: () =>
|
||||
import("./components/bookstack-config").then((m) => ({ default: m.BookStackConfig })),
|
||||
GITHUB_CONNECTOR: () =>
|
||||
import("./components/github-config").then((m) => ({ default: m.GithubConfig })),
|
||||
JIRA_CONNECTOR: () => import("./components/jira-config").then((m) => ({ default: m.JiraConfig })),
|
||||
CLICKUP_CONNECTOR: () =>
|
||||
import("./components/clickup-config").then((m) => ({ default: m.ClickUpConfig })),
|
||||
LUMA_CONNECTOR: () => import("./components/luma-config").then((m) => ({ default: m.LumaConfig })),
|
||||
CIRCLEBACK_CONNECTOR: () =>
|
||||
import("./components/circleback-config").then((m) => ({ default: m.CirclebackConfig })),
|
||||
MCP_CONNECTOR: () => import("./components/mcp-config").then((m) => ({ default: m.MCPConfig })),
|
||||
OBSIDIAN_CONNECTOR: () =>
|
||||
import("./components/obsidian-config").then((m) => ({ default: m.ObsidianConfig })),
|
||||
COMPOSIO_GOOGLE_DRIVE_CONNECTOR: () =>
|
||||
import("./components/composio-drive-config").then((m) => ({ default: m.ComposioDriveConfig })),
|
||||
COMPOSIO_GMAIL_CONNECTOR: () =>
|
||||
import("./components/composio-gmail-config").then((m) => ({ default: m.ComposioGmailConfig })),
|
||||
COMPOSIO_GOOGLE_CALENDAR_CONNECTOR: () =>
|
||||
import("./components/composio-calendar-config").then((m) => ({
|
||||
default: m.ComposioCalendarConfig,
|
||||
})),
|
||||
};
|
||||
|
||||
const componentCache = new Map<string, ConnectorConfigComponent>();
|
||||
|
|
|
|||
|
|
@ -59,13 +59,15 @@ const TAB_ITEMS = [
|
|||
},
|
||||
{
|
||||
title: "Extreme Assist",
|
||||
description: "Get inline writing suggestions powered by your knowledge base as you type in any app.",
|
||||
description:
|
||||
"Get inline writing suggestions powered by your knowledge base as you type in any app.",
|
||||
src: "/homepage/hero_tutorial/extreme_assist.mp4",
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
title: "Watch Local Folder",
|
||||
description: "Watch a local folder and automatically sync file changes to your knowledge base. Works great with Obsidian vaults.",
|
||||
description:
|
||||
"Watch a local folder and automatically sync file changes to your knowledge base. Works great with Obsidian vaults.",
|
||||
src: "/homepage/hero_tutorial/folder_watch.mp4",
|
||||
featured: true,
|
||||
},
|
||||
|
|
@ -84,7 +86,8 @@ const TAB_ITEMS = [
|
|||
// },
|
||||
{
|
||||
title: "Video & Presentations",
|
||||
description: "Create short videos and editable presentations with AI-generated visuals and narration from your sources.",
|
||||
description:
|
||||
"Create short videos and editable presentations with AI-generated visuals and narration from your sources.",
|
||||
src: "/homepage/hero_tutorial/video_gen_surf.mp4",
|
||||
featured: false,
|
||||
},
|
||||
|
|
@ -343,7 +346,12 @@ function DownloadButton() {
|
|||
</DropdownMenuItem>
|
||||
))}
|
||||
<DropdownMenuItem asChild>
|
||||
<a href={fallbackUrl} target="_blank" rel="noopener noreferrer" className="cursor-pointer">
|
||||
<a
|
||||
href={fallbackUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="cursor-pointer"
|
||||
>
|
||||
All downloads
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
|
|
@ -498,4 +506,3 @@ const TabVideo = memo(function TabVideo({ src }: { src: string }) {
|
|||
});
|
||||
|
||||
const GITHUB_RELEASES_URL = "https://github.com/MODSetter/SurfSense/releases/latest";
|
||||
|
||||
|
|
|
|||
|
|
@ -144,15 +144,8 @@ const MobileNav = ({ navItems, isScrolled, scrolledBgClassName }: any) => {
|
|||
ref={navRef}
|
||||
animate={{ borderRadius: open ? "4px" : "2rem" }}
|
||||
key={String(open)}
|
||||
className={cn(
|
||||
"relative mx-auto flex w-full max-w-[calc(100vw-2rem)] flex-col items-center justify-between px-4 py-2 lg:hidden transition-[background-color,border-color,box-shadow] duration-300",
|
||||
isScrolled
|
||||
? (scrolledBgClassName ??
|
||||
"bg-white/80 backdrop-blur-md border border-white/20 shadow-lg dark:bg-neutral-950/80 dark:border-neutral-800/50")
|
||||
: "bg-transparent border border-transparent"
|
||||
)}
|
||||
className={cn(
|
||||
"relative mx-auto flex w-full max-w-[calc(100vw-2rem)] flex-col items-center justify-between px-4 py-2 lg:hidden transition-all duration-300",
|
||||
"relative mx-auto flex w-full max-w-[calc(100vw-2rem)] flex-col items-center justify-between px-4 py-2 lg:hidden transition-[background-color,border-color,box-shadow] duration-300",
|
||||
isScrolled
|
||||
? (scrolledBgClassName ??
|
||||
"bg-white/80 backdrop-blur-md border border-white/20 shadow-lg dark:bg-neutral-950/80 dark:border-neutral-800/50")
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
"use client";
|
||||
|
||||
import { useRef, useState } from "react";
|
||||
import { motion, useInView } from "motion/react";
|
||||
import { IconPointerFilled } from "@tabler/icons-react";
|
||||
import { Check, X } from "lucide-react";
|
||||
import { motion, useInView } from "motion/react";
|
||||
import { useRef, useState } from "react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
@ -40,8 +40,8 @@ export function WhySurfSense() {
|
|||
Everything NotebookLM should have been
|
||||
</h2>
|
||||
<p className="mx-auto mt-4 max-w-2xl text-base text-muted-foreground">
|
||||
Open source. No data limits. No vendor lock-in. Built for teams that
|
||||
care about privacy and flexibility.
|
||||
Open source. No data limits. No vendor lock-in. Built for teams that care about privacy
|
||||
and flexibility.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -68,10 +68,7 @@ function UnlimitedSkeleton({ className }: { className?: string }) {
|
|||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex h-full flex-col justify-center gap-2.5", className)}
|
||||
>
|
||||
<div ref={ref} className={cn("flex h-full flex-col justify-center gap-2.5", className)}>
|
||||
{items.map((item, index) => (
|
||||
<motion.div
|
||||
key={item.label}
|
||||
|
|
@ -81,9 +78,7 @@ function UnlimitedSkeleton({ className }: { className?: string }) {
|
|||
className="flex items-center gap-2 rounded-lg bg-background px-3 py-2 shadow-sm ring-1 ring-border"
|
||||
>
|
||||
<span className="text-sm">{item.icon}</span>
|
||||
<span className="min-w-[60px] text-xs font-medium text-foreground">
|
||||
{item.label}
|
||||
</span>
|
||||
<span className="min-w-[60px] text-xs font-medium text-foreground">{item.label}</span>
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
<span className="text-[10px] text-muted-foreground line-through">
|
||||
{item.notebookLm}
|
||||
|
|
@ -125,10 +120,7 @@ function LLMFlexibilitySkeleton({ className }: { className?: string }) {
|
|||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-full flex-col items-center justify-center gap-3",
|
||||
className,
|
||||
)}
|
||||
className={cn("flex h-full flex-col items-center justify-center gap-3", className)}
|
||||
>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 8 }}
|
||||
|
|
@ -146,19 +138,13 @@ function LLMFlexibilitySkeleton({ className }: { className?: string }) {
|
|||
transition={{ duration: 0.3, delay: 0.1 + index * 0.1 }}
|
||||
className={cn(
|
||||
"flex w-full cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-left transition-all",
|
||||
selected === index
|
||||
? "bg-background shadow-sm ring-1 ring-border"
|
||||
: "hover:bg-accent",
|
||||
selected === index ? "bg-background shadow-sm ring-1 ring-border" : "hover:bg-accent"
|
||||
)}
|
||||
>
|
||||
<div className={cn("size-2 shrink-0 rounded-full", model.color)} />
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-xs font-medium text-foreground">
|
||||
{model.name}
|
||||
</p>
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
{model.provider}
|
||||
</p>
|
||||
<p className="truncate text-xs font-medium text-foreground">{model.name}</p>
|
||||
<p className="text-[10px] text-muted-foreground">{model.provider}</p>
|
||||
</div>
|
||||
{selected === index && (
|
||||
<motion.div
|
||||
|
|
@ -220,10 +206,7 @@ function MultiplayerSkeleton({ className }: { className?: string }) {
|
|||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex h-full items-center justify-center overflow-visible",
|
||||
className,
|
||||
)}
|
||||
className={cn("relative flex h-full items-center justify-center overflow-visible", className)}
|
||||
>
|
||||
<motion.div
|
||||
className="relative w-full max-w-[160px] rounded-lg bg-background p-3 shadow-sm ring-1 ring-border"
|
||||
|
|
@ -246,10 +229,7 @@ function MultiplayerSkeleton({ className }: { className?: string }) {
|
|||
className="my-1.5 flex items-center"
|
||||
style={{ paddingLeft: line.indent * 8 }}
|
||||
>
|
||||
<div
|
||||
className={cn("h-1.5 rounded-full", line.color)}
|
||||
style={{ width: line.width }}
|
||||
/>
|
||||
<div className={cn("h-1.5 rounded-full", line.color)} style={{ width: line.width }} />
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
|
@ -295,9 +275,7 @@ function MultiplayerSkeleton({ className }: { className?: string }) {
|
|||
<div className="flex size-5 items-center justify-center rounded-full bg-white/20 text-[9px] font-bold text-white">
|
||||
{collaborator.name[0]}
|
||||
</div>
|
||||
<span className="shrink-0 text-[10px] font-medium text-white">
|
||||
{collaborator.name}
|
||||
</span>
|
||||
<span className="shrink-0 text-[10px] font-medium text-white">{collaborator.name}</span>
|
||||
<span className="rounded bg-white/20 px-1 py-px text-[8px] text-white/80">
|
||||
{collaborator.role}
|
||||
</span>
|
||||
|
|
@ -321,9 +299,7 @@ function FeatureCard({
|
|||
<div className="flex h-full flex-col justify-between bg-card p-10 first:rounded-l-2xl last:rounded-r-2xl">
|
||||
<div className="h-60 w-full overflow-visible rounded-md">{skeleton}</div>
|
||||
<div className="mt-4">
|
||||
<h3 className="text-base font-bold tracking-tight text-card-foreground">
|
||||
{title}
|
||||
</h3>
|
||||
<h3 className="text-base font-bold tracking-tight text-card-foreground">{title}</h3>
|
||||
<p className="mt-2 text-sm leading-relaxed tracking-tight text-muted-foreground">
|
||||
{description}
|
||||
</p>
|
||||
|
|
@ -408,9 +384,7 @@ function ComparisonStrip() {
|
|||
transition={{ duration: 0.3, delay: 0.15 + index * 0.06 }}
|
||||
>
|
||||
<div className="grid grid-cols-3 items-center px-4 py-2.5 text-sm sm:px-6">
|
||||
<span className="font-medium text-card-foreground">
|
||||
{row.feature}
|
||||
</span>
|
||||
<span className="font-medium text-card-foreground">{row.feature}</span>
|
||||
<span className="flex justify-center">
|
||||
{typeof row.notebookLm === "boolean" ? (
|
||||
row.notebookLm ? (
|
||||
|
|
@ -419,9 +393,7 @@ function ComparisonStrip() {
|
|||
<X className="size-4 text-muted-foreground/40" />
|
||||
)
|
||||
) : (
|
||||
<span className="text-muted-foreground">
|
||||
{row.notebookLm}
|
||||
</span>
|
||||
<span className="text-muted-foreground">{row.notebookLm}</span>
|
||||
)}
|
||||
</span>
|
||||
<span className="flex justify-center">
|
||||
|
|
@ -436,9 +408,7 @@ function ComparisonStrip() {
|
|||
)}
|
||||
</span>
|
||||
</div>
|
||||
{index !== comparisonRows.length - 1 && (
|
||||
<Separator />
|
||||
)}
|
||||
{index !== comparisonRows.length - 1 && <Separator />}
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
|
|
|||
|
|
@ -91,13 +91,12 @@ export function SidebarSlideOutPanel({
|
|||
|
||||
{/* Panel extending from sidebar's right edge, flush with the wrapper border */}
|
||||
<motion.div
|
||||
style={{ width }}
|
||||
style={{ width, left: "100%", top: -1, bottom: -1 }}
|
||||
initial={{ x: -width }}
|
||||
animate={{ x: 0 }}
|
||||
exit={{ x: -width }}
|
||||
transition={{ type: "tween", duration: 0.2, ease: [0.4, 0, 0.2, 1] }}
|
||||
className="absolute z-20 overflow-hidden"
|
||||
style={{ width, left: "100%", top: -1, bottom: -1 }}
|
||||
>
|
||||
<div
|
||||
style={{ width }}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS
|
|||
// Permission check for public sharing
|
||||
const { data: access } = useAtomValue(myAccessAtom);
|
||||
const canCreatePublicLink =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("public_sharing:create") ?? false));
|
||||
!!access &&
|
||||
(access.is_owner || (access.permissions?.includes("public_sharing:create") ?? false));
|
||||
|
||||
// Query to check if thread has public snapshots
|
||||
const { data: snapshotsData } = useQuery({
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ export function PublicChatSnapshotsManager({
|
|||
!!access && (access.is_owner || (access.permissions?.includes("public_sharing:view") ?? false));
|
||||
|
||||
const canDelete =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("public_sharing:delete") ?? false));
|
||||
!!access &&
|
||||
(access.is_owner || (access.permissions?.includes("public_sharing:delete") ?? false));
|
||||
|
||||
// Mutations
|
||||
const { mutateAsync: deleteSnapshot } = useAtomValue(deletePublicChatSnapshotMutationAtom);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
|
|||
import { GenerateReportToolUI } from "@/components/tool-ui/generate-report";
|
||||
|
||||
const GenerateVideoPresentationToolUI = dynamic(
|
||||
() => import("@/components/tool-ui/video-presentation").then((m) => ({ default: m.GenerateVideoPresentationToolUI })),
|
||||
() =>
|
||||
import("@/components/tool-ui/video-presentation").then((m) => ({
|
||||
default: m.GenerateVideoPresentationToolUI,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -79,9 +79,11 @@ export function ImageModelManager({ searchSpaceId }: ImageModelManagerProps) {
|
|||
|
||||
const { data: access } = useAtomValue(myAccessAtom);
|
||||
const canCreate =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("image_generations:create") ?? false));
|
||||
!!access &&
|
||||
(access.is_owner || (access.permissions?.includes("image_generations:create") ?? false));
|
||||
const canDelete =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("image_generations:delete") ?? false));
|
||||
!!access &&
|
||||
(access.is_owner || (access.permissions?.includes("image_generations:delete") ?? false));
|
||||
const canUpdate = canCreate;
|
||||
const isReadOnly = !canCreate && !canDelete;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,9 +89,12 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
|||
|
||||
// Permissions
|
||||
const { data: access } = useAtomValue(myAccessAtom);
|
||||
const canCreate = !!access && (access.is_owner || (access.permissions?.includes("llm_configs:create") ?? false));
|
||||
const canUpdate = !!access && (access.is_owner || (access.permissions?.includes("llm_configs:update") ?? false));
|
||||
const canDelete = !!access && (access.is_owner || (access.permissions?.includes("llm_configs:delete") ?? false));
|
||||
const canCreate =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("llm_configs:create") ?? false));
|
||||
const canUpdate =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("llm_configs:update") ?? false));
|
||||
const canDelete =
|
||||
!!access && (access.is_owner || (access.permissions?.includes("llm_configs:delete") ?? false));
|
||||
const isReadOnly = !canCreate && !canUpdate && !canDelete;
|
||||
|
||||
// Local state
|
||||
|
|
|
|||
|
|
@ -1,43 +1,62 @@
|
|||
"use client";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
import { useAtom } from "jotai";
|
||||
import { Bot, Brain, Eye, FileText, Globe, ImageIcon, MessageSquare, Shield } from "lucide-react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useTranslations } from "next-intl";
|
||||
import type React from "react";
|
||||
import { searchSpaceSettingsDialogAtom } from "@/atoms/settings/settings-dialog.atoms";
|
||||
import { SettingsDialog } from "@/components/settings/settings-dialog";
|
||||
|
||||
const GeneralSettingsManager = dynamic(
|
||||
() => import("@/components/settings/general-settings-manager").then(m => ({ default: m.GeneralSettingsManager })),
|
||||
() =>
|
||||
import("@/components/settings/general-settings-manager").then((m) => ({
|
||||
default: m.GeneralSettingsManager,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const ModelConfigManager = dynamic(
|
||||
() => import("@/components/settings/model-config-manager").then(m => ({ default: m.ModelConfigManager })),
|
||||
() =>
|
||||
import("@/components/settings/model-config-manager").then((m) => ({
|
||||
default: m.ModelConfigManager,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const LLMRoleManager = dynamic(
|
||||
() => import("@/components/settings/llm-role-manager").then(m => ({ default: m.LLMRoleManager })),
|
||||
() =>
|
||||
import("@/components/settings/llm-role-manager").then((m) => ({ default: m.LLMRoleManager })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const ImageModelManager = dynamic(
|
||||
() => import("@/components/settings/image-model-manager").then(m => ({ default: m.ImageModelManager })),
|
||||
() =>
|
||||
import("@/components/settings/image-model-manager").then((m) => ({
|
||||
default: m.ImageModelManager,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const VisionModelManager = dynamic(
|
||||
() => import("@/components/settings/vision-model-manager").then(m => ({ default: m.VisionModelManager })),
|
||||
() =>
|
||||
import("@/components/settings/vision-model-manager").then((m) => ({
|
||||
default: m.VisionModelManager,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const RolesManager = dynamic(
|
||||
() => import("@/components/settings/roles-manager").then(m => ({ default: m.RolesManager })),
|
||||
() => import("@/components/settings/roles-manager").then((m) => ({ default: m.RolesManager })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const PromptConfigManager = dynamic(
|
||||
() => import("@/components/settings/prompt-config-manager").then(m => ({ default: m.PromptConfigManager })),
|
||||
() =>
|
||||
import("@/components/settings/prompt-config-manager").then((m) => ({
|
||||
default: m.PromptConfigManager,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
const PublicChatSnapshotsManager = dynamic(
|
||||
() => import("@/components/public-chat-snapshots/public-chat-snapshots-manager").then(m => ({ default: m.PublicChatSnapshotsManager })),
|
||||
() =>
|
||||
import("@/components/public-chat-snapshots/public-chat-snapshots-manager").then((m) => ({
|
||||
default: m.PublicChatSnapshotsManager,
|
||||
})),
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
"use client";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
import { useAtom } from "jotai";
|
||||
import { Globe, KeyRound, Monitor, Receipt, Sparkles, User } from "lucide-react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useMemo } from "react";
|
||||
import { userSettingsDialogAtom } from "@/atoms/settings/settings-dialog.atoms";
|
||||
|
|
@ -10,27 +10,45 @@ import { SettingsDialog } from "@/components/settings/settings-dialog";
|
|||
import { usePlatform } from "@/hooks/use-platform";
|
||||
|
||||
const ProfileContent = dynamic(
|
||||
() => import("@/app/dashboard/[search_space_id]/user-settings/components/ProfileContent").then(m => ({ default: m.ProfileContent })),
|
||||
() =>
|
||||
import("@/app/dashboard/[search_space_id]/user-settings/components/ProfileContent").then(
|
||||
(m) => ({ default: m.ProfileContent })
|
||||
),
|
||||
{ ssr: false }
|
||||
);
|
||||
const ApiKeyContent = dynamic(
|
||||
() => import("@/app/dashboard/[search_space_id]/user-settings/components/ApiKeyContent").then(m => ({ default: m.ApiKeyContent })),
|
||||
() =>
|
||||
import("@/app/dashboard/[search_space_id]/user-settings/components/ApiKeyContent").then(
|
||||
(m) => ({ default: m.ApiKeyContent })
|
||||
),
|
||||
{ ssr: false }
|
||||
);
|
||||
const PromptsContent = dynamic(
|
||||
() => import("@/app/dashboard/[search_space_id]/user-settings/components/PromptsContent").then(m => ({ default: m.PromptsContent })),
|
||||
() =>
|
||||
import("@/app/dashboard/[search_space_id]/user-settings/components/PromptsContent").then(
|
||||
(m) => ({ default: m.PromptsContent })
|
||||
),
|
||||
{ ssr: false }
|
||||
);
|
||||
const CommunityPromptsContent = dynamic(
|
||||
() => import("@/app/dashboard/[search_space_id]/user-settings/components/CommunityPromptsContent").then(m => ({ default: m.CommunityPromptsContent })),
|
||||
() =>
|
||||
import(
|
||||
"@/app/dashboard/[search_space_id]/user-settings/components/CommunityPromptsContent"
|
||||
).then((m) => ({ default: m.CommunityPromptsContent })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const PurchaseHistoryContent = dynamic(
|
||||
() => import("@/app/dashboard/[search_space_id]/user-settings/components/PurchaseHistoryContent").then(m => ({ default: m.PurchaseHistoryContent })),
|
||||
() =>
|
||||
import(
|
||||
"@/app/dashboard/[search_space_id]/user-settings/components/PurchaseHistoryContent"
|
||||
).then((m) => ({ default: m.PurchaseHistoryContent })),
|
||||
{ ssr: false }
|
||||
);
|
||||
const DesktopContent = dynamic(
|
||||
() => import("@/app/dashboard/[search_space_id]/user-settings/components/DesktopContent").then(m => ({ default: m.DesktopContent })),
|
||||
() =>
|
||||
import("@/app/dashboard/[search_space_id]/user-settings/components/DesktopContent").then(
|
||||
(m) => ({ default: m.DesktopContent })
|
||||
),
|
||||
{ ssr: false }
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -341,36 +341,28 @@ export function DocumentUploadTab({
|
|||
</button>
|
||||
)
|
||||
) : (
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="flex flex-col items-center gap-4 py-12 px-4 cursor-pointer w-full bg-transparent border-none"
|
||||
onClick={() => {
|
||||
if (!isElectron) fileInputRef.current?.click();
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
<button
|
||||
type="button"
|
||||
className="flex flex-col items-center gap-4 py-12 px-4 cursor-pointer w-full bg-transparent border-none"
|
||||
onClick={() => {
|
||||
if (!isElectron) fileInputRef.current?.click();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Upload className="h-10 w-10 text-muted-foreground" />
|
||||
<div className="text-center space-y-1.5">
|
||||
<p className="text-base font-medium">
|
||||
{isElectron ? "Select files or folder" : "Tap to select files or folder"}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">{t("file_size_limit")}</p>
|
||||
</div>
|
||||
<div
|
||||
className="w-full mt-1"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
role="group"
|
||||
}}
|
||||
>
|
||||
{renderBrowseButton({ fullWidth: true })}
|
||||
</div>
|
||||
</div>
|
||||
<Upload className="h-10 w-10 text-muted-foreground" />
|
||||
<div className="text-center space-y-1.5">
|
||||
<p className="text-base font-medium">
|
||||
{isElectron ? "Select files or folder" : "Tap to select files or folder"}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">{t("file_size_limit")}</p>
|
||||
</div>
|
||||
<fieldset
|
||||
className="w-full mt-1 border-none p-0 m-0"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
>
|
||||
{renderBrowseButton({ fullWidth: true })}
|
||||
</fieldset>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue